使用float和double的差异非常大

时间:2016-11-29 15:43:43

标签: c++ precision

#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相同。如果事情是精确的,我本来希望有一些不同的东西。

3 个答案:

答案 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