编程语言精度误差python,c语言,c++

num1 = 0.1
num2 = 0.2
num3 = 0.3
num4 = num1 + num2
if num3 == num4:
    print("y")
else:
    print("n")

结果是n
0.1和0.2 相加 不等于 0.3
0.1+0.2=0.30000000000004

原因

两浮点数X,Y进行加减运算时,必须按以下几步执行(可参考 [4] 中插图):
(1)对阶,使两数的小数点位置对齐,小的阶码向大的阶码看齐。
(2)尾数求和,将对阶后的两尾数按定点加减运算规则求和(差)。
(3)规格化,为增加有效数字的位数,提高运算精度,必须将求和(差)后的尾数规格化。
(4)舍入,为提高精度,要考虑尾数右移时丢失的数值位。
(5)判断结果,即判断结果是否溢出。

关键就在与对阶这一步骤,由于float的有效位数只有7位有效数字,如果一个大数和一个小数相加时,会产生很大的误差,因为尾数得截掉好多位。例如:

123 + 0.00023456 = 1.23*10^2 + 0.000002 * 10^2 = 123.0002

那么此时就会产生0.00003456的误差,如果累加多次,则误差就会进一步加大。

解决方案

  1. Kahan summation算法

解决方法就是把多余的误差部分算出来©,再在下一次循环减去这个误差
2.二分法递归计算加法,这样会没有误差,但是函数调用消耗大(尤其是多次)

int main()
{
float f = 0.1;
float sum = 0;
sum+=add(f,4000000);
cout<<sum<<endl;
return 0;
}
 
float add(float f,int count)
{
    if(count==1)
    return f;
    else
        return add(f,count/2)+add(f,count-count/2);
}

3.使用double,精度更高

4.ieee浮点数,为了规格化,精度每超过2的整数次幂,精度要下降一位,
你的f是0.1,float位数是23,当sum足够大的时候,会出现 sum+f==sum 的情况,这个是ieee标准,和C++没关系,事实上编译器应该已经做了浮点精度调整了。

简单的来说0.1的二进制是0.000110011001100(无限死循环下去)计算机是无法完整表示的所以将二进制再还原成10进制就会有误差再深一点就还得研究IEEE745标准具体自己研究,一两句说不清楚。

原文地址:https://www.cnblogs.com/AmosAlbert/p/12832351.html