|
本帖最后由 lee1892 于 2013-10-23 10:16 编辑
发现自己受下面提到的那个帖子影响,居然用文本来计算!实在是太傻了!
Sigh~,这个附件就不删了,权当鞭策了。
===================================================================
所谓超大整数,指数字的范围远远超过VBA提供的数据类型可计算的限制,其数字的位数为Long。
对于天文数字和高精度值i的计算的需求而言,超大整数的计算是有其现实意义的。
论坛里貌似只有这个贴子提供了代码:天文数字及高精度数字运算
但我测试了一下,其效率是非常低的,而且用起来也很不方便。
附件是一个超大整数的类,数字本身以字符串存储,目前支持:
1、超大数 + LONG
2、超大数 + 超大数
3、超大数 - LONG
4、超大数 - 超大数
5、超大数 * LONG
6、超大数 * 超大数
并且支持负数
除法未完成,计划支持获得商和余数。
Sheet1 中提供了测试代码,以验证其正确性以及速度,在我机器上测试速度如下(其中加减法为两个千万位的超大数,乘法为千万位的超大数和千万内的数):
[code=vb]' GREAT! No error found!!!
' Testing Huge Integer in length: 10,000,000 ...
' Huge Integer Plus Used: 3.250s
' Huge Integer Subtract Used: 3.297s
' Huge Integer Multiply Used: 33.297s[/code]
测试代码如下:
[code=vb]Sub TestHugeIntegerClass()
Dim hiNum As New HugeInt_LEE1892
Dim i&, nNumA&, nNumB&, nRes&, sRes$, bFlag As Boolean
bFlag = True
For i = 1 To 1000
nNumA = Int(2000000 * Rnd - 1000000)
nNumB = Int(2000 * Rnd - 1000)
With hiNum
.Number = CStr(nNumA)
nRes = nNumA + nNumB
sRes = .PlusLong(nNumB)
If CStr(nRes) <> sRes Then bFlag = False: Debug.Print nNumA; "+L"; nNumB; nRes; "NOT "; sRes
sRes = .PlusHugeInt(CStr(nNumB))
If CStr(nRes) <> sRes Then bFlag = False: Debug.Print nNumA; "+S"; nNumB; nRes; "NOT "; sRes
nRes = nNumA - nNumB
sRes = .SubtractLong(nNumB)
If CStr(nRes) <> sRes Then bFlag = False: Debug.Print nNumA; "-L"; nNumB; nRes; "NOT "; sRes
sRes = .SubtractHugeInt(CStr(nNumB))
If CStr(nRes) <> sRes Then bFlag = False: Debug.Print nNumA; "-S"; nNumB; nRes; "NOT "; sRes
nRes = nNumA * nNumB
sRes = .MultiplyLong(nNumB)
If CStr(nRes) <> sRes Then bFlag = False: Debug.Print nNumA; "*L"; nNumB; nRes; "NOT "; sRes
sRes = .MultiplyHugeInt(CStr(nNumB))
If CStr(nRes) <> sRes Then bFlag = False: Debug.Print nNumA; "*S"; nNumB; nRes; "NOT "; sRes
End With
Next
If bFlag Then Debug.Print "GREAT! No error found!!!"
Dim aNumA() As Byte, aNumB() As Byte, sNumA$, sNumB$, t#, nCnt&
nCnt = 10 ^ 7
ReDim aNumA(0 To nCnt * 2 - 1)
ReDim aNumB(0 To nCnt * 2 - 1)
For i = 1 To nCnt
aNumA((i - 1) * 2) = Int(Rnd * 10) + 48
aNumB((i - 1) * 2) = Int(Rnd * 10) + 48
Next
With hiNum
.Number = aNumA
sNumB = aNumB
Debug.Print "Testing Huge Integer in length: " & Format(.Length, "#,##0") & " ..."
t = Timer
sNumA = .PlusHugeInt(sNumB)
Debug.Print "Huge Integer Plus Used: " & Format(Timer - t, "0.000s")
t = Timer
sNumA = .SubtractHugeInt(sNumB)
Debug.Print "Huge Integer Subtract Used: " & Format(Timer - t, "0.000s")
nNumB = Int(nCnt * Rnd)
t = Timer
sNumA = .MultiplyLong(nNumB)
Debug.Print "Huge Integer Multiply Used: " & Format(Timer - t, "0.000s")
End With
Set hiNum = Nothing
Erase aNumA: Erase aNumB
End Sub[/code]
类代码可以直接编译为DLL,速度会更快。
测试环境:WinXP 32位,Excel 2003
如果有人有更快的实现,欢迎讨论。 |
评分
-
1
查看全部评分
-
|