我明白,由于 float / double 的性质,不应将它们用于精度重要的计算。但是,由于对类似问题的混合答案,我对它们的局限性感到有点困惑,不管有效数字如何, float 和 double 是否总是不准确,或者只到第 16 位不准确。
我已经用 Java 运行了几个示例,
System.out.println(Double.parseDouble("999999.9999999999");
// this outputs correctly w/ 16 digits
System.out.println(Double.parseDouble("9.99999999999999");
// This also outputs correctly w/ 15 digits
System.out.println(Double.parseDouble("9.999999999999999");
// But this doesn't output correctly w/ 16 digits. Outputs 9.999999999999998
我找不到指向另一个答案的链接,该答案指出像 1.98 和 2.02 这样的值会四舍五入为 2.0,因此会造成不准确,但测试表明这些值打印正确。 所以我的第一个问题是浮点/ double 值是否总是不准确,或者是否存在可以确保精度的下限。
我的第二个问题是关于使用 BigDecimal。我知道我应该使用 BigDecimal 进行精度重要的计算。因此我应该使用 BigDecimal 的方法进行算术和比较。但是,BigDecimal 还包括一个 doubleValue()
方法,它将 BigDecimal 转换为 double 值。 对我确定少于 16 位的 double 值进行比较对我来说安全吗?根本不会对它们进行任何算术运算,因此固有值不应该改变。
例如,我执行以下操作是否安全?
BigDecimal myDecimal = new BigDecimal("123.456");
BigDecimal myDecimal2 = new BigDecimal("234.567");
if (myDecimal.doubleValue() < myDecimal2.doubleValue()) System.out.println("myDecimal is smaller than myDecimal2");
编辑:在阅读了一些对我自己的回答的回复后,我意识到我的理解不正确并已将其删除。以下是其中的一些片段,可能对将来有所帮助。
“double 不能精确地保持 0.1。最接近 0.1 的可表示值是 0.1000000000000000055511151231257827021181583404541015625。Java Double.toString 只打印足够的数字来唯一标识 double,而不是精确值。” - 帕特里夏·沙纳汉
来源:
https://stackoverflow.com/a/5749978 - 声明 double 最多可容纳 15 位数字
最佳答案
我建议您阅读此页面:
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
一旦您阅读并理解了它,并且可能将几个示例转换为 64 位浮点格式的二进制表示形式,那么您就会更好地了解 Double 可以容纳哪些有效数字。
关于java - 通用编程和Java double ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31890175/