Java转换/转换对象为双,但防止轮询?


Object num = 12334555578912349.13;
System.out.println(BigDecimal.valueOf(((Number) num).doubleValue()).setScale(2, BigDecimal.ROUND_HALF_EVEN));

我期望该值为12334555578912349.13但是输出是123345555789123504.00

如何防止舍入?

Object num = 12334555578912349.13;

你已经输了。根据java规范,源文件中的字面文本'12334555578912349.13'被解释为双精度类型。考虑到计算机不是魔法,double值是64位值,因此,最多只有2^64个数字可以用它表示。我们称这些数字为"幸运数字"。12334555578912349.13不是被祝福的数字之一。与此最接近的数字是123345555789123504.0,这就是该值"编译"到的值。一旦你到了123345555789123504.0,就没有回头路了。

那么解决方案就是永远不把'12334555578912349.13'作为你的源文件的文字,因为如果你这样做,你会立即失去游戏。

这是我们如何避免在任何地方使用double的方法:

var bd = new BigDecimal("12334555578912349.13");
System.out.println(bd);
一般来说,如果你想提供有意义的精度保证,如果你的代码在任何地方包含double这个词,你就破坏了它。在代码中快速搜索单词"double",直到搜索返回0个结果,继续消除它的使用。

可以提供精度保证的替代方法:

  • 当然是BigDecimal。请注意,如果没有指定如何舍入的规则,BD就不能除法(出于同样的原因,1/3变成0.333333…永远不会结束)。
  • 消去分数。例如,如果它代表一个国家的国内生产总值,将其存储为美分而不是欧元,在long而不是double中。
  • 如果这个东西不代表你打算做任何数学运算的数字(例如,它是一个社会安全号码或ISBN代码或诸如此类的),将其存储为String。

相关内容

  • 没有找到相关文章

最新更新