Electronic – Detecting overflow with C18

cc18picsoftware

I'm implementing a calculator in a microcontroller which is controlled over the serial port. For example, I'd send 1234*5678= and it would reply with 7006652\r\n. I've written the code for this using the C18 compiler.

When I send 123456*789123=, I get the reply 2932688576, which is incorrect. The correct answer would have been 97421969088, but that overflows an unsigned long.

I do not want to increase the overflow limit, but would like to have a way to check if there has been an overflow. In ASM, that would be possible by checking the relevant bit in the STATUS register, however, with C, this bit would be cleared before I could read it, wouldn't it?

The best would be a general solution to see if an overflow has occured.

Best Answer

There may be tricks regarding the STATUS register but the following generic (untested) code is something I thought of to check the number of bits required to represent each input by doing repeated right bit shift operations until the value is empty.

Then by adding the two results together you should be able to work out if the output will overflow 32 bits.

unsigned long a = 123456;
unsigned long b = 789123;

int calc_bit_size(unsigned long v)
{
    int bit_count = 0;
    while (v > 0)
    {
        bit_count++;
        v >>= 1;
    }
    return bit_count;
}

if (calc_bit_size(a) + calc_bit_size(b) > 32)
   printf("Overflow!")
else
   printf("%lu", a * b);