打字猴:1.701005397e+09
1701005397
1701005398     clc,clear,close all        %清屏和清除变量    warning off                %消除警告    x_double_01_left=ieee2double(‘0011111110111001100110011001100110011001100110011001100110011001’)  %将IEEE编码转换为双精度数据    ans1 = double(x_double_01_left)-0.1 %可以看出,第一个IEEE编码和0.1还是有差距的    x_double_01_right=ieee2double(‘0011111110111001100110011001100110011001100110011001100110011010’)    ans2 = double(x_double_01_right)-0.1 %第二个IEEE编码和0.1就没有区别了
1701005399
1701005400 运行程序输出结果如下:
1701005401
1701005402     x_double_01_left =    7205759403792793/72057594037927936    ans1 =      -1.3878e-17        x_double_01_right =    3602879701896397/36028797018963968    ans2 =         0
1701005403
1701005404 由结果可以看出,第一个IEEE编码和0.1还是有差距的;第二个IEEE编码和0.1没有区别,然而它也不是0.1的真实编码,而是距离最近的一个,换句话说0.1是没有准确的IEEE编码的,当然还有很多数据也没有准确的IEEE编码。
1701005405
1701005406 同理可以得到0.2和0.3的IEEE编码,以及相应的IEEE编码代表的真实数值,程序如下:
1701005407
1701005408     %0.2的编码转换     clc,clear,close all             %清屏和清除变量    warning off         %消除警告    x_ieee_02=double2ieee(0.2)      %0.2 IEEE编码    x_double_02=ieee2double(x_ieee_02)    %0.3的编码转换     x_ieee_03=double2ieee(0.3)      %0.3 IEEE编码    x_double_03=ieee2double(x_ieee_03)
1701005409
1701005410 运行程序输出结果如下:
1701005411
1701005412     x_ieee_02 =    0011111111001001100110011001100110011001100110011001100110011010    x_double_02 =    3602879701896397/18014398509481984        x_ieee_03 =    0011111111010011001100110011001100110011001100110011001100110011    x_double_03 =    5404319552844595/18014398509481984
1701005413
1701005414 现在模拟计算0.1+0.3-0.2的结果:
1701005415
1701005416    x_double_01-x_double_03+x_double_02
1701005417
1701005418 运行程序输出结果如下:
1701005419
1701005420         ans =    1/36028797018963968
1701005421
1701005422 对输出结果求其导数如下:
1701005423
1701005424     1/36028797018963968
1701005425
1701005426 运行程序输出结果如下:
1701005427
1701005428     ans =       2.7756e-17
1701005429
1701005430 然后直接采用MATLAB输入0.1-0.3+0.2进行数值模拟,程序如下:
1701005431
1701005432     >> 0.1-0.3+0.2    ans =       2.7756e-17
1701005433
1701005434 也就是说,在IEEE标准下,0.1+0.3-0.2=1/36028797018963968≈2.7756e-17,显然这个不等于0。
1701005435
1701005436 【问题】为什么0.1-0.3+0.2和0.1+0.2+0.3的结果不一样?
1701005437
1701005438 【分析】
1701005439
1701005440 0.1-0.3+0.2和0.1+0.2-0.3的结果不一样,这个主要是由于加法运算是左结合的,也就是说0.1-0.3+0.2是先计算0.1-0.3,得到,0.2;而0.1+0.2-0.3是先计算0.1+0.2,得到0.3。
1701005441
1701005442 -0.2和0.3的IEEE编码当然是不同的,相应的误差也有区别,于是得到最后结果也就不同了。
1701005443
1701005444 因此,数学是严格服从逻辑计算的,不同的计算方式,得到的结果是有偏差的,只是在我们的可接受范围内,这点误差是可以忽略的。细微的观察生活,将得到不一样的惊奇结果。
1701005445
1701005446
[ 上一页 ]  [ :1.701005397e+09 ]  [ 下一页 ]