使用 float 和 double 的差异很大
Very large differences using float and double
#include <iostream>
using namespace std;
int main() {
int steps=1000000000;
float s = 0;
for (int i=1;i<(steps+1);i++){
s += (i/2.0) ;
}
cout << s << endl;
}
将 s
声明为 float
:9.0072e+15
将 s
声明为 double
:2.5e+17(与在 Julia 中实现的结果相同)
我知道 double
比 float
具有双精度,但 float
仍应处理最大 10^38 的数字。
我确实读过类似的主题,但结果不一样,但在那种情况下差异非常小,这里的差异是 25 倍。
我还补充说,使用 long double
得到的结果与 double
相同。如果问题是精度,我希望会有一些不同。
问题是精度不够:https://en.wikipedia.org/wiki/Floating_point
在 1 亿个数字之后,您要将 1e8 添加到 1e16(或至少该数量级的数字),但单精度数字仅精确到 7 位数字 - 因此它与将 0 添加到 1e16 相同;这就是为什么您的浮动结果要低得多的原因。
在大多数情况下更喜欢双倍浮动。
你没有提到你使用的是什么类型的浮点数,但我假设你使用的是 IEEE 754 或类似的。
I understand double has double precision
为了更精确 术语,double 使用两倍的位数。这不是可表示值数量的两倍,它是可表示值数量的 4294967296 倍,尽管被命名为 "double precision".
but float should still handle numbers up to 10^38.
Float 可以处理几个达到这个数量级的数字。但这并不意味着该范围内的浮点值是精确的。例如,3,4028235E+38
可以表示为单精度浮点数。您认为 float 表示的先前值之间的差异有多大?是机器epsilon吗?也许 0.1?也许 1?不,相差大约2E+31。
现在,您的数字不在那个范围内。但是,它们超出了可以用浮点数精确表示的整数的连续范围。该范围内的最大值恰好是 16777217,或大约 1.7E+7,远小于 2.5E+17。因此,超出该范围的每一次添加都会给结果增加一些误差。您执行了十亿次计算,因此这些错误加起来。
结论:
- 了解单精度远不如双精度精确。
- 避免可能累积精度误差的长计算序列。
浮点精度有问题!计算机的有限内存不可能表示无限实数。一般来说,浮点数只是它们要表示的数字的近似值。
更多详细信息,请查看以下文档:
https://softwareengineering.stackexchange.com/questions/101163/what-causes-floating-point-rounding-errors
#include <iostream>
using namespace std;
int main() {
int steps=1000000000;
float s = 0;
for (int i=1;i<(steps+1);i++){
s += (i/2.0) ;
}
cout << s << endl;
}
将 s
声明为 float
:9.0072e+15
将 s
声明为 double
:2.5e+17(与在 Julia 中实现的结果相同)
我知道 double
比 float
具有双精度,但 float
仍应处理最大 10^38 的数字。
我确实读过类似的主题,但结果不一样,但在那种情况下差异非常小,这里的差异是 25 倍。
我还补充说,使用 long double
得到的结果与 double
相同。如果问题是精度,我希望会有一些不同。
问题是精度不够:https://en.wikipedia.org/wiki/Floating_point
在 1 亿个数字之后,您要将 1e8 添加到 1e16(或至少该数量级的数字),但单精度数字仅精确到 7 位数字 - 因此它与将 0 添加到 1e16 相同;这就是为什么您的浮动结果要低得多的原因。
在大多数情况下更喜欢双倍浮动。
你没有提到你使用的是什么类型的浮点数,但我假设你使用的是 IEEE 754 或类似的。
I understand double has double precision
为了更精确 术语,double 使用两倍的位数。这不是可表示值数量的两倍,它是可表示值数量的 4294967296 倍,尽管被命名为 "double precision".
but float should still handle numbers up to 10^38.
Float 可以处理几个达到这个数量级的数字。但这并不意味着该范围内的浮点值是精确的。例如,3,4028235E+38
可以表示为单精度浮点数。您认为 float 表示的先前值之间的差异有多大?是机器epsilon吗?也许 0.1?也许 1?不,相差大约2E+31。
现在,您的数字不在那个范围内。但是,它们超出了可以用浮点数精确表示的整数的连续范围。该范围内的最大值恰好是 16777217,或大约 1.7E+7,远小于 2.5E+17。因此,超出该范围的每一次添加都会给结果增加一些误差。您执行了十亿次计算,因此这些错误加起来。
结论:
- 了解单精度远不如双精度精确。
- 避免可能累积精度误差的长计算序列。
浮点精度有问题!计算机的有限内存不可能表示无限实数。一般来说,浮点数只是它们要表示的数字的近似值。
更多详细信息,请查看以下文档: https://softwareengineering.stackexchange.com/questions/101163/what-causes-floating-point-rounding-errors