# How to take the average of two uint256s without overflowing?

Say you have two uint256 numbers, `x`, and `y`. One way to calculate the arithmetic average between them is this:

``````function avg(uint256 x, uint256 y) external returns (uint256 result) {
result = (x + y) / 2;
}
``````

But this doesn't work when the intermediate result `x + y` does not fit into uint256.

A seemingly better approach is the following:

``````function avg(uint256 x, uint256 y) external returns (uint256 result) {
result = x / 2 + y / 2;
}
``````

This doesn't overflow, but it doesn't work when both `x` and `y` are odd numbers - the 0.5 remainder is lost twice. Actually, if you'd prefer to round up the result, this doesn't work if either of `x` or `y` is an odd number.

How to take the average of two uint256 numbers in Solidity without overflowing?

• When `x <= y` the average can be calculated as `x + (y - x) / 2`. – Ismael Mar 29 at 16:24

## 1 Answer

After posting the question, I realised I gave the answer myself.

I simply have to check if both `x` and `y` are odd numbers and, if yes, add 1 to the result:

``````function avg(uint256 x, uint256 y) external returns (uint256 result) {
result = x / 2 + y / 2;
if (x % 2 == 1 && y % 2 == 1) {
result += 1;
}
}
``````

Update: I ended up optimising the function, since I found it rather expensive at ~210 gas. I wrapped the code in an `unchecked` block, used the bitwise operator AND instead of the MOD operation and finally applied De Morgan's law:

``````function avg(uint256 x, uint256 y) external view returns (uint256 result) {
unchecked {
result = (x >> 1) + (y >> 1);
if (!(x & 1 == 0 || y & 1 == 0)) {
result += 1;
}
}
}
``````

Which reduced the cost to ~82 gas.

2nd Update: I managed to save even more gas by getting rid of the if block:

``````function avg(uint256 x, uint256 y) external view returns (uint256 result) {
unchecked {
result = (x >> 1) + (y >> 1) + (x & y & 1);
}
}
``````

Which reduced the gas cost to ~60.