[英]Why is the behavior of the modulo operator (%) different between C and Ruby for negative integers?
我在這里運行了一些代碼。 我試過-40 % 3
。 它給了我輸出2
。 當我在 C 中執行相同的操作時,我得到:
int i = (-40) % 3
printf("%d", i);
輸出是
-1
兩種語言如何在內部執行模運算?
維基說:
給定兩個正數
a
(被除數)和n
(除數),模 n (縮寫為 mod n)是a by n
的余數。
....當a
或n
為負數時,幼稚的定義就會失效,並且編程語言在定義這些值的方式上有所不同。
現在的問題是為什么-40 % 3
在 Ruby 中是2
或者換句話說,它背后的數學是什么?
讓我們從歐幾里得除法開始,它指出:
給定兩個整數
a
和n
,其中n ≠ 0
,存在唯一整數q
和r
使得a = n*q + r
且0 ≤ r < |n|
, 其中|n|
表示n
的絕對值。
現在注意商的兩個定義:
q=floor(a/n)
,余數r
是: 這里商 ( q
) 總是向下舍入(即使它已經是負數),余數 ( r
) 與除數具有相同的符號。
q = sgn(a)floor(|a| / n)
sgn
是符號函數。
余數 ( r
) 與被除數 ( a
) 的符號相同。
現在一切都取決於q
:
- 如果實現符合定義
1
並將q
定義為floor(a/n)
則40 % 3
值為1
,-40 % 3
值為2
。 這似乎是 Ruby 的情況。- 如果實現符合定義
2
並將q
定義為sgn(a)floor(|a| / n)
,則40 % 3
值為1
,-40 % 3
值為-1
。 這似乎是 C 和 Java 的情況。
在 Java 和 C 中,模運算的結果與被除數具有相同的符號,因此 -1 是您示例中的結果。
在 Ruby 中,它與除數具有相同的符號,因此根據您的示例,結果為 +2。
在 ruby 實現中,當分子為負而分母為正時,取模運算符回答的問題是,“從分子中減去時,允許分母整除的最小正數是多少?”
在所有實現中,當分子和分母都是正數時,要回答的問題是:“當從分子中減去時,允許分母平均除以結果的最小正數是多少?”
因此,您可以看到 ruby 實現始終在回答相同的問題,即使結果起初並不直觀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.