我写了一个简单的程序来计算n+1中n是一个大整数的位数。下面的测试用例输出的答案是34,但答案是33。测试用例- 999999999999999999999999999999999999990
——代码
#python3
import math
inp = eval(input())
if inp > 0:
digits = int(math.log10(inp+1))+1
elif inp == 0:
digits = 1
else:
digits = int(math.log10(-inp))+2
print(digits)
当我输入一个较小的整数,比如10位,它会显示正确的答案当input = 9999999990时,输出为10,正确
math.log10()将计算为双精度浮点数。它没有足够的精度来区分结果和数字33。您可以使用mpmath以更高的精度计算log10。下面的代码对我有效:
#python3
from mpmath import mp
mp.prec = 127 # set the precision to 127 bits
inp = int('999999999999999999999999999999990')
if inp > 0:
digits = int(mp.log10(inp))+1
elif inp == 0:
digits = 1
else:
digits = int(mp.log10(-inp))+2
print(digits)
注意,精度设置为127位。当求一个40位数字的值时,我们会遇到和之前一样的问题。当40位数字非常接近10^41时,log10的结果可能比41大一点,而实际值则小一点。这就是为什么将其转换为整数会产生41。让我们估计一下精确度是多少:log10(x)的导数是1/(x * ln(10))。对于高x, log10(x+1) - log10(x)约为1/(x * ln(10))我们需要Delta_y/y的相对精度,其中Delta_y为(log10(x+1) - log10(x)) y为log10(x)。我们可以用log2(1/relative_precision)来估计二进制数。得到log2(x * ln(x))x有39个9和1个0,得到139.4。所以如果我们输入
mp.prec = 140
我们将得到正确的结果。事实上
#python3
from mpmath import mp
mp.prec = 140
inp = int(39 * '9' + '0')
if inp > 0:
digits = int(mp.log10(inp))+1
elif inp == 0:
digits = 1
else:
digits = int(mp.log10(-inp))+2
print(digits)
print( len( str(inp) ) )
输出:
40
40
注意,这可能不是计算位数的最佳方法。例如,你可以使用一个循环,每一步除以10。或者直接输入
print( len( str(inp) ) )