當我在Objective-C中進行模運算時,我得到的結果有點嚇壞了。 -1%3出來是-1,這是不正確的答案:根據我的理解,它應該是-2 -2%3出現-2,這也是不正確的:它應該是1.Objective-C中的Modulo運算符返回錯誤結果
除了%運算符以獲得正確的結果之外,還有另外一種方法嗎?
當我在Objective-C中進行模運算時,我得到的結果有點嚇壞了。 -1%3出來是-1,這是不正確的答案:根據我的理解,它應該是-2 -2%3出現-2,這也是不正確的:它應該是1.Objective-C中的Modulo運算符返回錯誤結果
除了%運算符以獲得正確的結果之外,還有另外一種方法嗎?
帶負數的Modulo並不像您想象的那樣直截了當。請參閱http://mathforum.org/library/drmath/view/52343.html
Objective-C是C99的超集,而C99的定義a % b
在a
爲負數時爲負數。另見the Wikipedia entry on the Modulo operation和this StackOverflow question。
類似於(a >= 0) ? (a % b) : ((a % b) + b)
(尚未經過測試,可能有不必要的括號)應該會給你想要的結果。
太棒了!它對我很有幫助,但是我記錄了兩種導致我錯誤的情況:(1)-n mod n給出了n而不是0.(2)將它定義爲宏時,有些括號中出現混淆。我最終這樣做: #define模塊(a,b)(a> = 0 || - (a)==(b))? (a)%(b):((a)%(b)+ b) – kahlo 2013-08-25 20:10:49
ANSI C99 6.5.5乘operators-
6.5.5.5:在操作者/
的結果是由第二所述第一操作數的除法的商;餘下的是%
運算符的結果。在兩種操作中,如果第二個操作數的值爲零,則行爲未定義。
6.5.5.6:當整數分開時,/
算子的結果是捨棄任何小數部分(* 90)的代數商。如果商a/b
可表示,則表示(a/b)*b + a%b
應等於a
。
* 90:這通常稱爲「向零截斷」。
您正在考慮的模行爲的類型稱爲「模運算」或「數論」樣式模/餘數。使用模運算符的模算術/數論定義,得到否定結果是不合理的。這顯然不是C99定義和使用的模行爲的風格。 C99的方式沒有什麼「錯誤」,這不符合你的期望。 :)
一個明確的功能,會給你正確的答案是在年底,但首先,這裏所討論的的一些其他的想法解釋:
其實,(a >= 0) ? (a % b) : ((a % b) + b)
只會導致如果負數a在b的一個倍數內,則爲正確答案。
換句話說:如果您想查找:-1%3,那麼當然,(a >= 0) ? (a % b) : ((a % b)+ b)
將起作用,因爲您在((a % b) + b)
的末尾加回。
-1 % 3 = -1
and -1 + 3 = 2
,這是正確的答案。
但是,如果你嘗試它= -4和b = 3,那麼它將無法工作:
-4 % 3 = -4
但 -4 + 3 = -1
。
雖然這在技術上也等同於2(模3),但我不認爲這是您正在尋找的答案。您可能期待規範形式:答案應始終爲0到n-1之間的非負數。
你不得不增加+3兩次得到的答案:
-4 + 3 = -1
-1 + 3 = 2
這裏是做一個明確的方式:
a - floor((float) a/b)*b
**要小心!確保你保持(浮)鑄在那裏。否則,它會將a/b分成整數,您會得到意想不到的答案。當然,這意味着你的結果也將是一個浮動。它將是一個寫成浮點數的整數,如2.000000,因此您可能希望將整個答案轉換回整數。
(int) (a - floor((float) a/b)*b)
斯賓塞,有一種簡單的方法來思考mods(它在數學中定義的方式,而不是編程)。它實際上是相當簡單:
採取所有的整數:
...- 9,-8,-7,-6,-5,-4,-3,-2,-1,0, 1,2,3,4,5,6,7,8,9 ...
現在我們來考慮3的倍數(如果您正在考慮mod 3)。讓我們從0開始,並且3的正整數:
... -9,-8,-7,-6,-5,-4,-3,-2,-1,,1 ,2,3 ,4,5,6 ,7,8,9 ...
這些都是當除以3具有一個零剩餘的數字,即,這些都是修改爲零的那些。
現在讓我們把這整個組合起來。
...- 9,-8,-7,-6,-5,-4,-3,-2,-1,0,,2,3,4 ,5, 6,,8,9 ...
這些都是當除以3具有一爲1其餘部分的數字,即,這些都認爲國防部爲1
現在讓我們移的那些這整個組合再次由一個。
...- 9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2 ,3,4,5 , 6,7,8 ,9 ...
這些都是當除以3即有2個剩餘數量,即這些都認爲國防部於2
你的那些注意,在每種情況下,選中的數字間隔爲3.因爲我們考慮模3,所以我們總是取每三位數。(如果我們在做模5,我們會每五位取一個數)。
所以,你可以將這種模式向後轉換爲負數。只需保持3的間距。你會得到這三個相同級(一種特殊類型的等價類,因爲他們是所謂的在數學):
... -9,-8,-7,-6,-5,-4,-3 ,-2,-1,,1,2,3 ,4,5,6 ,7,8,9 ...
...- 9,-8,-7,-6,-5 ,-4,-3,-2 ,-1,0,,2,3,4 ,5,6,7 ,8,9 ...
...- 9,-8,-7 ,-6,-5,-4 ,-3,-2,-1 ,0, 1,,3,4,,6,7,,9 ...
所有這些等效數字的標準數學表示法是使用該類的殘基,這意味着取最小的非負數。
所以通常情況下,當我想MODS的,我處理的是一個負數,我只是覺得先後連連加模數,直到我得到的第一個0或正數:
如果我們在做mod 3,然後用-1,只需加3一次:-1 + 3 = 2. 隨着-4,兩次加3,因爲一次不夠。如果我們加一次+3,我們得到-4 + 3 = -1,這仍然是負值。所以我們再次加上+3:-1 + 3 = 2.
讓我們嘗試一個更大的負數,比如-23。如果不斷增加+3,你會得到:
-23,-20,-17,-14,-11,-8,-5,-2,1。我們得到了一個正數,所以我們停止。殘差是1,這是數學家通常使用的形式。
我有同樣的問題,但我解決了它!您只需檢查數字是正數還是負數,如果數字是負數,則需要再添加一個數字:
//neg
// -6 % 7 = 1
int testCount = (4 - 10);
if (testCount < 0) {
int moduloInt = (testCount % 7) + 7; // add 7
NSLog(@"\ntest modulo: %d",moduloInt);
}
else{
int moduloInt = testCount % 7;
NSLog(@"\ntest modulo: %d",moduloInt);
}
// pos
// 1 % 7 = 1
int testCount = (6 - 5);
if (testCount < 0) {
int moduloInt = (testCount % 7) + 7; // add 7
NSLog(@"\ntest modulo: %d",moduloInt);
}
else{
int moduloInt = testCount % 7;
NSLog(@"\ntest modulo: %d",moduloInt);
}
希望對您有所幫助!答:
好奇,如果任何這些答案重新模數你正在尋找 – kris 2011-11-10 16:02:42
使用frem(a,b) - 你期待的模數(這是標準數學中使用的那種)在編碼中被稱爲「餘數」 。 C有fmod()和frem(),你使用的是mod(又名「%」),你需要使用rem。數學模數===代碼中的剩餘(rem)。啞巴,我知道。 – 2016-07-07 07:36:05
它引起了我的注意,frem(a,b)僅在GNU C中,沒有被帶入Obj-C。相當於這樣:'a-b * floor((float)a /(float)b)' – 2016-07-07 07:44:46