• 编程语言精度误差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标准具体自己研究,一两句说不清楚。

  • 相关阅读:
    Java IO 5 : 对象序列化
    Java IO 4 : RandomAccessFile
    3 Linux平台安装jenkins
    AWS-EC2配置swap
    2.8 环境准备-静态资源服务器搭建
    2.7 环境准备-MongoDB
    2.6 环境准备-redis
    2.5 环境准备-zookeeper
    2.4 环境准备-mysql8
    2.3 环境准备-nexus
  • 原文地址:https://www.cnblogs.com/AmosAlbert/p/12832351.html
Copyright © 2020-2023  润新知