2009-08-29 2 views
15

У меня динамически меняется ввод данных из файла. Цифрами являются либо Int, либо Double. Почему Scala печатает .0 после каждого номера Double? Есть ли способ, чтобы Scala печатала его так же, как читает?Форматирование номера в Scala?

Пример:

var x:Double = 1 
println (x)    // This prints '1.0', I want it to print '1' 
x = 1.0     // This prints '1.0', which is good 

Я не могу использовать Int, потому что некоторые из входных я получаю Double с. Я не могу использовать String или AnyVal, потому что выполняю некоторые математические операции.

Спасибо,

ответ

7

Использование printf:

printf("The value is %.0f", x) 

Для описания строки формата, см this page из документации API Java SE 6.

Обратите внимание, что вы также можете использовать библиотеку Java из Scala, поэтому другие способы форматирования чисел из Java также могут быть использованы из Scala. Вы можете, например, использовать класс java.text.DecimalFormat:

val df = new java.text.DecimalFormat("#####") 
println(df.format(x)) 
+0

Спасибо вам ответить Но проблема в том, что число неизвестно, либо это «1» или «1,0». Если он «1», я хочу напечатать «1», если это «1.0», тогда я хочу напечатать «1.0». Но поскольку это Double, Scala всегда печатает как «1.0» – 2009-08-29 06:14:08

+3

Если вы этого хотите, вам нужно сохранить его как строку. «Двойной» не помнит, присвоили ли вы его «1» или «1.0». – cdmckay

+2

Kodo, номера по сути не имеют числа цифр. Нет никакой разницы между числом, которое имеет значение 1 и число, которое имеет значение 1.0. – Jesper

9
var x:Double = 1 
var y:Double = 1.0 

print(x) // => 1.0 
print(y) // => 1.0 

Если я понимаю вас вопрос вы хотите напечатать Scala х и у по-разному? Проблема в том, что x и y являются переменной типа Double и выглядят одинаково.

Почему вы явно определяете тип варов?

var x = 1 
var y= 1.0 

print(x) // => 1 
print(y) // => 1.0 
+0

Он сказал «динамически меняющееся входное чтение из файла». Он вводит числа, и числа могут быть целыми или нет (но всегда сохраняются как двойные). – akauppi

1

Использовать тип вывода, а не явный ввод текста.

scala> val xi = 1 
xi: Int = 1 

scala> val xd = 1.0 
xd: Double = 1.0 

scala> println(xi) 
1 

scala> println(xd) 
1.0 
+0

Ой, извините, это дубликат ответа. – Synesso

29
scala> "%1.0f" format 1.0 
res3: String = 1 

Если вход либо Int или Double, вы можете сделать это следующим образом:

def fmt(v: Any): String = v match { 
    case d : Double => "%1.0f" format d 
    case i : Int => i.toString 
    case _ => throw new IllegalArgumentException 
} 

Использование:

scala> fmt(1.0) 
res6: String = 1 

scala> fmt(1) 
res7: String = 1 

scala> fmt(1.0f) 
java.lang.IllegalArgumentException 
     at .fmt(<console>:7) 
     at .<init>(<console>:6) 
     at .<clinit>(<console>) 
     at RequestResult$.<init>(<console>:4) 
     at RequestResult$.<clinit>(<console>) 
     at RequestResult$result(<console>) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.Dele... 

В противном случае, вы можете использовать BigDecimals. Они медленно, но они приходят с масштабом, так что «1», «1,0» и «1,00» все разные:

scala> var x = BigDecimal("1.0") 
x: BigDecimal = 1.0 

scala> x = 1 
x: BigDecimal = 1 

scala> x = 1.0 
x: BigDecimal = 1.0 

scala> x = 1.000 
x: BigDecimal = 1.0 

scala> x = "1.000" 
x: BigDecimal = 1.000 
+0

Это ужасно. Ты просто выбросил из окна все виды безопасности. Самый простой способ - сделать: n.toInt.toString – juancn

+4

@juancn Как я выбрал тип безопасности из окна? Кстати, «var n = 1.0; n.toInt.toString'» производит '1', а не' 1.0' по желанию. –

+2

Дело в том, что в 'fmt' вы заявляете, что принимаете« Any », что на самом деле не так, потому что вы бросаете исключение IllegalArgumentException, если я передаю, скажем, String. Вы можете сделать что-то вроде: 'def fmt [T <% math.ScalaNumericConversions] (n: T) = if (n.toInt == n) n.toInt.toString else n.toString', который является безопасным. Недопустимые исключения исключений должны быть выбрасываться только в том случае, если система типов не может выразить разумный набор ограничений (например, scala не позволяет указывать целочисленные числа в виде типов). – juancn

4

Использование «_.0» в конце плавающей точкой числа - это соглашение. Просто способ узнать, что число - это фактически плавающая точка, а не целое число.

Если у вас действительно необходимо «распечатать его так же, как оно читает», возможно, вам придется переосмыслить, как структурирован ваш код, возможно, сохраняя ваши входные данные.Если это просто форматирование вопрос, самый простой способ, чтобы преобразовать значения в целых числах перед печатью:

val x = 1.0 
println(x.toInt) 

Если некоторые целые числа, а некоторые нет, вам нужно немного больше кода:

def fmt[T <% math.ScalaNumericConversions](n : T) = 
        if(n.toInt == n) n.toInt.toString else n.toString 

val a : Double = 1.0 
val b : Double = 1.5 
val c : Int = 1 

println(fmt(a)) 
println(fmt(b)) 
println(fmt(c)) 

выше код должен напечатать:

1 
1.5 
1 

подпись метода fmt принимает любой тип, который либо является подтипом ScalaNumericConversions или может быть преобразован в один через неявные преобразования (поэтому мы можем использовать метод toInt).

2

Начиная с Scala 2.10 можно использовать the f interpolator:

scala> val x: Double = 1 
x: Double = 1.0 

scala> println(f"$x%.0f") 
1 

scala> val i = 1 
i: Int = 1 

scala> println(f"$i%.0f") 
1 
Смежные вопросы