從C++和Python除法的區別談談求模(Modulus)和取余(Remainder)


今天發現一個很有意思的現象。

當做除法的時候,Python2和C++在負數的情況下會得到不同的整除結果:

當做-5 / 3的時候

C++的結果: -1

Python2的結果:-2

(請注意5 / -3的時候仍然會在C++中得到-1, Python2中得到-2)

 

可以看出C++在進行負數整除的時候執行的是直接舍去小數點后數字的操作,也就是返回和0比較接近的那個數字。

但在Python2中返回的則是小於等於商的最大整數,也就是返回和-∞更接近的數。

 

在做%操作的時候,依據的是這樣的邏輯:

a = b * c + r

其中a是被除數,b是除數,c是商,r是%操作的結果。

在上述例子中,a和b是-5和3。

C++的情況下商c是-1,因此r可以算出來是-2。

Python情況下商c是-2,因此r可以算出來是1。

 

!!!值得注意的是:當把操作改成5 % -3的時候,C++的結果是2,Python2的結果是-1,和之前的結果正好符號相反。

如果有同學覺得這里非常亂,請牢記a = b * c + r。

用同樣的邏輯,當a是5,b是-3時,c++因為商c是-1,因此r是2,Python時商c是-2因此r是-1。

 

那么造成這種差異的原因是什么呢?

 

其實是因為“求模”(Modulus)和“取余”(Remainder)的區別。

很多同學可能認為,求模運算和取余運算是一回事。實際上在正整數范圍內它們確實表現出完全相同的性質。但在負數運算的情況下,它們則會表現出不同的行為。

C++的%表現出的是“取余”操作的結果。

Python的%表現出的是“求模”操作的結果。

 

無論C++還是Python,求模和取余都是根據a = b * c + r這個公式定義的,而唯一的區別就是商c究竟是向0方向取整還是向-∞方向取整。

當商c向0方向取整的時候,得到的r是“余數”,也就是在C++中的結果。

當商c向-∞方向取整的時候,得到的r是“模數”,也就是在Python2中的結果。

 

在Python3中,無論“/”兩邊是否均為整數,運算的時候都轉換成實數運算並返回實數。整除則用“//”來表示。

利用Python這個整除的特性,我們可以得到一個小技巧:

很多時候我們會碰到“某物x個一組,一共需要y個,至少需要多少組?”這樣的問題。

在C++中我們必須寫成這樣的邏輯:answer = y / x; if (y % x != 0) ans += 1;

在Python中我們可以利用負數的特性很方便地得到結果:answer = -(-y // x)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM