Search code examples
ccastingintegerunsignedsigned

How to perform signed comparison between unsigned operands?


I have declared 4 unsigned variables:

uint32_t empty_bucket;
uint32_t base_bucket;
uint32_t hop_size;
uint32_t ht_size;

I want to perform a signed conditional check:

if (empty_bucket < base_bucket + (hop_size - 1) - ht_size)

Knowing that base_bucket + (hop_size - 1) - ht_size could be a negative value. What is the right casting for the operands to perform this singed operation?

NB: base_bucket + (hop_size - 1) - ht_size could be something really close to -2^32, so casting to signed 32-bits int32_t could cause an overflow.


Solution

  • Since you're using stdint include, you could convert the operands to 64 bit signed values, and compare that, no risk that any of the terms to the right become negative, and we have to cast the left operand to signed integer to avoid undefined/implementation behaviour when comparing signed/unsigned:

    if ((int64_t)empty_bucket < ((int64_t)base_bucket + ((int64_t)hop_size - 1) - (int64_t)ht_size))
    

    To sum it up:

    • no risk of overflow (I may have cast a little too much on the right side)
    • comparison between signed entities
    • On the downside, 64 bit conversion may have a negative impact on the performance on a 32 bit architecture