0

I'm working with signed 16 bit wide variables. When adding, subtracting etc, can i detect the carry and overflow the following way:

I store the result in a 32bit wide variable, and then check the 17th bit (bits from 0-16 represent the value, and if there's carry or overflow the 17h bit should be 1 - overflow)? If it's one then it's an overflow/carry, if it's zero - it isn't. Can carry happen without overflow, or vice versa, when working with 16b values?

I searched StackOverflow, but i was unable to find a clear answer to my question.

idjuradj
  • 1,355
  • 6
  • 19
  • 31
  • "Carry" is a concept from unsigned arithmetic, "overflow" is a concept from signed arithmetic: http://stackoverflow.com/questions/6265896/arithmetic-overflow-vs-arithmetic-carry. – Oliver Charlesworth Aug 17 '14 at 13:13
  • Did you even try to convert your method into code? – Zaid Amir Aug 17 '14 at 13:17
  • I have an assignment, which requiries of me to work with signed values, and i need to set both carry and overflow flags :). Can i detect overflow in signed values, by storing the result in a 32b values (and operands are 16b, and then check if the result is greater than 32767 and less than 32768 – idjuradj Aug 17 '14 at 13:18
  • 1
    @Oli Charlesworth Disagree that the duplicate referenced strongly applies here. In this case, the overflow post is about 16-bit integers and C, though `long` supports 32-bit or wider integers. In the dupe, the question is about `int` addition. C does not guarantee the `long`, `long long`, etc. are wider than `int` and so good portable answers then need to do the various tests on `INT_MAX`, etc. Here all one needs to do is `int16_t a,b; long sum = (long) a + b; if (sum > 32767) || (sum < -32768) Ovrflow()`. A complete answer would discus `int32_t vs. long` and `int16_t vs. short`. – chux - Reinstate Monica Aug 17 '14 at 17:32
  • @chux: The mechanisms given in the answers there are largely equivalent to what you're suggesting, though. – Oliver Charlesworth Aug 17 '14 at 18:13

1 Answers1

0

upd: One can use approach, when operands are testing against the limits (declared in the limits.h) when doing the operation. E.g. look at this "safe" addition function:

int safe_add(int x, int y)
{
    if(y < 0)
       return save_sub(x, -y);
    if(x > (INT_MAX - y)) 
    {
        printf("overflow\n");
        return INT_MAX;
    }
    return x + y;
}

int save_sub(int x, int y)
{
    if(y < 0)
        return save_add(x, -y);
    if(x > (INT_MIN + y)) 
    {
        printf("underflow\n");
        return INT_MIN;
    }
    return x - y;
}

Note: these methods have at least one bug: they may fail if invoked on the largest negative integer, INT_MIN.

ars
  • 707
  • 4
  • 14
  • I don't want to test if it's safe. I just want to execute it, and then indicate if overflow happened. – idjuradj Aug 17 '14 at 13:19
  • @Matt McNabb, you're right, i forget to mention this case. Added this to case to code. – ars Aug 17 '14 at 13:24
  • @Nicholas In C, signed integer math, overflow is undefined behavior. That means that should such overflow occur, the rest of the code is pointless. One cannot test _after_ overflow. Code needs to occur such that overflow (at that integer width) never occurs. Going to wider integers or doing tests like this post are the 2 main options. – chux - Reinstate Monica Aug 17 '14 at 17:37