在Python中除以大数

2024-10-01 17:27:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着用Python划分一些大的数字,但是得到了一些奇怪的结果

NStr = "7D5E9B01D4DCF9A4B31D61E62F0B679C79695ACA70BACF184518" \
       "8BDF94B0B58FAF4A3E1C744C5F9BAB699ABD47BA842464EE93F4" \
       "9B151CC354B21D53DC0C7FADAC44E8F4BDF078F935D9D07A2C07" \
       "631D0DFB0B869713A9A83393CEC42D898516A28DDCDBEA13E87B" \
       "1F874BC8DC06AF03F219CE2EA4050FA996D30CE351257287" 

N = long(NStr, 16)
f2 = 476

fmin = N / float(f2)

print N - (fmin * float(f2))

这将按预期输出0.0。但是,如果我,例如,将代码更改为

fmin = N / float(f2)
fmin += 1

我仍然得到0.0的输出

我也试过用十进制程序包

fmin = Decimal(N) / Decimal(f2)
print Decimal(N) - (fmin * Decimal(f2))

但这给了我一个-1.481136900397802034028076389E+280的输出

我想我并没有告诉python如何正确地处理大数,但是我很难知道从这里开始该怎么做。

我还要补充一点,最终目标是

fmin = ceil(N / float(f2))

尽可能长和准确


Tags: 代码程序包数字floatlongf2decimalprint
3条回答

如果需要精度,请完全避免使用浮点运算。由于python有任意精度的整数,所以可以使用基本整数算法计算除法的上限。假设被除数和除数都是正的,方法是在除数之前把除数-1加到被除数上。就你而言:

fmin = (N + f2 - 1) / f2

在Python 3.x上,使用//运算符而不是/来获取整数除法。

如果Nf2严格大于0,那么

 fmin = (N - 1) // f2 + 1

完全是ceil(N / float(f2))(但比使用浮点更精确)。

(使用//而不是/进行整数除法是为了与Python 3.x兼容而无需额外的工作。)

因为N // f2给了你floor(N / float(f2)),所以N // f2 + 1几乎总是和ceil一样。但是,当Nf2的倍数时,N // f2 + 1太大(不应该有+1),但是使用N - 1可以修复这个问题,并且不会破坏另一个情况。

(这对于小于或等于0的Nf2都不起作用,但可以单独处理)

fmin是将长整数除以浮点数后的float。它的值是1.84952718165824e+305。再加上1根本不会改变它,精度根本没有那么高。

如果改为整数除法,fmin将保持为long

>>> fmin = N / f2
>>> fmin
18495271816582402193321106509793602189617847415669131056768139225220221855498293
49983070478076000952025038039460539798061570960870927236986153971731443029057201
52035339202255934728764897424408896865977423536890485615063959262845076766281553
766072964756078264853041334880929452289298495368916583660903481130L
>>> N - (fmin * f2)
111L

当然,您不会得到0,因为结果的小数部分在整数除法中被丢弃。 但现在,添加1将产生不同的效果:

>>> N - ((fmin+1) * f2)
-365L

使用Decimal模块不会改变问题:

>>> from decimal import Decimal, getcontext
>>> fmin = Decimal(N) / Decimal(f2)
>>> fmin
Decimal('1.849527181658240219332110651E+305')

仍然没有无限精度,即使设置了Decimal.getcontext().prec = 2000,也不会得到精确的0。

相关问题 更多 >

    热门问题