【VBA研究】浮点数计算总是有误差的

在计算人工挖孔桩对某个数据判断的时候,发现If rysd - yzg - ytg <= whbcd Then明明是相等的数据,就是无法进入

    whbcd = yxzc - hbcd - yzg - ytg '无护壁长度=有效长度-护壁长度-圆柱高-圆台高
    'whbcd1 = Round(yxzc - hbcd - yzg - ytg, 2)
    'whbcd2 = (yxzc - hbcd - yzg - ytg) * 100
    If rysd - yzg - ytg <= whbcd Then
        上部无护壁体积ry = Application.Pi * (zj / 2) ^ 2 * (rysd - yzg - ytg)
    Else
        上部有护壁体积ry = Application.Pi * (zj / 2 + hbncc + hbwcc) ^ 2 * (rysd - yzg - ytg - whbcd)
        上部无护壁体积ry = Application.Pi * (zj / 2) ^ 2 * whbcd
    End If

经过检查,发现是vba的浮点计算问题,解决办法详以下转载


数字有两种表达方式,一种是整数,一种是浮点数。浮点数是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学计数法。

计算机中存储浮点数的方式决定了浮点数往往是个近似值,因为日常生活中我们用的是十进制,而计算机用的是二进制,二进制很难精确的表达十进制的小数,这里不想讨论计算机是如何存储浮点数的,那会是很长的一篇枯燥文字,这里仅以实验来验证,请看下面程序:

Sub tt1()
    For i = 0 To 1000 Step 0.1
        Debug.Print i
    Next
End Sub

运行上面你会发现,前面可以正确显示的数值,只有一位小数,加到6以后,小数点后就暴增到了十几位,结果如下:

 ......
 5.3 
 5.4 
 5.5 
 5.6 
 5.7 
 5.8 
 5.9 
 6 
 6.1 
 6.19999999999999 
 6.29999999999999 
 6.39999999999999 
 6.49999999999999 
 6.59999999999999 
 6.69999999999999 
 ......

这就是浮点数的累积误差,因为计算机的二进制存储无法精确的存储0.1这个数字。把上述程序的步长换成0.125,再运行上述程序,则不再出现误差,这是因为二进制可以精确的存储0.125这个数字。

这样的误差可能导致比较失误,比如上面的值,你觉得应该等于6.2的,但实际值却是小于6.2,所以,在一些需要精确计算、精确比较的场合,最好不要用浮点数。如果原始数据是浮点数,可以先化成整数计算、比较,然后再还原成浮点数。比如上述程序可以写成如下:

Sub tt1()
    For i = 0 To 1000 Step 1
        Debug.Print   i / 10
    Next
End Sub

这样就可以避免浮点数计算造成的累积误差。此外,浮点数应尽量避免精确比较,一般采取大于、小于这样的比较,以免产生逻辑错误。
————————————————
版权声明:本文为CSDN博主「宋哥」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/iamlaosong/article/details/47444605

添加新评论

评论列表