Tra*_*own 136
你可以使用scala.math.BigDecimal:
BigDecimal(1.23456789).setScale(2, BigDecimal.RoundingMode.HALF_UP).toDouble
Run Code Online (Sandbox Code Playgroud)
还有许多其他的舍入模式,遗憾的是目前还没有很好地记录(尽管他们的Java等价物是).
Kai*_*ito 71
这是没有BigDecimals的另一种解决方案
截短:
(math floor 1.23456789 * 100) / 100
Run Code Online (Sandbox Code Playgroud)
回合:
(math rint 1.23456789 * 100) / 100
Run Code Online (Sandbox Code Playgroud)
或者对于任何双n和精度p:
def truncateAt(n: Double, p: Int): Double = { val s = math pow (10, p); (math floor n * s) / s }
Run Code Online (Sandbox Code Playgroud)
对于舍入函数可以进行类似的操作,这次使用currying:
def roundAt(p: Int)(n: Double): Double = { val s = math pow (10, p); (math round n * s) / s }
Run Code Online (Sandbox Code Playgroud)
这是更可重复使用的,例如,当舍入金额时,可以使用以下内容:
def roundAt2(p: Int) = roundAt(2)(p)
Run Code Online (Sandbox Code Playgroud)
aka*_*ppi 32
由于没有人提到过%运营商,所以来了.它只会截断,你不能依赖返回值不会有浮点不准确,但有时它很方便:
scala> 1.23456789 - (1.23456789 % 0.01)
res4: Double = 1.23
Run Code Online (Sandbox Code Playgroud)
使用 Scala 插值器实际上很容易处理f- https://docs.scala-lang.org/overviews/core/string-interpolation.html
假设我们想要四舍五入到小数点后两位:
scala> val sum = 1 + 1/4D + 1/7D + 1/10D + 1/13D
sum: Double = 1.5697802197802198
scala> println(f"$sum%1.2f")
1.57
Run Code Online (Sandbox Code Playgroud)
怎么样 :
val value = 1.4142135623730951
//3 decimal places
println((value * 1000).round / 1000.toDouble)
//4 decimal places
println((value * 10000).round / 10000.toDouble)
Run Code Online (Sandbox Code Playgroud)
编辑:解决了@ryryguy指出的问题.(谢谢!)
如果你想要它快,Kaito有正确的想法. math.pow但是很慢.对于任何标准用途,您最好使用递归函数:
def trunc(x: Double, n: Int) = {
def p10(n: Int, pow: Long = 10): Long = if (n==0) pow else p10(n-1,pow*10)
if (n < 0) {
val m = p10(-n).toDouble
math.round(x/m) * m
}
else {
val m = p10(n).toDouble
math.round(x*m) / m
}
}
Run Code Online (Sandbox Code Playgroud)
如果你在Long(即18位数)的范围内,这大约快10倍,所以你可以在10 ^ 18到10 ^ -18之间的任何地方进行舍入.
对于那些有兴趣的人,这里有一些建议的解决方案......
Rounding
Java Formatter: Elapsed Time: 105
Scala Formatter: Elapsed Time: 167
BigDecimal Formatter: Elapsed Time: 27
Truncation
Scala custom Formatter: Elapsed Time: 3
Run Code Online (Sandbox Code Playgroud)
截断是最快的,其次是 BigDecimal。请记住,这些测试是在运行 norma scala 执行时完成的,没有使用任何基准测试工具。
object TestFormatters {
val r = scala.util.Random
def textFormatter(x: Double) = new java.text.DecimalFormat("0.##").format(x)
def scalaFormatter(x: Double) = "$pi%1.2f".format(x)
def bigDecimalFormatter(x: Double) = BigDecimal(x).setScale(2, BigDecimal.RoundingMode.HALF_UP).toDouble
def scalaCustom(x: Double) = {
val roundBy = 2
val w = math.pow(10, roundBy)
(x * w).toLong.toDouble / w
}
def timed(f: => Unit) = {
val start = System.currentTimeMillis()
f
val end = System.currentTimeMillis()
println("Elapsed Time: " + (end - start))
}
def main(args: Array[String]): Unit = {
print("Java Formatter: ")
val iters = 10000
timed {
(0 until iters) foreach { _ =>
textFormatter(r.nextDouble())
}
}
print("Scala Formatter: ")
timed {
(0 until iters) foreach { _ =>
scalaFormatter(r.nextDouble())
}
}
print("BigDecimal Formatter: ")
timed {
(0 until iters) foreach { _ =>
bigDecimalFormatter(r.nextDouble())
}
}
print("Scala custom Formatter (truncation): ")
timed {
(0 until iters) foreach { _ =>
scalaCustom(r.nextDouble())
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
100149 次 |
| 最近记录: |