I recently learned that integer overflow is an undefined behavior in C (side question - is it also UB in C++?)
Often in C programming you need to find the average of two
This is from Calculating the average of two integer numbers rounded towards zero in a single instruction cycle:
(a >> 1) + (b >> 1) + (a & b & 0x1)
You must consider that:
it's implementation defined whether right shifting a negative integer shifts zeros or ones into the high order bits. Many CPUs often have two different instructions: an arithmetic shift right (preserves the sign bit) and a logical shift right (doesn't preserve the sign bit). The compiler is allowed to choose either (most compilers choose an arithmetic shift instruction).
ISO/IEC 9899:2011 §6.5.7 Bitwise shift operators
¶5 The result of E1 >> E2is E1 right-shifted E2 bit positions. [CUT] If E1 has a signed type and a negative value, the resulting value is implementation-defined.
Changing the expression to:
a / 2 + b / 2 + (a & b & 0x1)
isn't a solution since logical right shifts are equivalent to division by a power of 2 only for positive or unsigned numbers.
also (a & b & 0x1)
isn't well defined. This term should be non-zero when both a
and b
are odd. But it fails with one's complement representation and ISO C, section 6.2.6.2/2, states that an implementation can choose one of three different representations for integral data types:
(usually the two's complement far outweigh the others).