一般编程和Java的双精度 [英] The accuracy of a double in general programming and Java

查看:180
本文介绍了一般编程和Java的双精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我明白,由于浮动/双重的性质不应该将它们用于精确的重要计算。但是,由于对类似问题的混合回答,我有点混淆了他们的限制,无论浮点数和双精度是否总是不准确,无论有意义的数字,还是只有不准确的第16位数。



我在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆