+ 1
Why does char store 127 and 129 as the same?
Why is the binary value for the two numbers the same? Using unsigned char solves the issue, but I specifically want to know why 129 is converted into 127's binary form. Thanks. https://sololearn.com/compiler-playground/c7nuk5W1JCfh/?ref=app
7 Answers
+ 4
Calvin Jude this has to do with the way that this C compiler handles signed char type and promotion from signed char to signed int. When it passes the char argument into the int parameter, it converts the signed char into a signed int. So the value inside the function gets represented as int -127 and the sign bit gets moved from bit 7 up to bit 31.
If you adjust either the declaration of char a to be unsigned char a, or the function declaration to take unsigned int, then you will see accurate results.
+ 6
The range for signed char is -128 to 127
128 and 129 in your code both overflows so they be clamped to negative 128 and 127 respectively.
so literally, it just
puts(get_bin(-128));. for __128
puts(get_bin(-127));. for __129
+ 1
Calvin Jude there is more detail to fully explain it. Two more behaviors are entailed.
1) Beware that using num % 2 on a negative number in C evaluates to 0 or -1. The remainder matches the sign of the operand, num. Not a problem here, just beware.
2) Whether you divide by 2 or use bitwise >>, shifting bits of negative numbers in C does not work very well. This is among my chief complaints about C.
Dividing a negative value by 2 (num /= 2) can change the original bits because integer division in C truncates (e.g., -63.5 => -63). Note that bit0 keeps getting set to 1, and it fills in 1 bits from the left:
-127 = 10000001
-127/2 = -63 = 11000001
-63/2 = -31 = 11100001
-31/2 = -15: = 11110001
...
-1/2 = 0: 11111111 / 2 = 00000000
If you try bitwise shift (num >>= 1), it preserves the low bit but the sign bit stays and propagates downward.
-127 = 10000001
-127>>1 = -64 = 11000000
-64>>1 = -32 = 11100000
-32>>1 = -16 = 11110000
...
-2>>1 = -1 = 11111111
-1>>1 = -1 = 11111111
Unsigned fixes all this.
0
Brian, hereâs how I understand it (feedback on the accuracy would be much appreciated):
In signed types, the leftmost bit acts as an indicator for the sign. If that bit is 1, the value is interpreted as negative, be it a char, short, int or a long. For unsigned types, that same bit is used to represent larger positive values.
In my case, I provided specific input that set the leftmost bit to 1. Since the value was stored as a signed char, it was treated as a negative number, changing the given int data's meaning. This negative value was then converted into its corresponding negative integer, which caused the unexpected output.
0
RuntimeTerror, oh right! I think I need to add an additional check for negative numbers in my function, and once the current function completes, call another function to find the twoâs complement. That'd prove the accuracy of get_bin
0
Ok
0
Brian Here are my thoughts, structured into bullets:
1. I see something like -5 % 2 as the 'x' in 2 * (-2) + x = -5, i.e, the remainder
2. It's weird seeing how the sign bit is unaffected by bitwise shift. C *does* treat signed and unsigned quite differently. So I'll keep that in mind when dealing with negative numbers in c (be it ints or floats)