簡體   English   中英

具有負值的模數運算 - 奇怪的是什么?

[英]Modulus operation with negatives values - weird thing?

你能告訴我(-2) % 5多少錢? 根據我的Python解釋器是3,但你有一個明智的解釋嗎?

我讀過在某些語言中,結果可能與機器有關,但我不確定。

順便說一句:大多數編程語言都不同意Python並給出結果-2 根據模數的解釋,這是正確的。 然而,最常見的數學定義表明ab的模數是a / b除法的(嚴格為正)余數r 更准確地說,根據定義,0 <= r < b

負面模數運算的結果似乎是編程語言依賴,這里是一個列表http://en.wikipedia.org/wiki/Modulo_operation

你的Python解釋器是正確的。 計算模量的一種(愚蠢的)方法是減去或加上模數,直到結果值在0和(模數-1)之間。

例如:13 mod 5 =(13-5)mod 5 =(13-10)mod 5 = 3

或者在你的情況下:-2 mod 5 =( - 2 + 5)mod 5 = 3

就像文檔在二進制算術運算中所說的那樣,Python保證:

整數除法和模運算符通過以下標識連接: x == (x/y)*y + (x%y) 整數除法和模數也與內置函數divmod()連接: divmod(x, y) == (x/y, x%y)

真的,

>>> divmod(-2, 5)
(-1, 3).

另一種可視化此方法均勻性的方法是計算divmod數字的divmod

>>> for number in xrange(-10, 10):
...     print divmod(number, 5)
...
(-2, 0)
(-2, 1)
(-2, 2)
(-2, 3)
(-2, 4)
(-1, 0)
(-1, 1)
(-1, 2)
(-1, 3)
(-1, 4)
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(1, 4)

那么,0%5應該是0,對嗎?

-1%5應該是4,因為這是下一個允許的數字反向運行(即,它不能是5,因為它超出了范圍)。

遵循該邏輯,-2必須為3。

考慮它如何工作的最簡單方法是在數字落在0(含)和5(不包括)之間繼續加5或減5。

我不確定機器依賴 - 我從來沒有見過一個實現,但我不能說它從未完成。

正如其他答案中所解釋的,對於具有負值的模運算有很多選擇。 通常,不同的語言(和不同的機器架構)將給出不同的結果。

根據Python參考手冊

模運算符總是產生一個與第二個操作數(或零)相同符號的結果; 結果的絕對值嚴格小於第二個操作數的絕對值。

是Python的選擇。 基本上定義模數,以便始終保持:

x == (x/y)*y + (x%y)

所以有意義的是(-2)%5 = -2 - (-2/5)* 5 = 3

好吧,-2除以5將為0,其余為3.我不相信這應該是非常依賴平台的,但我看到了陌生的東西。

確實是3.在模運算中 ,模數只是除法的余數,-2除以5的余數是3。

結果取決於語言。 Python返回除數的符號,例如c#返回被除數的符號(即-2%5在c#中返回-2)。

一種解釋可能是使用2的補碼存儲負數。 當python解釋器嘗試進行模運算時,它會轉換為無符號值。 因此,它不是做(-2)%5而是實際計算0xFFFF_FFFF_FFFF_FFFD%5,即3。

注意不要在所有操作系統和體系結構上依賴C / C ++中的這種mod行為。 如果我沒記錯的話,我試着依賴C / C ++代碼

float x2 = x % n;

將x2保持在從0到n-1的范圍內,但是當我在一個操作系統上編譯時,負數會悄悄進入,但事情在另一個操作系統上可以正常工作。 這是一個邪惡的時間調試,因為它只發生了一半的時間!

術語“模數”和“余數”之間似乎存在共同的混淆。

在數學中,余數應始終定義與商一致,因此如果a / b == c rem d(c * b) + d == a 根據你如何圍繞你的商,你得到不同的余數。

但是,模數應始終給出結果0 <= r < divisor ,如果允許負整數,則僅與舍入到負無窮除法一致。 如果除法向零舍入(這是常見的),則模數和余數僅等於非負值。

某些語言(特別是C和C ++)沒有定義所需的舍入/余數行為, %是不明確的。 許多人將舍入定義為零,但使用術語模數,其中余數更正確。 Python是相對不尋常的,因為它舍入到負無窮大,因此模數和余數是等價的。

Ada向零IIRC轉向,但同時擁有modrem運營商。

C策略旨在允許編譯器為機器選擇最有效的實現,但IMO至少是錯誤的優化。 一個好的編譯器可能能夠在不能出現負數的情況下使用等價進行優化(如果使用無符號類型,幾乎可以肯定)。 另一方面,在可能出現負數的情況下,您幾乎肯定會關注細節 - 出於便攜性的原因,您必須使用非常精心設計的過復雜算法和/或檢查以確保您獲得所需的結果,而不考慮舍入和余數行為。

換句話說,這種“優化”的增益主要是(如果不是總是)一種錯覺,而在某些情況下則存在非常實際的成本 - 所以這是一種錯誤的優化。

暫無
暫無

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

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