我假设您正在编写自己的 bignum 类。如果你只关心 log2 的积分结果,那很容易。取不为零的最高有效数字的对数,并在该字节之后为每个字节添加 8。这是假设每个字节都包含 0-255 的值。这些精度仅在 ±.5 范围内,但速度非常快。
[0][42][53] (10805 in bytes)
log2(42) = 5
+ 8*1 = 8 (because of the one byte lower than MSB)
= 13 (Actual: 13.39941145)
如果您的值以 10 位为基数,则结果为log2(MSB)+3.32192809*num_digits_less_than_MSB
.
[0][5][7][6][2] (5762)
log2(5) = 2.321928095
+ 3.32192809*3 = 9.96578427 (because 3 digits lower than MSB)
= 12.28771 (Actual: 12.49235395)
(only accurate for numbers with less than ~10 million digits)
如果你使用你在维基百科上找到的算法,它会非常慢。(但如果您需要小数则准确)
有人指出,当 MSB 较小时(仍在 ±.5 以内,但不会更远),我的方法是不准确的,但这很容易解决,只需将前两个字节转换为一个数字,然后记录,和对小于该数字的字节进行乘法运算。我相信这将在半个百分点内准确,并且仍然比正常对数快得多。
[1][42][53] (76341 in bytes)
log2(1*256+42) = ?
log2(298) = 8.21916852046
+ 8*1 = 8 (because of the one byte lower than MSB)
= 16.21916852046 (Actual: 16.2201704643)
对于基数 10 位数字,它是log2( [mostSignificantDigit]*10+[secondMostSignifcantDigit] ) + 3.32192809*[remainingDigitCount]
.
如果性能仍然是一个问题,您可以使用 log2 的查找表而不是使用完整的对数函数。