为什么双精度和长双精度给出不同的答案?

why double and long double are giving different answer in the following program

本文关键字:双精度 答案 为什么      更新时间:2023-10-16

这段代码正在计算一个级数的第n项,该级数定义为Tn+2=(Tn+1)^2+Tn,其中第一项和第二项在编码中分别表示为a和b。

#include<iostream>
#include<string>
using namespace std;
int main()
{
 int a,b,n;
 char ch[100];
 cin>>a>>b>>n;
 long double res[3];
 res[0]=a,res[1]=b;
 for(int i=n-2;i>0;i--)
 {
  res[2]=res[1]*res[1]+res[0];
  res[0]=res[1];
  res[1]=res[2];
 }
 sprintf(ch,"%.0Lf",res[2]);
 cout<<ch;
 return 0;
}

输入:0 1 10

输出:

84266613096281242861568        // in case of double res[3];
84266613096281243385856       // in case of long double res[3];
correct output : 84266613096281243382112

因为它超出了整型的范围,所以我使用double/long double。

但问题是我得到双精度和长双精度的不同输出,而中间值没有一个在小数点后有非零数字,所以不应该有任何四舍五入,我猜。

而中间值在小数点后没有非零数字,所以我猜不应该有任何四舍五入。

这个假设是完全错误的。所有浮点数(如double等)的存储方式为

mantissa * 2^exponent

具有有限位数的尾数和指数。因此,浮点数可以存储固定数量的有效数字(对于转换为十进制表示的double,通常在16左右)。如果一个数字在小数点前有更多的数字,则会发生舍入,并且需要"忘记"的数字越多,总舍入误差就越大。

如果你想了解更多的细节,最常见的浮点实现遵循IEEE浮点标准。