I am having a problem with a program I wrote. The program is going into a if statement whereas it should not. I have two variables:
size_t len = 5;
int tmp = -1;
When I do :
if (tmp > len)
ft_putstr("this is crazy");
I prints out "this is crazy whereas -1 is smaller than 5 to me ! Ok, ok. So I looked on my favorite website and saw this.
When trying:
printf("%zu", tmp)
I see a big positive number. Ok ! This might be the reason why my program goes into the if condition above, but how can I make it not to go inside the if condition ??? thanks
To compare two negative integers, the negative integer with the smaller number is greater.
The C standard doesn't mandate any particular way of representing negative signed numbers. In most implementations that you are likely to encounter, negative signed integers are stored in what is called two's complement. The other major way of storing negative signed numbers is called one's complement.
C and C++ are unusual amongst languages nowadays in making a distinction between signed and unsigned integers. An int is signed by default, meaning it can represent both positive and negative values.
When negative comparison shows up, there is usually a lack of acceptance, appreciation, and love for ourselves. Instead of feeling bad about what we think is wrong with us or critical of ourselves for being judgmental, what if we took this as a cue to take care of and nurture ourselves in an authentic way?
The problem here is that you are trying to compare something that is unsigned with something that is signed. This means that there's an implicit conversion involved before the actual conversion is done. In this case the signed is converted to unsigned (which is normally not what one would want - therefore many compilers have options to display warning when this is done).
To do it more correct in a sloppy way you would write:
if( (int)tmp > (int)len )
however this ignores the fact that size_t
could have values that are too large for int
. To be strict one would have to handle that the range of int
combined with the range of size_t
could be larger than any available type. This means that you would have to handle this in two cases, so you would use the fact that if tmp<0
then tmp<len
(mathematically, since len>=0
). So for example mathematically tmp<len
would be written as tmp<0 || tmp<len
. And the opposite would be tmp>=0 && tmp >= len
. You should therefore write:
if( tmp >= 0 && tmp > len )
Note that then the conversion is not a problem, tmp
could after the first check be converted to unsigned without change of value, different ranges of int
and size_t
are not a problem either as the smaller is converted to wider range before comparison.
The only problem left is that if you have enabled warnings about signed-unsigned comparison (to detect these kind of mistakes) it would still warn. To take care of that you would need to explicitely type cast it, but we know that conversion to unsigned doesn't change tmp
once we checked that tmp>=0
. So to avoid warnings you would write:
if( tmp >= 0 && (unsigned)tmp > len) )
the (unsigned)
is because tmp
is an int
, you need to respect the type when converting to unsigned if tmp
were of another type.
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