VB6 Log10功能

时间:2014-07-14 14:09:06

标签: vb6 ieee-754

对我来说,第一个问题,请保持温和。

我有一个Log10功能,我很满意

Public Function Log10(ByVal n As Long) As Long

    Select Case n
        Case Is >= 1000000000: Log10 = 9
        Case Is >= 100000000: Log10 = 8
        Case Is >= 10000000: Log10 = 7
        Case Is >= 1000000: Log10 = 6
        Case Is >= 100000: Log10 = 5
        Case Is >= 10000: Log10 = 4
        Case Is >= 1000: Log10 = 3
        Case Is >= 100: Log10 = 2
        Case Is >= 10: Log10 = 1
        Case Else: Log10 = 0
    End Select

End Function

然而,当为这个函数创建一个测试(我知道它是微不足道的,我知道它有用 - QA等),看起来像这样

Public Const LONG_MAX As Long = 2147483647

Public Sub testLog10()

    Dim i As Long
    Dim a As Long
    Dim b As Long

    For i = 1 To LONG_MAX
        DoEvents
        a = Log10(i)
        b = Int(Log(i) / Log(10))
        Debug.Assert a = b
    Next

End Sub

A通常不等于B,正如您可以想象的那样,这是一个相当大的惊喜,因为主要的对数标识应始终保持不变。如果将它抽象为函数,

Private Function Log10(ByVal n As Long) As Long
    Dim d As Double
    d = Log(n) / Log(10)
    DblLog10 = Int(d)
End Function

然后你会看到当n = 10时,d = 1,这是正确的。但是,当它转换为int时,会将其截断为零。对于那些感兴趣的人,Fix没有任何区别(不管怎样都不应该))这可以通过,

来解决
Private Function Log10(ByVal n As Long) As Long
    Dim d As Double
    d = Log(n) / Log(10) + 0.000000001
    DblLog10 = Int(d)
End Function

暗示了double的内部表示,而在VB6 IDE中显示的只是一个,不是那种。

无论如何,问题是:我错过了什么,或者只是我必须做的事情。它不是至关重要的,因为这是一个测试功能,而不是生产代码。最重要的是,我只是感兴趣。

2 个答案:

答案 0 :(得分:0)

VB6 Double是二进制浮点数类型。算术时会出现舍入误差。别担心!

你听起来像个数学家,所以你应该找到更多关于此的信息。如果您正在编写数字内容,它将非常有用。试试这个。它是一篇c#文章,但VB6中的原则相同。

http://www.yoda.arachsys.com/csharp/floatingpoint.html

答案 1 :(得分:0)

您可以通过将结果临时转换为Double来规避String个特性

Private Function Log10(ByVal n As Long) As Long
    Dim d As Double
    d = Log(n) / Log(10)
    Log10 = Int(CStr(d))
End Function

如果您打算在紧密循环中调用该函数,这会对性能产生轻微影响。