I have two variables (test1
and test2
), both unsigned.
I need to check which of them is bigger.
I'm trying to understand what happens if overflow occurs.
My first test was done with uint8_t (char) data type:
#include <stdio.h>
#include <stdint.h>
#include <math.h>
int main()
{
uint8_t test1 = 0;
printf("test1 = %d\n", test1);
uint8_t test2 = pow(2, 8 * sizeof(test1)) - 1; //max holdable value of uint8_t
printf("test2 = %d\n", test2);
uint8_t test3 = test1 - test2;
printf("test1 - test2 = %d\n", test3);
if ((test1 - test2) == 0)
printf("test1 == test2\n");
if ((test1 - test2) > 0)
printf("test1 > test2\n");
if ((test1 - test2) < 0)
printf("test1 < test2\n");
if (test3 == 0)
printf("test1 == test2\n");
if (test3 > 0)
printf("test1 > test2\n");
if (test3 < 0)
printf("test1 < test2\n");
return 0;
}
output:
test1 = 0
test2 = 255
test1 - test2 = 1
test1 < test2
test1 > test2
What? Making the substraction and save it in a variable, then checking it, is different from checking the substraction on the fly?
My second test was done with uint32_t (long) data type:
#include <stdio.h>
#include <stdint.h>
#include <math.h>
int main()
{
uint32_t test1 = 0;
printf("test1 = %d\n", test1);
uint32_t test2 = pow(2, 8 * sizeof(test1)) - 1; //max holdable value of uint32_t
printf("test2 = %lu\n", test2);
uint32_t test3 = test1 - test2;
printf("test1 - test2 = %d\n", test3);
if ((test1 - test2) == 0)
printf("test1 == test2\n");
if ((test1 - test2) > 0)
printf("test1 > test2\n");
if ((test1 - test2) < 0)
printf("test1 < test2\n");
if (test3 == 0)
printf("test1 == test2\n");
if (test3 > 0)
printf("test1 > test2\n");
if (test3 < 0)
printf("test1 < test2\n");
return 0;
}
output:
test1 = 0
test2 = 4294967295
test1 - test2 = 1
test1 > test2
test1 > test2
What??? Now making the substraction and saving it in a variable, then check it, is the same as checking the substraction on the fly?
SO I was expecting that substraction between unsigned values (without an explicit cast) ALWAYS returns a value >= 0. But doing the substraction inside the IF leads to unexpected results.
Now I'm confused. Can someone explain this behaviour to me?
The somewhat arcane type promotion rules apply. In the first example where the operands are uint8_t
, for the expression:
test1 - test2
both operands are implicitly promoted to int
before subtraction, and the expression itself has type int
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With