java - 如果 double 类型可以处理数字 4.35 和 435,为什么 4.35 * 100 的计算结果为 434.99999999999994?

标签 java string math printing floating-point

<分区>

据我了解,有些数字不能用二进制精确表示,这就是为什么浮点运算有时会给我们带来意想不到的结果;比如 4.35 * 100 = 434.99999999999994。类似于十进制的 1/3 所发生的事情。

这是有道理的,但这引发了另一个问题。似乎在二进制中 4.35 和 435 都可以精确表示。那就是它对我来说不再有意义的时候。为什么 4.35 * 100 的计算结果为 434.99999999999994? 435 和 4.35 在 double 类型动力学中有一个精确的表示:

double number1 = 4.35;
double number2 = 435;
double number3 = 100;
System.out.println(number1); // 4.35
System.out.println(number2); // 435.0
System.out.println(number3); // 100.0
// So far so good. Everything ok. 

System.out.println(number1 * number3); // 434.99999999999994 !!!
// But 4.35 * 100 evaluates to 434.99999999999994

为什么?

编辑:这个问题被标记为重复,但事实并非如此。正如您在接受的答案中看到的那样,我的困惑在于实际值和打印值之间的差异。

最佳答案

Seems that in binary both 4.35 and 435 can be represented with exactitude.

我看到您了解 float 的内部表示方式。至于你的疑问,没有 4.35 没有精确的二进制表示。所以问题是,为什么 1st 打印语句打印 4.35

这是因为 System.out.println() 调用了 Double.toString(double)方法,依次使用 FloatingDecimal#toJavaFormatString()方法,它在内部对传递的 double 参数执行一些舍入。您可以查看我链接的源代码。

要查看 4.35 的实际值,请尝试使用此方法:

BigDecimal bd = new BigDecimal(number1);
System.out.println(bd);

这将打印:

4.3499999999999996447286321199499070644378662109375

在这种情况下,不是打印 double 值,而是创建一个 BigDecimal 对象,将 double 值作为参数传递。 BigDecimal 表示任意精度带符号的十进制数。因此它为您提供了 4.35 的准确值。

关于java - 如果 double 类型可以处理数字 4.35 和 435,为什么 4.35 * 100 的计算结果为 434.99999999999994?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18389455/

相关文章:

java - 正则表达式捕获引号之外的注释

java - 使用 GSON 解析 JSON 返回 null

string - 带引号和不带引号的 bash 字符串有什么区别

c - 为什么 C 为这个算法给 Python 不同的值?

math - float 学有问题吗?

java - 如何将存储在 byte[] 数组中的两个 8 字节数字相加

java - 支柱2 : return to calling page

c - strcmp 有什么问题?

javascript - substr() 没有像预期的那样连接字符串 javascript

使用 PHP/MySQL 值的 jQuery 数学