Negative Power 2

I study the characteristics of different data types. For example, this program is printing more and more power 2 with four different formats: integer, unsigned integer, hexadecimal, octal

 #include<stdio.h> int main(int argc, char *argv[]){ int i, val = 1; for (i = 1; i < 35; ++i) { printf("%15d%15u%15x%15o\n", val, val, val, val); val *= 2; } return 0; } 

It works. unsigned rises to 2147483648 . integer increases to -2147483648 . But why is this getting negative?

I have a theory: is it because the maximum signed integer we can represent on a 32-bit machine is 2147483647 ? If so, why does it return a negative number?

+5
source share
3 answers

First of all, you should understand that this program is undefined. It causes a continuous overflow of integers, and it is declared undefined in the C standard.

The technical reason is that no behavior can be predicted since different representations are allowed for negative numbers, and there may even be padding bits in the representation.

The most likely reason you see a negative number in your case is because your machine uses 2 lookups to represent negative numbers, while arithmetic works on bits without checking for overflow. Therefore, the most significant bit is a sign bit, and if your value overflows into this bit, it becomes negative.

+5
source

What you are describing is UB caused by integer overflow. Since the behavior is undefined, everything can happen ("When the compiler encounters [this undefined construct], it is legal for it to make demons fly out of your nose"), BUT what actually happens on some machines (I suspect you included):

You start with int val = 1; . This appears to be 0b00...1 in binary form. Every time you val *= 2; , the value is multiplied by 2, so the view changes to 0b00...10 , and then to 0b00...100 , etc. (Bit 1 moves one step each time). Last time you val *= 2; you get 0b100... Now, using 2 add-ons (this is what I think your machine uses, as it is very common), this is actually -1 * 0b1000... , which is -2147483648

Please note that although this may be what really happens on your machine, it should not be trusted or perceived as the β€œright” thing, as, as mentioned earlier, this is UB

+2
source

In this program, the val value will overflow if it is a 32-bit machine, since the integer size is 4 bytes. Now we have 2 types of values ​​in mathematics, positive and negative, so for calculations with negative results we use the signed representations ie int or char in C.

Let's look at a char example, range -128 to 127, unsigned char range 0-255. He reports that the range is divided into two parts for a signed view. Thus, for any signed variable, if it crosses its range of values ​​+ ve, it goes into a negative value. As here, in the case of char , when the value exceeds 127, it becomes -ve. And suppose that if you add 300 to any char or unsigned char variable, what happens, it will flip over and start again from scratch.

 char a=2; a+=300; 

what value? now you know that the maximum char value is 255 (a total of 256 values, including zero), so 300-256 = 44 + 2 = 46.
Hope this helps

-1
source

Source: https://habr.com/ru/post/1269324/


All Articles