5

Let us have

int a, b, c; // may be char or float, anything actually
c = a + b;

let int type be represented by 4 bytes. Let's say a+b requires 1 bit more than 4 bytes (ie, let's say the result is 1 00....0 (32 zeroes, in binary)). This would result in C=0, and I am sure the computer's microprocessor would set some kind of overflow flag. Is there any built in method to check this in C?

I am actually working on building a number type that is 1024 bits long (for example, int is a built in number type that is 32 bits long). I have attempted this using unsigned char type arrays with 128 elements. I also need to define addition and subtraction operations on these numbers. I have written the code for addition but I am having problem on subtraction. I don't need to worry about getting negative results because the way I will call the subtracting function always ensures that the result of subtraction is always positive, but to implement the subtraction function I need to somehow get the 2's complement of the subtrahend, which is it self my custom 1024 bit number.

I am sorry if it is difficult to understand my description. If needed I will elaborate it more. I am including my code for the adding function and the incomplete subtracting function. the NUM_OF_WORDS is a constant declared as

#define NUM_OF_WORDS 128

Please let me know if you did not understand my question or any part of my code.

PS: I don't see how to upload attachments in this forum so I am directing you to another website. My code may be found there

click on download in this page

Incidentally, I found this I intend to replace INT_MAX by UCHAR_MAX as my 1024 bit numbers consist of array of char types (8-bit variable) Is this check sufficient for all cases?

Update:

Yes I am working on Cryptography.
I need to implement a Montgomery Multiplication routine for 1024 bit size integers.
I had also considered using GMP library but couldn't find out how to use it.
I looked up a tutorial and after a few small modifications I was able to build the GMP project file in VC++ 6 which resulted in a lot of .obj files, but now I am not sure what to do with them.
Still it would be good if I can write my own data types, as it will give me complete control over how the arithmetic operations on my custom data type work, and I also need to be able to extend it from 1024 bits to larger numbers in the future.

7
  • 2
    Unless you are doing this as a programming exercise (and it certainly is a good one), you should consider using a library for working with arbitrary-size integers, such as the GNU Multiple Precision Arithmetic Library. Commented Apr 11, 2011 at 9:46
  • You can give every star in the universe a number with 128-bits. Why would you need a 1024 bits one? Commented Apr 11, 2011 at 9:47
  • @Kevin: I've seen combinatorial problems that gave rise to numbers beyond 10^40 > 2^128. (Specifically, I was doing parsing using an ambiguous grammar that my lecturer remarked was "just a toy grammar".) Commented Apr 11, 2011 at 9:54
  • 1
    @Kevin: Also, cryptography often involves integers of at least that size. Commented Apr 11, 2011 at 9:58
  • @Kevin: there are plenty of problems to which the size of the universe is irrelevant. Most of them, really ;-) Commented Apr 11, 2011 at 10:01

7 Answers 7

6

Contrary to popular belief, an int overflow results in undefined behavior. This means that once a + b overflows, it doesn't make sense to use this value (or do anything else, for that matter). The wrap-around is just what most machines happen to do in case of overflow, but they might as well explode.

To check whether an int overflow will occur when adding two non-negative integers a and b, you can do the following:

if (INT_MAX - b < a) {
        /* int overflow when evaluating a+b */
}

This is due to the fact that if a + b > INT_MAX, then INT_MAX - b < a, but INT_MAX - b can not overflow.

You will have to pay special attention to the case where b is negative, which is left as an exercise for the reader ;)


Regarding your actual goal: 1024-bit numbers suffer from exactly the same overall issues as 32-bit numbers. It might be more promising to choose a completely different approach, e.g. representing numbers as, say, linked lists of digits, using a very large base B. Usually, B is chosen such that B = sqrt(INT_MAX), so multiplication of digits doesn't overflow the machine's int type.

This way, you can represent arbitrarily large numbers, where "arbitrary" means "only limited by the amount of main memory available".

Sign up to request clarification or add additional context in comments.

Comments

4

If you're adding unsigned numbers then you can do this

c = a+b;
if (c<a) {
  // you'll get here if and only if overflow has occurred
}

and you may even find that your compiler is clever enough to implement it by checking the overflow or carry flag instead of doing an extra comparison. For instance, I just fed this to gcc -O3 -S:

unsigned int foo() {
  unsigned int x=g(), y=h();
  unsigned int z = x+y;
  return z<0 ? 0 : z;
}

and got this for the key bit of the code:

movl  $0,   %edx
addl  %ebx, %eax
cmovb %edx, %eax

where you'll notice there's no extra comparison instruction.

4 Comments

This wont work for all cases if b itself is an overflowed int. If int max size is 10, a = 6 and b = 11 then c = 7.
If "int max size = 10" then b can't be 11. Obviously no possible code can tell whether, when you're adding a and b, one of them is the result of an overflow somewhere earlier.
Note that although this works for unsigned integers (as you say), this method cannot be used with signed integers, as in the OP's question.
Unless I misread, the OP is working with unsigned integers and wants to be able to subtract them as well as adding them. A test very similar to the one I described works just fine for subtraction: c = a-b; if (c>a) { ... }.
1

If you are working with unisigned numbers, then if a <= UINT_MAX, b <= UINT_MAX, and a + b >= UINT_MAX, then c = (a + b) % UINT_MAX will always be smaller than a and b. And this is the only case where this can happen.

So you can detect overflow this way.

int add_return_overflow(unsigned int a, unsigned int b, unsigned int* c) {
    *c = a + b;
    return *c < a && *c < b;
}

Comments

1

Information which maybe useful in this subject :

  1. Secure Coding in C and C++
  2. IntSafe library

Comments

0

You can base a solution on a particular feature of the C language. According to the specification, when you add two unsigned ints, "the result value is congruent to the modulo 2^n of the true result" ("C - A reference manual" by Harbison and Steele). This means you can use some simple arithmetic checks to detect overflow:

#include <stdio.h>

int main() {
    unsigned int a, b, c;
    char *overflow;

    a = (unsigned int)-1;
    for (b = 0; b < 3; b++) {
        c = a + b;
        overflow = (a < b) ? "yes" : "no";
        printf("%u + %u = %u, %s overflow\n", a, b, c, overflow);
    }

    return 0;
}

Comments

0

Just xor MSB of both operands and result. Result of this operation is overflow flag.

But that will not show you if result is correct or not. (it might be correct result even whit overflow) for instance 3 + (-1) is 2 whit overflow.

In order to figure that using signed arithmetic you need to check if both operdas were same sign (xor of MSB).

Comments

-1

Once you add 1 to INT_MAX, you end up getting INT_MIN (i.e. overflow).
In C, there's no reliable way to test for overflow, because all 32 bytes are used to represent the integer (and not a state flag). You can only test to see if the number you get will be within a valid range, as in your link.

You'll get answers suggesting that you can test if (c < a), however note that you could overflow the value of a and/or b to the point where their addition forms a number greater than a (but still overflown)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.