簡體   English   中英

Python 3.7 math.remainder 和 %(modulo operator) 之間的區別

[英]Difference between Python 3.7 math.remainder and %(modulo operator)

What's New In Python 3.7我們可以看到有新的math.remainder 它說

返回 x 相對於 y 的 IEEE 754 樣式余數。 對於有限 x 和有限非零 y,這是x - n*y的差值,其中 n 是最接近商x / y精確值的整數。 如果x / y正好位於兩個連續整數的中間,則最近的偶數整數用於n 因此,余數r = remainder(x, y)總是滿足abs(r) <= 0.5 * abs(y)

特殊情況遵循 IEEE 754:特別是,對於任何有限的remainder(x, math.inf)是 x,並且對於任何非 NaN x remainder(math.inf, x) remainder(x, 0)remainder(math.inf, x)引發ValueError 如果余數運算的結果為零,則該零的符號與 x 相同。

在使用 IEEE 754 二進制浮點數的平台上,此操作的結果始終可以精確表示:不引入舍入誤差。

但我們也記得有%符號是

x / y余數

我們還看到操作員有一個注釋:

不適用於復數。 如果合適,改為使用abs()轉換為浮點數。

如果可能的話,我還沒有嘗試運行 Python 3.7。

但我試過了

Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> 100 % math.inf
100.0
>>> math.inf % 100
nan
>>> 100 % 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

所以區別ZeroDivisionError我們會得到ValueError ,而不是nanZeroDivisionError正如它在文檔中所說的那樣。

所以問題是%math.remainder之間有什么區別? math.remainder也適用於復數(缺少% )? 主要優勢是什么?

這是官方 CPython github 存儲庫math.remainder來源

返回 x 相對於 y 的 IEEE 754 樣式余數。 對於有限 x 和有限非零 y,這是x - n*y的差值,其中 n 是最接近商x / y精確值的整數。 如果x / y正好位於兩個連續整數的中間,則 n 使用最近的偶數。 因此,余數r = remainder(x, y)總是滿足abs(r) <= 0.5 * abs(y)

對於模數,這是m = x - n*y其中nfloor(x/y) ,所以0 <= m < y而不是abs(r) <= 0.5 * abs(y)余數。

所以

modulo(2.7, 1) = 0.7
remainder(2.7, 1) = -0.3

感謝@MaartenFabré,我沒有注意細節:

math.remainder()x - n*y的差值,其中n是最接近商x / y精確值的整數

我構建了 Python 3.7:

Python 3.7.0a0 (heads/master:f34c685020, May  8 2017, 15:35:30)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import math

以下是不同之處:

零作為除數:

>>> math.remainder(1, 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error
>>> 1 % 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

基本數字,其中math.remainder(x, y) < x % y

>>> math.remainder(5, 3)
-1.0
>>> 5 % 3
2

復數:

>>> math.remainder(3j + 2, 4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't convert complex to float
>>> (3j + 2) % 4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't mod complex numbers.

無窮大( math.inf )

>>> math.remainder(3, math.inf)
3.0
>>> 3 % math.inf
3.0
>>> math.remainder(math.inf, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error
>>> math.inf % 3
nan

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM