Python模拟浮点数

任何人都可以解释模运算符在Python中的工作原理吗?
我不明白为什么3.5%0.1 = 0.1。
实际上,3.5%0.1是0.1是不正确的。你可以很容易地测试:

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

实际上,在大多数系统上,3.5%0.1是0.099999999999999811。但是,在某些版本的Python上,str(0.0999999999999811)为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.1是0.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.1是3.5999999999999996,甚至不接近3.5。这对于定义模数几乎是至关重要的,Python的错误以及其他所有的编程语言都是错误的。

但是Python 3在那里得到救援。大多数人知道//知道它是如何在整数之间进行“整数除法”,但是不知道它是如何在任何类型之间进行模数兼容的划分。 3.5 // 0.1是34.0,所以3.5 // 0.1 * 0.1 3.5%0.1是(至少在小的舍入误差内)3.5。这已经反映到2.x,所以(取决于你的确切的版本和平台),你可以依靠这个。而且,如果没有,可以使用divmod(3.5,0.1),它返回(在舍入误差内)(34.0,0.099999999999981)一直回到时间的迷雾。当然,你仍然希望这是(35.0,0.0),而不是(34.0,几乎-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')

这不是一个神奇的灵丹妙药 – 如果你有数字可以表示为2级浮标,而不是10级浮点数,那实际上会更糟。 (对于浮点数,十进制仍然有优势,因为您可以指定显式精度,跟踪有效数字等,并且在所有Python版本中从2.4到3.3实际上相同,而float的详细信息在同时,只是这不完美,因为这是不可能的。)但是,如果你提前知道你的数字在10中完全可以表示,它将会奏效。

http://stackoverflow.com/questions/14763722/python-modulo-on-floats

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:Python模拟浮点数