During the undergraduate studying process, students are familiar with the representation of integers and fractional numbers inside the machine. As a result, this chapter may be kind of basic. However, some interesting facts do exists, which I never think about before.

For instance, we all know that when computing with `int`

and `float`

data, all the data will be cast to float to make sure the loss of data being deduced. To get a result of 0.4, use

1 2 3 |
int a = 2; int b = 5; double f = (a + 0.0) / b |

to make the cast.

Actually, this also happens when computing with `int`

and `unsigned`

, but I didn’t notice that since the two datatype have the same amount of information, and casting from one to the other wouldn’t noticeable when doing arithmetic.

However, things happen when doing relational operations, like “<” and “>”. All is casted to `unsigned`

, so the `-1 < 0`

is true, while `-1 <(unsigned) 0`

becomes false.

Automatic casting also happens for constant. According to C99,

An integer constant begins with a digit, but has no period or exponent part. It may have a prefix that specifies its base and a suffix that specifies its type.

which means a negative number is not constant. When you enter -2147483648, the constant is 2147483648 and then it is negated. For a 32-bit machine, it is overflowed for int, which is the same as long. According to C99, the complier will try int->long->long long. So the result will be -2147483648 but the type will be long long, which is unexpected. That’s the reason why we got in `limits.h`

like this:

1 2 3 |
/* Minimum and maximum values a ‘signed int’ can hold. */ #define INT_MAX 2147483647 #define INT_MIN (-INT_MAX - 1) |

TBC