Number formatting in Scala?

前端 未结 7 2132
夕颜
夕颜 2021-02-18 23:09

I have a dynamically changing input reading from a file. The numbers are either Int or Double. Why does Scala print .0 after every D

相关标签:
7条回答
  • 2021-02-18 23:16

    The use of a "_.0" at the end of floating point numbers is a convention. Just a way to know that the number is actually floating point and not an integer.

    If you really need to "to print it the same way it reads it" you may have to rethink the way your code is structured, possibly preserving your input data. If it's just a formatting issue, the easiest way is to convert the values to integers before printing:

    val x = 1.0
    println(x.toInt)
    

    If some are integers and some are not, you need a bit more code:

    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))
    

    The code above should print:

    1
    1.5
    1
    

    The signature of the fmt method accepts any type that either is a subtype of ScalaNumericConversions or can be converted to one through implicit conversions (so we can use the toInt method).

    0 讨论(0)
  • 2021-02-18 23:19
    var x:Double = 1
    var y:Double = 1.0
    
    print(x) // => 1.0
    print(y) // => 1.0
    

    If i understand you question you want scala to print x and y differently? The problem is that x and y are both a variable of the type Double and look the same.

    Why do you explicitly define the type of the vars?

    var x = 1 
    var y= 1.0
    
    print(x) // => 1
    print(y) // => 1.0
    
    0 讨论(0)
  • 2021-02-18 23:19

    Use type inference, rather than explicit typing.

    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 讨论(0)
  • 2021-02-18 23:28
    scala> "%1.0f" format 1.0
    res3: String = 1
    

    If your input is either Int or Double, you can do it like this:

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

    Usage:

    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...
    

    Otherwise, you might use BigDecimals. They are slow, but they do come with the scale, so "1", "1.0" and "1.00" are all different:

    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 讨论(0)
  • 2021-02-18 23:28

    If you are working with a Double and want to format it as a String without .0 when it's a whole number and with its decimals otherwise, then you could use String::stripSuffix:

    x.toString.stripSuffix(".0")
    // val x: Double = 1.34    =>   "1.34"
    // val x: Double = 1.0     =>   "1"
    
    0 讨论(0)
  • 2021-02-18 23:31

    Use printf:

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

    For a description of the format string, see this page from the Java SE 6 API documentation.

    Note that you can ofcourse also use the Java library from Scala, so other ways to format numbers from Java can also be used from Scala. You can for example use class java.text.DecimalFormat:

    val df = new java.text.DecimalFormat("#####")
    println(df.format(x))
    
    0 讨论(0)
提交回复
热议问题