I have noticed something weird and I would really appreciate if someone could help me to understand what’s happening on a deeper level.

```
temp1 = 0x3a
temp2 = 0xfb
printf("%x", abs(temp1 - temp2))
```

will print `0x3f`

if temp1, temp2 were of type `int8_t`

.

will print `0xc1`

if temp1, temp2 were of type `int16_t`

.

will print `0xc1`

if temp1, temp2 were of type `uint8_t`

.

now I understand that int16_8 and uint8_t has bigger positive range, but I still don’t understand what’s going on, I tried int8_t and to use casting

`printf("%x", abs((int16_t) (temp1) - (int16_t)(temp2)))`

The program printed `0x3f`

(I expected to get `0xc1`

) which is really confusing

### >Solution :

If `temp1`

and `temp2`

have type `int8_t`

, then `temp1 = 0x3a`

sets `temp1`

to 58 (the value of `0x3a`

), but it is implementation-defined what `temp2 = 0xfb`

sets `temp2`

to, because the value of `0xfb`

(251) is too large for `int8_t`

. Commonly, a C implementation will set it to −5 (which equals 251−256 and which has the same bit encoding in two’s complement as 251 does in unsigned binary).

Then `temp1 - temp2`

is 58 − −5 = 63, for which the absolute value is 63, the value of `0x3f`

.

If `temp1`

and `temp2`

have type `int16_t`

or `uint8_t`

, then `temp1 = 0x3a`

sets `temp1`

to 58, as before, and `temp2 = 0xfb`

sets `temp2`

to 251.

Then `temp1 - temp2`

is 58 − 251 = −193, for which the absolute value is 193, the value of `0xc1`

. Note that, in the evaluation of `temp1 - temp2`

, values of type `int16_t`

or `uint8_t`

are automatically promoted to `int`

, so the arithmetic is done using the `int`

type and produces −193 even if the types of `temp1`

and `temp2`

are `uint8_t`

.