为什么C++和Java中的这种浮点运算会产生不同的结果
Why does this float operation in C++ and Java give different results?
我刚刚看到这个网站,并尝试用Java和C++做这件事。为什么用Java编写以下内容会产生0.300000000000000004
double x = 0.1 + 0.2;
System.out.print(x);
而用C++编写以下内容会得到0.3?
double x = 0.1 + 0.2;
cout<<x;
C++标准不能保证使用IEEE 754浮点运算,因此结果实际上是由实现定义的。然而,大多数实现都会这样做
在Java中,float
和double
被定义为IEEE 754浮点类型。此外,您可以将strictfp
修饰符添加到类或方法声明中,以要求即使对于中间结果也要使用严格的IEEE 754浮点运算。
在处理浮点数时,如果有疑问,查看实际的位表示通常是有用的。
#include <cstdint>
#include <cstdio>
int
main()
{
static_assert(sizeof(double) == sizeof(uint64_t), "wrong bit sizes");
const double x = 0.1 + 0.2;
const uint64_t bits = *reinterpret_cast<const uint64_t *>(&x);
printf("C++: 0x%016lXn", bits);
return 0;
}
public final class Main {
public static void main(final String[] args) {
final double x = 0.1 + 0.2;
final long bits = Double.doubleToLongBits(x);
System.out.printf("Java: 0x%016Xn", bits);
}
}
当我在我的计算机上执行这两个程序(GNU/Linux与GCC和OpenJDK)时,输出是
C++: 0x3FD3333333333334
Java: 0x3FD3333333333334
这表明两者产生完全相同的结果。但是,可移植程序不应该依赖于此。
在IEEE浮点表示中,0.1、0.2(或0.3)都不是精确值。只有2的负幂和它们的组合将是(例如0.5、0.25、0.75…)
因此,您看到的差异只是Matt Adams所说的默认输出格式的差异。
决定您的精度级别,并专门为输出流设置该级别,该级别应显示相同的
相关文章:
- 使用双精度的浮点运算
- 将异常字符串解析为向量上的浮点运算?
- -O1改变浮点运算
- 将浮点运算与 Z3 C++ API 结合使用
- C++模运算符,使用 #define 和自己的类进行浮点运算
- 浮点运算
- 浮点运算的精度
- 为什么GDB对浮点运算的评估与C++不同
- C中的浮点运算出错
- 在Visual C++中,浮点运算优化会导致罕见而奇怪的行为
- 为什么十进制浮点运算的提议没有被 C++0x 接受?
- 为什么这个浮点运算被编译得如此奇怪(没有经过优化)
- 浮点运算结果的重现性
- 在浮点运算上执行平方运算和平方根运算时:表达式必须具有整型或非整型枚举类型
- C++:浮点运算的稳定性策略
- 自动获取某些代码段的浮点运算计数的方法
- 用于浮点运算的快速、基于秩的基数排序
- 浮点运算中的整数转换
- 浮点运算是如何在一个大数字上加一的
- 为什么C++和Java中的这种浮点运算会产生不同的结果