3

Why does the following C code produce negative numbers as output? And how do I prevent this from happening?

    #include <stdio.h>

    int main()
    {
            int i;
            char buf[1024];
            for (i = 0; i < 1024; i++)
                    buf[i] = i%256;

            for (i=0; i<1024; i++) {
                    printf("%d ", buf[i]);
                    if (i%32==31)
                            printf("\n");
            }
    }
templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
leonixyz
  • 1,130
  • 15
  • 28
  • the code needs to use unsigned char. As all the values above 0x7F have the sign bit set. – user3629249 Dec 18 '14 at 03:36
  • [Does either ANSI C or ISO C specify what -5 % 10 should be?](http://stackoverflow.com/q/3609572/995714), [Modulo operation with negative numbers](http://stackoverflow.com/q/11720656/995714), [Why is the behavior of the modulo operator (%) different between C and Ruby for negative integers?](http://stackoverflow.com/q/24074869/995714) – phuclv May 13 '17 at 13:11
  • Possible duplicate of [Modulo operation with negative numbers](http://stackoverflow.com/questions/11720656/modulo-operation-with-negative-numbers) – phuclv May 13 '17 at 13:14

1 Answers1

7

Let's look at this line of code:

buf[i] = i%256;

Here, i % 256 is computed as a value of type int. However, buf is an array of chars, so when the value is assigned into the array, it's truncated to a char. If the result of the modulus is outside of the range of positive values that can be stored in a char, it may end up wrapping around and being stored as a negative number instead.

In other words, it's not that the modulus produced a negative value as much as you stored the result in a type that can't hold it. Try changing the array to an int array or unsigned char array and see if that fixes things.

Hope this helps!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • This is NOT what is happening. Rather the results of the modulo operation are ranging from 0 through 255 (0x00 through 0xFF) and all the results above 0x7F are considered negative (char sign bit is '1') the fix is to use unsigned char – user3629249 Dec 18 '14 at 03:39
  • @user3629249 What you're describing is what I'm intending to say here. Can you point out what about my answer isn't correct so that I can update it to more clearly communicate what's going on? – templatetypedef Dec 18 '14 at 07:36
  • 1
    @user3629249 - What you wrote is exactly very close to what templatedypedef wrote in this answer. In fact, what templatedypedef wrote is in fact more correct than what you wrote because the answer says "it **may** end up wrapping around". Whether a plain `char` is signed or unsigned is explicitly marked in the standard (sections 6.2.5 and 6.3.1.1) as an implementation-defined behavior. – David Hammen Dec 18 '14 at 22:25