Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I safely average two unsigned ints in C++?

Using integer math alone, I'd like to "safely" average two unsigned ints in C++.

What I mean by "safely" is avoiding overflows (and anything else that can be thought of).

For instance, averaging 200 and 5000 is easy:

unsigned int a = 200; unsigned int b = 5000; unsigned int average = (a + b) / 2; // Equals: 2600 as intended 

But in the case of 4294967295 and 5000 then:

unsigned int a = 4294967295; unsigned int b = 5000; unsigned int average = (a + b) / 2; // Equals: 2499 instead of 2147486147 

The best I've come up with is:

unsigned int a = 4294967295; unsigned int b = 5000; unsigned int average = (a / 2) + (b / 2); // Equals: 2147486147 as expected 

Are there better ways?

like image 300
Tim Avatar asked Sep 28 '10 19:09

Tim


People also ask

Is it good practice for unsigned int?

Unsigned is good programming practice to indicate the intention, to yourself and others, of use of the data element - just in the same way all types are used. For example, a normal array index variable should never be negative and so declaring the variable unsigned should be best practice.

How do you find the average of two integers?

Divide the sum of the integers by the number of integers. In our example, the sum of the integers is 24, and there are five integers total, so this is the formula: 24 / 5 = 4.8. For the set of integers 4, 5, 7, 2 and 6, the average is 4.8.

How are unsigned integers stored in C?

Variables such as integers can be represent in two ways, i.e., signed and unsigned. Signed numbers use sign flag or can be distinguish between negative values and positive values. Whereas unsigned numbers stored only positive numbers but not negative numbers.

Can we compare signed and unsigned int in C?

One of the several ways in which 2's complement is convenient, is that C (un)signed conversions don't change the bit pattern. That's particular to 2's complement: the C conversions to unsigned types are defined in terms of modulo arithmetic, not in terms of bit pattern.


2 Answers

Your last approach seems promising. You can improve on that by manually considering the lowest bits of a and b:

unsigned int average = (a / 2) + (b / 2) + (a & b & 1); 

This gives the correct results in case both a and b are odd.

like image 173
sellibitze Avatar answered Oct 13 '22 20:10

sellibitze


If you know ahead of time which one is higher, a very efficient way is possible. Otherwise you're better off using one of the other strategies, instead of conditionally swapping to use this.

unsigned int average = low + ((high - low) / 2); 

Here's a related article: http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html

like image 34
Sheldon L. Cooper Avatar answered Oct 13 '22 22:10

Sheldon L. Cooper