负数的奇怪Objective-C Mod行为

con*_*are 42 objective-c modulo

所以我认为负数,当mod'ed应该被放入正空间...我不能让这发生在objective-c

我期待这个:

-1 % 3 = 2
 0 % 3 = 0
 1 % 3 = 1
 2 % 3 = 2
Run Code Online (Sandbox Code Playgroud)

但得到这个

-1 % 3 = -1
 0 % 3 = 0
 1 % 3 = 1
 2 % 3 = 2
Run Code Online (Sandbox Code Playgroud)

为什么会这样,是否有解决方法?

Unc*_*leO 53

result = n % 3;
if( result < 0 ) result += 3;
Run Code Online (Sandbox Code Playgroud)

不要像其他答案中所建议的那样执行额外的mod操作.它们非常昂贵且不必要.

  • if()几乎肯定比第二个mod更快; 任何体面的优化编译器都可以将if()转换为cmov(条件移动)指令,这将在没有分支的情况下执行相同的操作. (4认同)
  • 我从来没有见过一个处理器,其中除法或模数不是最慢的操作.检查负数会减少测试位的值,因此通常是最快的指令之一. (2认同)

Ada*_*eld 14

在C和Objective-C中,除法和模运算符执行截断为零. a / bfloor(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,和negative % negative == negative(你可以制定出所有4个案件的逻辑,虽然这是一个有点棘手).


Pet*_*wis 8

如果n具有有限的范围,那么您可以通过添加3的已知常数倍数来获得您想要的结果,该常数倍数大于最小值的绝对值.

例如,如果n限制为-1000..2000,那么您可以使用以下表达式:

result = (n+1002) % 3;
Run Code Online (Sandbox Code Playgroud)

确保最大加上常量在求和时不会溢出.


Art*_*ldt 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运算符,通过检查每次进行减法时是否掉到底部.


max*_*llb 5

如果这将是行为,并且您知道它将是,那么对于m % n = r,只需使用r = n + r。如果您不确定这里会发生什么,请使用 then r = r % n

编辑:总结一下,使用r = ( n + ( m % n ) ) % n