#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
相同。如果事情是精确的,我本来希望有一些不同的东西。
答案 0 :(得分:5)
问题在于缺乏精确度:https://en.wikipedia.org/wiki/Floating_point
在1亿个数字之后,您将1e8添加到1e16(或者至少是该数量的数字),但是单精度数字仅精确到7位数 - 因此它与添加0到1e16相同;这就是为什么你的结果浮动的结果要低得多。
在大多数情况下,首选双重浮动。
答案 1 :(得分:0)
您没有提到您正在使用的浮点数类型,但我会假设您使用的是IEEE 754或类似的。
我知道double有双精度
要使用术语更加精确,double使用两倍的位数。虽然被命名为&#34;双精度&#34;
,但它的重复数值不会翻倍,它是可表示值的4294967296倍。但浮动仍应处理最多10 ^ 38的数字。
Float可以处理一些数量级别的数字。但这并不意味着该范围内的浮动值是精确的。例如,3,4028235E+38
可以表示为单精度浮点数。你能想象多少是浮动代表的前一个值之间的差异?它是机器epsilon?也许0.1?也许1?不。差异大约是2E + 31。
现在,你的数字并不在这个范围内。但是,它们超出了可以用浮点精确表示的整个整数的连续范围。该范围内的最高值恰好是16777217,或大约1.7E + 7,这小于2.5E + 17。因此,超出该范围的每次添加都会给结果增加一些误差。您执行了十亿次计算,以便将这些错误加起来。
结论:
答案 2 :(得分:0)
浮点精度问题!无限实数不可能由计算机的有限存储器表示。一般而言,Float只是它们所代表的数字的近似值。
有关详细信息,请查看以下文档: https://softwareengineering.stackexchange.com/questions/101163/what-causes-floating-point-rounding-errors