我正在尝试使用最大位数来格式化浮点数,但我不想要不必要的尾随零。我想如果我使用g
代替f
它会起作用(参见this question)
def testF(d: Double) = f"$d%1.2f"
def testG(d: Double) = f"$d%1.2g"
现在这种行为很奇怪:
testF(3.1415) // --> 3.14 ok
testF(3.1) // --> 3.10 hmmm, don't want that zero
testG(3.1415) // --> 3.1 what the ?
好的,也许我需要为g
增加一位数字:
def testG(d: Double) = f"$d%1.3g"
testG(3.1415) // --> 3.14 ok
testG(3.1) // --> 3.10 grmpf
所以有两个问题 - 一个,为什么h g
丢掉一个数字并且似乎并不关心拖尾零?二,我怎么能
testX(3.1415) // --> 3.14
testX(3.1) // --> 3.1
答案 0 :(得分:3)
你可以使用java DecimalFormat,但它可能不会令人满意:
def testX(d: Double) = new java.text.DecimalFormat("#.##").format(d)
还要回答你的第一个问题为什么heck是g
丢弃一位并且似乎并不关心尾随零
对于浮点转换'e','E'和'f',精度是小数点分隔符后的位数。如果转换为“g”或“G”,那么精确度是舍入后得到的幅度中的总位数。
答案 1 :(得分:2)
与C world的printf一样,Java(和Scala)Formatter
包括最小和最大字段宽度(对于%s
格式说明符):
// Minimum field width -- right-aligned
scala> "%23s".format(23)
res0: String = " 23"
// Minimum field width -- left-aligned
scala> "%-23s".format(23)
res1: String = "23 "
// Maximum field width with right truncation
scala> "%.3s".format(12345)
res2: String = 123
// Minimum and maximum width -- right aligned
scala> "%3.3s".format(1)
res3: String = " 1"
// Minimum and maximum width -- left aligned
scala> "%-3.3s".format(1)
res4: String = "1 "
答案 2 :(得分:1)
这个版本怎么样?
使用Formattable
需要%s
格式,但您可以根据需要使用格式化args进行解释。
Formattable
可以在f
- 插值中间弹出,因为普通format
只使用toString
或您的自定义formatTo
。
package object succinctly {
import java.util.{ Formattable, FormattableFlags, Formatter }
import scala.language.implicitConversions
implicit class Succinctly(val __thing: Double) extends AnyVal {
@inline def succinctly(s: String): String = s format fmtable(__thing)
@inline def succinctly: Formattable = fmtable(__thing)
}
private[this] val trailing = "(.*\\...*?)(0*)".r
private[this] def fmtable(a: Double) = new Formattable {
override def formatTo(formatter: Formatter, flags: Int, width: Int, precision: Int) = formatter.out append (
if (precision <= 0) a.toInt.toString
else s"%${width}.${precision}f" format a.asInstanceOf[java.lang.Double] match { case trailing(num, _) => num }
)
}
}
package succinctly {
import scala.language.postfixOps
import scala.math._
object Test extends App {
Console println (Pi succinctly "%1.2s")
Console println (3.1 succinctly "%1.2s")
Console println (3.0 succinctly "%1.2s")
Console println f"${3.1 succinctly}%1.2s"
}
}
也可以想到编写一个自定义插值器,可以将双打提升为无跟踪,并将%f
更改为%s
,但需要付出一定代价,因为f
- 插值器是一个宏。