对我来说,第一个问题,请保持温和。
我有一个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中显示的只是一个,不是那种。
无论如何,问题是:我错过了什么,或者只是我必须做的事情。它不是至关重要的,因为这是一个测试功能,而不是生产代码。最重要的是,我只是感兴趣。
答案 0 :(得分:0)
VB6 Double是二进制浮点数类型。算术时会出现舍入误差。别担心!
你听起来像个数学家,所以你应该找到更多关于此的信息。如果您正在编写数字内容,它将非常有用。试试这个。它是一篇c#文章,但VB6中的原则相同。
答案 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
如果您打算在紧密循环中调用该函数,这会对性能产生轻微影响。