如何使用取模运算处理大浮点数

3

嗨,我想使用模数运算处理大的浮点数,但Python好像不太喜欢那些大数字。我的目标是检查两个整数的除法是否得到整数结果(所以如果 division_result%1 == 0,则为整数)。

例如:

x = 3**2
x = x+0.3
x%1
result = 0.3000000000000007 | expected = 0.3
x = 3**199
x = x+0.3
x%1
result = 0.0 |expected = 0.3

我应该如何提高结果的精度,或者找到一个聪明的方法来检查除法是否得到整数?


2
阅读有关浮点表示法的内容。对于足够大的浮点数,没有足够的精度来跟踪所有数字,因此会得到不正确的结果。 - Leon
4个回答

4

并非所有的分数都能够以浮点数的形式精确地表示。因此,你的方法可能无法正常工作。

你可以尝试使用fractions模块:

from fractions import Fraction

print(repr(Fraction(25, 5)))  # Fraction(5, 1)

这是使用Fraction的方法:

def div_result_int(a, b):

    f = Fraction(a, b)
    return f.denominator == 1

print(div_result_int(a=25, b=5))  # True
print(div_result_int(a=25, b=3))  # False

2

对于整数xy,如果且仅当y % x == 0时,分数y/x为整数。只要xy是整数,你不必担心浮点误差、特殊数字类或任何其他问题。只需确保xy实际上被表示为整数而不是浮点数。由于Python可以处理大整数,因此这适用于长于64位的整数,例如:

> x = 17**100
> y = 17**200    
> y % x
0
> (y + 1) % x
1

0

您可以使用 float.is_integer() 来测试实数或自然数值:

>>> x=3**23
>>> y=3**299
>>> res=x/y
>>> res
2.0631637441810574e-132
>>> res.is_integer()
False
>>> res=4.0000000000004
>>> res.is_integer()
False
>>> res=4.000
>>> res.is_integer()
True

0
另一个选项是使用decimal模块。
以您的第一个示例为例:
import decimal
x = decimal.Decimal('9.3')
x % 1

结果将会是Decimal('0.3')

对于第二个例子,您需要将精度设置为50:

decimal.getcontext().prec = 50
x = decimal.Decimal('171792506910670443678820376588540424234035840667.3')

再次强调,x % 1 的结果将会是 Decimal('0.3')


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接