python 中的大整数的意外结果
Unexpected result for a large integer in python
我写了一个简单的程序来计算 n+1 中的位数,其中 n 很大 integer.The 下面的测试用例输出答案为 34,但答案是 33。
测试用例 - 99999999999999999999999999999990
代码-
#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 位数字,它会显示正确答案,例如
当输入=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))。所以 log10(x+1) - log10(x) 对于高 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) )。对于 39 个九和一个零的 x,这给了我们大约 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) ) )
我写了一个简单的程序来计算 n+1 中的位数,其中 n 很大 integer.The 下面的测试用例输出答案为 34,但答案是 33。 测试用例 - 99999999999999999999999999999990
代码-
#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 位数字,它会显示正确答案,例如 当输入=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))。所以 log10(x+1) - log10(x) 对于高 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) )。对于 39 个九和一个零的 x,这给了我们大约 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) ) )