vba修复功能,双重比较返回意外值

时间:2015-09-02 17:22:20

标签: excel vba

vba中的修复功能在传递3时返回2:

Debug.Print (Fix(Log(1000) / Log(10)))

- >这打印2而不是3

为什么?

5 个答案:

答案 0 :(得分:2)

Log(1000)/Log(10)或6.90775527898214÷2.30258509299405应该等于 3 ,但看起来15位浮点精度正在生成15 digit precision floating point error而修复正在终止所有小数。如果您Round到15位小数以消除无限小的错误,您将收到 3 作为答案。

?round(log(1000)/log(10), 15)

答案 1 :(得分:2)

Debug.Print Log(1000)   '6.90775527898214
Debug.Print Log(10)     '2.30258509299405

6.90775527898214
   /
2.30258509299405
=2.999999999999996      'VBA is convering this to '3#'

Debug.Print Fix(3#)     '2
Debug.Print Round(Fix(Log(1000) / Log(10)))     '2
Debug.Print Round(Round(Fix(Log(1000)) / Round(Log(10))))   '3 (This is what you want)  
Debug.Print (Round(Fix(Log(1000)) / Round(Log(10))))        '3 (Or may be only this)

答案 2 :(得分:1)

对日志功能进行调试:

Public Sub Test()
    Dim number As Double
    number = Log(1000)
    Debug.Print number
End Sub

打印:6.90775527898214

Public Sub Test()
    Dim number As Double
    number = Log(10)
    Debug.Print number
End Sub

打印:2.30258509299405

当你划分你得到的那些:2。(很多9个)并且在那个号码上调用Fix会给你2而不是3。

答案 3 :(得分:0)

嗯 - 我认为这是VB处理Log与工作表函数处理它的方式。使用此功能,我得到3

Debug.Print fix(worksheetfunction.log10(1000)/worksheetfunction.log10(10))

我记得我在Logs上遇到了类似的问题,并在SO上询问了这个问题,所以也许这是一个相关的问题。

答案 4 :(得分:0)

  

使用浮点数时(单数据类型(Visual   基本)和双数据类型(Visual Basic)),记住它们是   存储为二进制分数。这意味着他们无法保持准确   表示任何不是二进制分数的数量   形式k /(2 ^ n)其中k和n是整数)。例如,0.5(= 1/2)   和0.3125(= 5/16)可以保持为精确值,而0.2(= 1/5)   和0.3(= 3/10)只能是近似值。

https://msdn.microsoft.com/en-us/library/ae382yt8.aspx

所以我做的是创建另一个修复函数,如下所示: '修复有问题

Public Function FixModified(ByVal x As Double, ByVal threshold As Double)
    If Fix(x) = x Then
        FixModified = x
    ElseIf Fix(x) + 1 - x < threshold Then
        FixModified = Fix(x) + 1
    Else
        FixModified = Fix(x)
    End If
End Function

我现在通过的门槛是0.000000000001,它正在按预期工作。