【问题标题】:How to avoid auto rounding down small double number in Scala?如何避免在Scala中自动舍入小双数?
【发布时间】:2020-12-27 19:01:18
【问题描述】:

我有这个函数(用 Java 编写),它返回一个小的双精度数(1e-6、1e-9 等)。我在 scala 中的其他服务正在使用该服务,并且应该使用该值。但是,该值始终返回为 0e-10(为零),即使在我的 JUnit 中该值被正确返回。 我在 Java 部分使用的数据类型是 Double,而不是 double,因为我也需要它是 Optional。虽然我不确定这是否与此有关,但只想提供尽可能多的细节。 代码sn-p:

生成小数的方法

private Optional<Double> getSmallNumber(InputObject obj) {
 if(obj meets certain condition)
  return Optional.of(0.00000000001)
}

创建和返回对象的方法

public JavaObject javaObjectGenerator(InputObject obj){
 return JavaObjectBuilder.setSmallNumber(getSmallNumber(obj)).
 ...
 .build();
}

假设这个“SmallNumber”只是我的 Java 对象的一个​​属性。然后,这个 Java 对象被传递给我的另一个 Scala 模块并被我的其他 Scala 模块使用。我希望在阅读“SmallNumber”时得到 0.00000000001,但它总是被舍入到 0e-10。

【问题讨论】:

  • 虽然浮点(双精度)没有精度,但在编组中应用精度 5(比例 -5)可能会导致 0.0。
  • 你在哪里丢失了号码?能分享一下丢失的代码sn-p吗?
  • @JoopEggen 有趣的是,我尝试了精度 3,它被传给了 scala,没有任何舍入。我仍在尝试找出根本原因,因为我需要的数字要小得多。
  • @TomerShetah 我将 sn-p 添加到我的帖子中。基本上,java 部分就像一个对象构建器,它生成所有属性并将最终对象传递给 scala 模块。我认为当 java 部分作为库作为 scala 模块的一部分时,它开始失去精度。与其在 JUnit 中测试的行为相比,它的行为完全不同。
  • @user3128826 是因为您只读取 10 位数字并且在 10 个零之后设置 1?那么当它打印时它被四舍五入为0?您可以在拨打getSmallNumber 以检查它是否为0 后尝试打印该号码吗?请尝试将其乘以 100000,假设只是为了确保它不为 0。您使用的是哪个数据库?会不会是数据库将其四舍五入为 0?

标签: java scala double rounding precision


【解决方案1】:

看起来这只是数字格式的结果,底层表示没有改变

val d = 0.00000000001
println(d) //prints 1.0E-11
println(f"$d%.12f") //prints 0.000000000010

【讨论】:

  • 它实际上将数字向下舍入为 0,就像它在数据库中显示的那样。
  • 正如我在这里展示的,这个数字没有四舍五入。也许您的数据库出于某种原因将数字四舍五入,但您最初的问题根本没有提到数据库。为了让人们帮助你,你需要准确地展示你做了什么,以及你得到了什么结果。如果问题是从数据库查询中返回了一个意外的数字,请说明它是如何插入的、如何查询的以及您如何查看结果。
猜你喜欢
  • 1970-01-01
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-11
  • 2013-03-24
相关资源
最近更新 更多