所以我认为负数,当mod'ed应该被放入正空间...我不能让这发生在objective-c
我希望如此:
-1 % 3 = 2
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
但是得到这个
-1 % 3 = -1
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
为什么会这样,是否有解决方法?
答案 0 :(得分:53)
result = n % 3;
if( result < 0 ) result += 3;
不要按照其他答案中的建议执行额外的mod操作。它们非常昂贵且不必要。
答案 1 :(得分:14)
在C和Objective-C中,除法和模运算符执行截断为零。如果a / b
,则floor(a / b)
为a / b > 0
,否则ceiling(a / b)
为a / b < 0
。 a == (a / b) * b + (a % b)
总是如此,除非b
当然为0.因此,positive % positive == positive
,positive % negative == positive
,negative % positive == negative
和{{1} (你可以计算所有4个案例的逻辑,虽然这有点棘手)。
答案 2 :(得分:8)
如果n的范围有限,那么只需添加一个大于最小值绝对值的3的已知常数倍,就可以得到想要的结果。
例如,如果n限制为-1000..2000,则可以使用表达式:
result = (n+1002) % 3;
确保求和后最大加上常数不会溢出。
答案 3 :(得分:7)
我们遇到语言问题:
math-er-says: i take this number plus that number mod other-number code-er-hears: I add two numbers and then devide the result by other-number code-er-says: what about negative numbers? math-er-says: WHAT? fields mod other-number don't have a concept of negative numbers? code-er-says: field what? ...
在这种情况下,您需要数学家的mod运算符,并且可以使用余数函数。你可以将余数运算符转换为数学家的mod运算符,通过检查每次进行减法时是否掉到底部。
答案 4 :(得分:4)
我本来期望得到一个正数,但我从ISO / IEC 14882:2003:编程语言 - C ++,5.6.4(在Wikipedia article on the modulus operation中找到)中找到了这个:
二进制%运算符从第一个表达式除以第二个表达式得到余数。 ....如果两个操作数都是非负的,那么余数是非负的;如果没有,余数的符号是实现定义的
答案 5 :(得分:4)
如果这是行为,并且您知道它会是,那么对于m % n = r
,只需使用r = n + r
。如果您不确定此处会发生什么,请使用r = r % n
。
编辑:总结一下,使用r = ( n + ( m % n ) ) % n
答案 6 :(得分:1)
JavaScript也是这样做的。我被它抓了好几次。可以把它想象成零而不是延续的反映。
答案 7 :(得分:1)
为什么:因为这是在C标准中指定mod运算符的方式(请记住,Objective-C是C的扩展)。它让我认识的大多数人(比如我)感到困惑,因为它令人惊讶,你必须记住它。
至于解决方法:我会使用uncleo's。
答案 8 :(得分:1)
UncleO的答案可能更强大,但是如果你想在单行上做,并且你确定负值不会比mod的单次迭代更负面例如,如果您在任何时候只能减去mod值,那么您可以将其简化为单个表达式:
int result = (n + 3) % 3;
因为你正在做mod,所以在初始值上加3对没有影响,除非 n为负(但不小于-3),在这种情况下它会导致结果为预期正模量。
答案 9 :(得分:0)
其余部分有两种选择,符号取决于语言。 ANSI C选择被除数的符号。我怀疑这就是为什么你看到Objective-C这样做的原因。 See the wikipedia entry as well
答案 10 :(得分:0)
不仅是java脚本,几乎所有语言都显示错误答案' coneybeare说的是正确的,当我们有模式时,我们必须得到余数 剩余只不过是除法之后剩余的,它应该是一个正整数....
如果您检查数字线,则可以理解
我在VB中也面临同样的问题,它让我强行添加额外的支票 如果结果是否定的,我们必须在结果中添加除数
答案 11 :(得分:0)
而不是a%b
使用:a-b*floor((float)a/(float)b)
您期望余下并且正在使用 modulo 。在数学中它们是相同的东西,在C中它们是不同的。 GNU-C有Rem()和Mod(),objective-c只有mod()所以你必须使用上面的代码来模拟rem函数(这与数学世界中的mod相同,但不是在编程中世界[至少对大多数语言而言])
另请注意,您可以为此定义一个易于使用的宏。
#define rem(a,b) ((int)(a-b*floor((float)a/(float)b)))
然后你可以在你的代码中使用rem(-1,3)
,它应该可以正常工作。