0

If I google (7 - 12) mod 24 I get the answer 19.

When I do it C++ I get 4294967291

uint32_t hour = (7 - 12) % 24;
// hour = 4294967291

If I try an int32_t

int32_t hour = (7 - 12) % 24;
// hour = -5
  • When you convert [singed to unsigned](https://stackoverflow.com/questions/22801069/using-1-as-a-flag-value-for-unsigned-size-t-types) you add or subtract `UMAX+1` to get a valid unsigned value. For example converting `-1` to unsigned will always give you the max unsigned value for that type. – Shafik Yaghmour Apr 07 '14 at 01:54
  • 1
    In C++, `/` does truncation-towards-zero, so `-5 / 24 == 0`. `%` is defined such that `(a/b)*b + a%b == a`, therefore it must be `-5`. – M.M Apr 07 '14 at 02:00
  • Don't mix signed and unsigned values. –  Apr 07 '14 at 02:45

4 Answers4

4

(7 - 12) % 24 is a signed expression, and assigning it to an unsigned int makes you see a different result

In C % is the remainder operation so (7 - 12) % 24 = -5

unsigned(-5) = 4294967291 // since 4294967291 + 5 = 4294967296

While Google and Python uses the mathematics modulus operation, the result is 19. And 19 + 5 = 24

C,Python - different behaviour of the modulo (%) operation

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • Saying `4294967291 + 5 = 4294967296` does not really explain why, you can see my answer to the question I [linked above](https://stackoverflow.com/questions/22902364/7-12-mod-24-equals-19-but-in-c-it-equals-4294967291#comment34952458_22902364) for the explanation. – Shafik Yaghmour Apr 07 '14 at 02:09
1

7-12 ans an unsigned int (uint32) gives underflow.

See also http://en.wikipedia.org/wiki/Modulo_operation for definition of the operator for negative numbers in respect to the programming language

Soren
  • 14,402
  • 4
  • 41
  • 67
1

uint32_t is unsigned, meaning that it is restricted to positive numbers. It also means it has a larger range, since a signed byte can have values from -127 to 127, but an unsigned byte can have them from 0-255. When the unsigned int underflows, it will return a large number.

The reason that the int32_t is returning -5 instead of 19, is because in C++ and C# the modulus operator is actually remainder.

Also see this blog psot by Eric Lippert that sums this up amazingly. Specifically...

"The % operator does not give the canonical modulus, it gives the remainder. "

Meanwhile, google gives the canonical modulus since -123 mod 4 = 1, not -3, as it would be in C++ or C#.

Community
  • 1
  • 1
Liam McInroy
  • 4,339
  • 5
  • 32
  • 53
  • @RobertHarvey So [remainder != modulus](http://blogs.msdn.com/b/ericlippert/archive/2011/12/05/what-s-the-difference-remainder-vs-modulus.aspx) – Liam McInroy Apr 07 '14 at 02:03
  • Thanks, but I don't see how this addresses the question at all. – Robert Harvey Apr 07 '14 at 02:16
  • @RobertHarvey Check edits... I just didn't want to beat a dead horse with the whole unsigned/signed thing, but the actual operator still needed to be addressed. – Liam McInroy Apr 07 '14 at 02:22
  • So far, nobody's provided a decent answer to the question anyway. I stated simply in my answer that a negative number can't be stuffed into an unsigned int without consequences, but apparently that's not specific enough. The right answer is to use the correct data type. – Robert Harvey Apr 07 '14 at 02:25
  • @RobertHarvey The question(s) being asked are not amazingly clear – Liam McInroy Apr 07 '14 at 02:27
  • That's part of the reason I decided to close it. – Robert Harvey Apr 07 '14 at 02:27
  • @RobertHarvey The only reason I even posted an answer was [this](http://stackoverflow.com/questions/22902364/7-12-mod-24-equals-19-but-in-c-it-equals-4294967291/22902430?noredirect=1#comment34952428_22902375) – Liam McInroy Apr 07 '14 at 02:28
  • Ah, I see. Well, it's better to address the question that was asked in the question in an answer, rather than a question that was asked in a comment, a matter best responded to in another comment, not an answer (since, by responding in an answer, nobody knows what the hell is happening). – Robert Harvey Apr 07 '14 at 02:30
0

The modulus operation actually has several different possible definitions producing various results for negative numbers. C++'s definition gives a negative result (-5) for the expression (7 - 12) % 24, and when you cast a negative value to an unsigned value you get that strange result. That value is the same as what you get if you were to do:

uint32_t x = 0;
x = x - 5;
bames53
  • 86,085
  • 15
  • 179
  • 244