2

我正在尝试使用最大位数格式化浮点数,但我不想要不必要的尾随零。我想如果我使用它g而不是f它会起作用(参见这个问题

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

所以有两个问题——一个,为什么他的g数字下降了,而且似乎并不关心尾随的零?二、我怎么能有

testX(3.1415)  // --> 3.14
testX(3.1)     // --> 3.1

?

4

3 回答 3

4

您可以使用 java DecimalFormat但它可能不讨人喜欢:

def testX(d: Double) = new java.text.DecimalFormat("#.##").format(d)

还要回答你的第一个问题,为什么要丢g一个数字,而且似乎并不关心尾随零

对于浮点转换“e”、“E”和“f”,精度是小数点分隔符后的位数。如果转换为“g”或“G”,则精度是舍入后结果幅度中的总位数

格式化程序详细信息

于 2013-06-13T14:24:08.307 回答
3

As with the C world's printf, Java's (and Scala's) Formatter includes both minimum and maximum field widths (for the %s format specifier):

// 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  "
于 2013-06-13T15:01:38.397 回答
1

这个版本怎么样?

的使用Formattable需要%s格式,但您可以根据需要解释格式参数。

A可以在-interpolationFormattable中间弹出,因为正常只使用或者您的 custom 。fformattoStringformatTo

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-interpolator 是一个宏。

于 2013-06-14T04:10:24.587 回答