Форматирование номера в Scala?

У меня динамически меняется ввод данных из файла. Цифрами являются либо Int, либо Double. Почему Scala печатать .0 после каждого номера Double? Есть ли способ для 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 s. Я не могу использовать String или AnyVal, потому что выполняю некоторые математические операции.

Спасибо,

Ответы

Ответ 1

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

Ответ 2

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

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

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

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

var x = 1 
var y= 1.0

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

Ответ 3

Используйте printf:

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

Описание строки формата см. в этой странице из документации API Java SE 6.

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

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

Ответ 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).

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

Если вы работаете с Double и хотите отформатировать его как String без .0 когда оно целое число, а в противном случае с десятичными знаками, вы можете использовать String::stripSuffix:

x.toString.stripSuffix(".0")
// val x: Double = 1.34    =>   "1.34"
// val x: Double = 1.0     =>   "1"