Python 对 float 取模

标签 python modulo

谁能解释模运算符在 Python 中的工作原理? 我不明白为什么 3.5 % 0.1 = 0.1.

最佳答案

实际上,3.5 % 0.10.1 是不正确的。您可以很容易地对此进行测试:

>>> print(3.5 % 0.1)
0.1
>>> print(3.5 % 0.1 == 0.1)
False

实际上,在大多数系统上,3.5 % 0.10.099999999999999811。但是,在某些版本的 Python 上,str(0.099999999999999811)0.1:

>>> 3.5 % 0.1
0.099999999999999811
>>> repr(3.5 % 0.1)
'0.099999999999999811'
>>> str(3.5 % 0.1)
'0.1'

现在,您可能想知道为什么 3.5 % 0.10.099999999999999811 而不是 0.0。这是因为通常的浮点舍入问题。如果您还没有阅读 What Every Computer Scientist Should Know About Floating-Point Arithmetic ,你应该——或者至少是简短的 Wikipedia这个特定问题的摘要。

还要注意 3.5/0.1 不是 34,它是 35。所以,3.5/0.1 * 0.1 + 3.5%0.13.5999999999999996,这甚至不是 接近3.5 .这对于模数的定义非常重要,但在 Python 和几乎所有其他编程语言中都是错误的。

但是 Python 3 来拯救那里。大多数了解 // 的人都知道这是你如何在整数之间进行“整数除法”,但没有意识到这是你如何在 any 之间进行模数兼容的除法类型。 3.5//0.134.0,所以 3.5//0.1 * 0.1 + 3.5%0.1 是(至少在一个小的舍入误差之内) 3.5。这已被向后移植到 2.x,因此(取决于您的确切版本和平台)您可以依赖它。如果没有,您可以使用 divmod(3.5, 0.1),它返回(在舍入误差内)(34.0, 0.09999999999999981) 一直回到时间的迷雾.当然,您仍然希望这是 (35.0, 0.0),而不是 (34.0, about-0.1),但由于舍入错误,您不能这样。

如果您正在寻找快速解决方案,请考虑使用 Decimal类型:

>>> from decimal import Decimal
>>> Decimal('3.5') % Decimal('0.1')
Decimal('0.0')
>>> print(Decimal('3.5') % Decimal('0.1'))
0.0
>>> (Decimal(7)/2) % (Decimal(1)/10)
Decimal('0.0')

这不是 Elixir ——例如,当运算的确切值不能以 10 为基数有限表示时,你仍然需要处理舍入误差——但舍入误差更符合情况人类的直觉预计会有问题。 (与 float 相比,Decimal 还具有优势,您可以指定显式精度、跟踪有效数字等,并且它在所有 Python 版本中实际上都是相同的2.4 到 3.3,而关于 float 的详细信息同时更改了两次。只是它并不完美,因为那是不可能的。)但是当您提前知道您的数字都是完全可表示的时以 10 为底,并且它们不需要比您配置的精度更多的数字,它会起作用。

关于Python 对 float 取模,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14763722/

相关文章:

python - NLTK 与斯坦福 NLP

Python PIL 从 STDIN 读取 PNG

python - 如何在 Windows 中从命令行启动atom

python - 如何处理 AWS Lambda 中的大依赖?

c - 测试一个数是否能整成 6?

algorithm - 如何有效解决涉及 'modulo' 操作的编码问题?

c++ - 为什么 0 mod 0 是一个错误?

javascript - Python Selenium : wait until class is visible

Javascript:减少到一个数字

c++ - 条件表达式中的模数