Allow signed integer overflows in C / C ++

I want signed integers to be full when they get too big. How to achieve this without using the next largest data type (or when I'm already at int128_t)?

For example, using 8-bit integers, 19 * 12 is usually 260, but I want to get the result 1 11 10 01 00 with the 9th bit disabled, so -27.

+6
c ++ c integer-overflow
Nov 21 '10 at 22:24
source share
7 answers

The signed overflow is undefined in C and that is valid .

Next solution:

 signed_result = (unsigned int)one_argument + (unsigned int)other_argument; 

The above solution implies implementation-defined behavior in the final conversion from unsigned to int , but does not cause undefined behavior. With most compilation platform implementation options, the result is exactly the result you expect.

Finally, an optimizing compiler for one of the many platforms on which implementation-specific options force the compiler to give you the behavior you expect to compile the above code to an obvious build instruction.

Alternatively, if you use gcc, the -fwrapv / -fno-strict-overflow options may be exactly what you want. They provide an additional guarantee regarding the standard that signs the overflow. I am not sure of the difference between the two.

+6
Nov 21 '10 at 22:48
source share

Signed integer overflow undefined according to C and C ++ standards. It is not possible to accomplish what you want without considering a particular platform.

+3
Nov 21 '10 at 22:26
source share

You can create an object wrapper around int, but this will require quite a lot of utility code.

0
Nov 21 '10 at 22:30
source share

It looks like you want to do uncured integer arithmetic, and then write the result into a signed integer:

 unsigned char a = 19; unsigned char b = 12; signed char c = (signed char)(a*b); 

should give you what you are looking for. Let us know if this is not the case.

0
Nov 21 '10 at
source share

Assuming that today there are two arithmetic values ​​with a complement with a sign (which is a reasonable assumption), for addition and subtraction, it is simply assigned without an sign for calculation. For multiplication and division, make sure that the operands are positive, cast without sign, calculate and correct the signs.

0
Nov 21 2018-10-21T00-11-21
source share

This can be done with the correct C standard if you have access to the unsigned type, which is the same width as your signed type (i.e. it has one more bit of value), to demonstrate with int64_t :

 int64_t mult_wrap_2scomp(int64_t a, int64_t b) { uint64_t result = (uint64_t)a * (uint64_t)b; if (result > INT64_MAX) return (int64_t)(result - INT64_MAX - 1) - INT64_MAX - 1; else return (int64_t)result; } 

This does not create problematic intermediate results.

0
Nov 22 '10 at 1:30
source share

Use larger data types. With GMP , you will have all the necessary space.

-one
Nov 21 '10 at 22:41
source share



All Articles