簡體   English   中英

為什么對於負整數,C 和 Ruby 之間的模運算符 (%) 的行為不同?

[英]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的余數。
....an為負數時,幼稚的定義就會失效,並且編程語言在定義這些值的方式上有所不同


現在的問題是為什么-40 % 3在 Ruby 中是2或者換句話說,它背后的數學是什么?

讓我們從歐幾里得除法開始,它指出:

給定兩個整數an ,其中n ≠ 0 ,存在唯一整數qr使得a = n*q + r0 ≤ r < |n| , 其中|n| 表示n的絕對值。

現在注意商的兩個定義:

  1. Donald Knuth描述了地板除法,其中商由地板函數q=floor(a/n) ,余數r是:

在此處輸入圖片說明

這里商 ( q ) 總是向下舍入(即使它已經是負數),余數 ( r ) 與除數具有相同的符號

  1. 一些實現將商定義為:

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.

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