一般编程和Java的双精度 [英] The accuracy of a double in general programming and Java
问题描述
我在Java中运行了几个例子,
System.out.println(Double。 parseDouble(999999.9999999999);
//输出正确w / 16位数
System.out.println(Double.parseDouble(9.99999999999999);
//这也正确输出w / 15位数
System.out.println(Double.parseDouble(9.999999999999999);
//但是这不能正确输出w / 16位数输出9.999999999999998
我找不到另一个答案的链接,指出像1.98和2.02这样的值可以舍入到2.0,因此创建不准确,但测试显示值正确打印。所以我的第一个问题是浮动/双精度值是否永远是不准确或有下限,您可以确保精度。
我的第二个问题是使用BigDecimal。我知道我应该使用BigDecimal进行精确的重要计算。因此,我应该使用BigDecimal的算法和比较方法。但是,BigDecimal还包含一个 doubleValue()
方法,它将BigDecimal转换为double。 对我来说,我认识的双重值之间的比较肯定有不到16位的数字是否安全?不会对它们进行任何算术,所以固有的值不应该改变。
例如,我可以安全地执行以下操作?
BigDecimal myDecimal = new BigDecimal(123.456);
BigDecimal myDecimal2 = new BigDecimal(234.567);
if(myDecimal.doubleValue()< myDecimal2.doubleValue())System.out.println(myDecimal is small than myDecimal2);
编辑:在阅读了自己的答案后,我意识到我的理解不正确,已删除它。以下是一些可能会在未来有帮助的片段。
双精度不能精确地保持0.1,最接近0.1的代表值是0.1000000000000000055511151231257827021181583404541015625。仅限Java Double.toString打印足够的数字来唯一标识双倍,而不是确切的值。 - Patricia Shanahan
资料来源:
https:// stackoverflow .com / a / 5749978 - 双重可以容纳多达15位数的状态
我建议你阅读此页面:
https://en.wikipedia.org/wiki / double-precision_floating-point_format
一旦你已经阅读并理解了它,也可能将几个例子转换成其64位浮点格式的二进制表示那么你可以更好地了解一个Double有多大的数字。
I understand that due to the nature of a float/double one should not use them for precision important calculations. However, i'm a little confused on their limitations due to mixed answers on similar questions, whether or not floats and doubles will always be inaccurate regardless of significant digits or are only inaccurate up to the 16th digit.
I've ran a few examples in 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
I can't find the link to another answer that stated that values like 1.98 and 2.02 would round down to 2.0 and therefore create inaccuracies but testing shows that the values are printed correctly. So my first question is whether or not floating/double values will always be inaccurate or is there a lower limit where you can be assured of precision.
My second question is in regards to using BigDecimal. I know that I should be using BigDecimal for precision important calculations. Therefore I should be using BigDecimal's methods for arithmetic and comparing. However, BigDecimal also includes a doubleValue()
method which will convert the BigDecimal to a double. Would it be safe for me to do a comparison between double values that I know for sure have less than 16 digits? There will be no arithmetic done on them at all so the inherent values should not have changed.
For example, is it safe for me to do the following?
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");
Edit: After reading some of the responses to my own answer i've realized my understanding was incorrect and have deleted it. Here are some snippets from it that might help in the future.
"A double cannot hold 0.1 precisely. The closest representable value to 0.1 is 0.1000000000000000055511151231257827021181583404541015625. Java Double.toString only prints enough digits to uniquely identify the double, not the exact value." - Patricia Shanahan
Sources:
https://stackoverflow.com/a/5749978 - States that a double can hold up to 15 digits
I suggest you read this page:
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
Once you've read and understood it, and perhaps converted several examples to their binary representations in the 64 bit floating point format, then you'll have a much better idea of what significant digits a Double can hold.
这篇关于一般编程和Java的双精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!