Weird Objective-C Mod Behavior for Negative Numbers

前端 未结 12 1901
旧巷少年郎
旧巷少年郎 2020-12-09 15:00

So I thought that negative numbers, when mod\'ed should be put into positive space... I cant get this to happen in objective-c

I expect this:

-1 % 3          


        
相关标签:
12条回答
  • 2020-12-09 15:14

    In C and Objective-C, the division and modulus operators perform truncation towards zero. a / b is floor(a / b) if a / b > 0, otherwise it is ceiling(a / b) if a / b < 0. It is always the case that a == (a / b) * b + (a % b), unless of course b is 0. As a consequence, positive % positive == positive, positive % negative == positive, negative % positive == negative, and negative % negative == negative (you can work out the logic for all 4 cases, although it's a little tricky).

    0 讨论(0)
  • 2020-12-09 15:14

    If this will be the behavior, and you know that it will be, then for m % n = r, just use r = n + r. If you're unsure of what will happen here, use then r = r % n.

    Edit: To sum up, use r = ( n + ( m % n ) ) % n

    0 讨论(0)
  • 2020-12-09 15:16

    JavaScript does this, too. I've been caught by it a couple times. Think of it as a reflection around zero rather than a continuation.

    0 讨论(0)
  • 2020-12-09 15:18

    Instead of a%b

    Use: a-b*floor((float)a/(float)b)

    You're expecting remainder and are using modulo. In math they are the same thing, in C they are different. GNU-C has Rem() and Mod(), objective-c only has mod() so you will have to use the code above to simulate rem function (which is the same as mod in the math world, but not in the programming world [for most languages at least])


    Also note you could define an easy to use macro for this.

    #define rem(a,b) ((int)(a-b*floor((float)a/(float)b)))

    Then you could just use rem(-1,3) in your code and it should work fine.

    0 讨论(0)
  • 2020-12-09 15:25

    If n has a limited range, then you can get the result you want simply by adding a known constant multiple of 3 that is greater that the absolute value of the minimum.

    For example, if n is limited to -1000..2000, then you can use the expression:

    result = (n+1002) % 3;
    

    Make sure the maximum plus your constant will not overflow when summed.

    0 讨论(0)
  • 2020-12-09 15:27

    I would have expected a positive number, as well, but I found this, from ISO/IEC 14882:2003 : Programming languages -- C++, 5.6.4 (found in the Wikipedia article on the modulus operation):

    The binary % operator yields the remainder from the division of the first expression by the second. .... If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined

    0 讨论(0)
提交回复
热议问题