在C程序中我試圖下面的操作模運算(只是爲了檢查的行爲)負數
x = 5 % (-3);
y = (-5) % (3);
z = (-5) % (-3);
printf("%d ,%d ,%d", x, y, z);
給我輸出作爲GCC (2, -2 , -2)
。我每次都期待着一個積極的結果。模數可以爲負數嗎?任何人都可以解釋這種行爲嗎?
在C程序中我試圖下面的操作模運算(只是爲了檢查的行爲)負數
x = 5 % (-3);
y = (-5) % (3);
z = (-5) % (-3);
printf("%d ,%d ,%d", x, y, z);
給我輸出作爲GCC (2, -2 , -2)
。我每次都期待着一個積極的結果。模數可以爲負數嗎?任何人都可以解釋這種行爲嗎?
模操作的結果取決於分子的符號,因此你要-2 Ÿ和ž
這裏的參考
http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_14.html
整數部門
本節介紹執行整數除法的功能。 這些函數在GNU C庫中是多餘的,因爲在GNU C中, '/'操作符總是向零調整。但在其他C 實現中,'/'可能會因負面參數而異。 div和ldiv非常有用,因爲它們指定如何將商數:朝零調整。其餘部分與 分子的符號相同。
你指的是關於ANSI C的文本。這是一個相當古老的C規範。不是確定文本對於ANSI C是否正確,但絕對不適用於C99。在C99§6.5.5中,整數除法定義爲始終向零截斷。 – Palec 2014-02-05 20:36:49
和一個鏈接:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf – 2015-05-05 21:25:20
C99 需要當a/b
可表示:
(a/b) * b
+a%b
應等於a
這是有道理的,在邏輯上。對不對?
讓我們來看看這導致:
例A. 5/(-3)
是-1
=>(-1) * (-3)
+5%(-3)
= 5
這隻能發生,如果5%(-3)
是2.
實施例B.(-5)/3
是-1
=>(-1) * 3
+(-5)%3
= -5
如果(-5)%3
是-2
編譯器是否足夠聰明並檢測到無符號模另一個無符號總是正數?目前(當然,GCC 5.2)編譯器似乎認爲在這種情況下「%」返回「int」,而不是「無符號」,即使兩個操作數都是uint32_t或更大。 – 2016-09-24 14:56:47
@FrederickNord你有一個例子來顯示[那個行爲](http://stackoverflow.com/questions/11720656/modulo-operation-with-negative-numbers#comment66655578_11720841)? – chux 2017-02-24 16:16:46
的%
操作者在C不在模操作者這隻能發生但其餘運營商。
模數和餘數運算符在負值方面有所不同。
對於餘數運算符,結果的符號與被除數的符號相同,而使用模運算符時結果的符號與除數相同。
下a % b
定義爲%
操作:
a == (a/b * b) + a % b
與/
整數除法具有朝向0
截斷。這是朝着0
(而不是朝向負性無限性)完成的截斷,其將%
定義爲餘數運算符而不是模運算符。
[餘數爲模數運算的結果]由定義(https://en.wikipedia.org/wiki/Remainder)。應該沒有剩餘操作符這樣的事情,因爲沒有剩餘操作這樣的事情,所以稱爲模數。 – gronostaj 2015-06-27 20:49:16
@gronostaj不在CS。查看像Haskell或Scheme這樣的更高級的語言,它們都定義了兩個不同的運算符(Scheme中的'remaining'和'modulo',Haskell中的'rem'和'mod')。這些運算符的規格在這些語言上的差異如何劃分:截斷爲0或朝向負無窮大。順便說一下,C標準決不會調用'*'模運算符*,他們只是將它命名爲*%運算符*。 – ouah 2015-12-21 16:55:44
不要與在C'remainder' _function_,它實現IEEE其餘與混淆圓入,向最近的分割 – Eric 2017-09-18 02:11:48
基於C99的規格:a = (a/b) * b + a % b
我們可以寫一個函數來計算(a % b) = a - (a/b) * b
!
int remainder(int a, int b)
{
return a - (a/b) * b;
}
對於模運算,我們可以有下面的函數(假設B> 0)
int mod(int a, int b)
{
int r = a % b;
return r < 0 ? r + b : r;
}
我的結論是(A%B)中C是一個餘數運算符和NOT模運算符。
此沒有給出陽性結果時,'B'是否定的(語義和實際上爲'r'和'b'都是負數,結果小於'-b')。爲了確保所有輸入的正面結果,你可以使用'r + abs(b)'或匹配'b's符號,你可以改變條件爲'r * b <0'。 – 2016-09-20 11:42:02
其他的答案已經在C99解釋或更高版本,涉及到負操作數整數的除法總是接近零截斷。
請注意,在C89中,向上或向下循環的結果是否是實現定義的。因爲在所有標準中(a/b) * b + a%b
等於a
,涉及負操作數的%
的結果也在C89中實現定義。
我不認爲有任何需要檢查數字是否定的。 找到正模的最簡單的一般函數就是這個 - 它可以對x的正值和負值都有效。
int modulo(int x,int N){
return (x % N + N) %N;
}
這對我有用。謝謝!!! – 2017-12-18 01:05:38
在這些慣例源於數學的數學中,沒有斷言模數運算應該產生積極結果。
例如,
1 mod 5 = 1,但它也可以等於-4。也就是說,1/5產生從0開始的餘數1或從5開始產生-4。(兩個因子爲5)
類似地, -1模5 = -1,但它也可以等於4。 1/5從-5得到0或4的餘數-1。 (兩個因子爲5)
欲瞭解更多,請查看equivalence classes數學。
模數運算符就像mod運算符,當數字是正數時,但是如果數字是負數,則不同。
很多次在問題中,我們被要求以10^9 + 7的模數給出答案。
讓答案(在使用模之前)用'a'表示。
簡單直接的基於規則
如果a是正,然後模10^9 + 7 = 一%(10^9 + 7)
如果是負,則模10^9 + 7 = (一%(10^9 + 7))+(10^9 + 7)
如果在SUC h問題,我們發現循環的任何一步可能會計算出一個超出整數範圍的值(如果我們使用整數),那麼我們可以在該步驟中使用模運算符。最終答案就好像我們只使用模運算符一次。
這是因爲 - (a * b)%c =((a%c)(b%c))%c同樣適用於加法和減法。
模運算符給出餘數。在C 模運算符通常需要分子
此外模數(餘數)操作者只能與使用整型,不能與浮點一起使用。
如果您可以通過指向外部資源的鏈接來支持它,那就太好了。 – 2017-08-26 16:13:02
https://archive.org/details/letusc_201605 – Kavya 2017-08-28 16:42:22
可能的重複http://stackoverflow.com/questions/4003232/how-to-code-a-modulo-operator-in-cc-obj-c-that-handles-negative-numbers – james 2012-07-30 11:41:15
可能重複的[模運算符與負值](http://stackoverflow.com/questions/7594508/modulo-operator-with-negative-values) – sugavaneshb 2015-02-08 08:46:18