После принятия ответа (4 года)
Я бы ожидал, что функция int average_int(int a, int b)
будет:
1. Работайте по всему диапазону [INT_MIN..INT_MAX]
для комбинаций a
и b
.
2. Получите тот же результат, что и (a+b)/2
, как при использовании более широкой математики.
Когда существует int2x , подход @ Сантьяго Алессандри работает хорошо.
int avgSS(int a, int b) {
return (int) ( ((int2x) a + b) / 2);
}
В противном случае вариант @ AProgrammer :
int avgC(int a, int b) {
if ((a < 0) == (b < 0)) { // a,b same sign
return a/2 + b/2 + (a%2 + b%2)/2;
}
return (a+b)/2;
}
A решение с большим количеством тестов, но без %
Все приведенные ниже решения «работали» с точностью до 1 из (a+b)/2
, когда переполнения не произошло, но я надеялся найти решение, которое соответствует (a+b)/2
для всех int
.
@ Сантьяго Алессандри Решение работает до тех пор, пока диапазон int
уже, чем диапазон long long
- который обычно равен * .
((long long)a + (long long)b) / 2
@ AProgrammer , принятый ответ, не соответствует примерно 1/4 времени совпадения (a+b)/2
. Пример ввода, например a == 1, b == -2
a/2 + b/2 + (a%2 + b%2)/2
@ Guy Sirton , Решение не удается примерно в 1/8 времени, чтобы соответствовать (a+b)/2
. Пример ввода, например a == 1, b == 0
int sgeq = ((a<0)==(b<0));
int avg = ((!sgeq)*(a+b)+sgeq*(b-a))/2 + sgeq*a;
@ R .. , Решение не удается примерно в 1/4 времени от совпадения (a+b)/2
. Пример ввода, например a == 1, b == 1
return (a-(a|b)+b)/2+(a|b)/2;
@ MatthewD , теперь удаленному решению не удается примерно 5/6 времени совпадения с (a+b)/2
. Пример ввода, например a == 1, b == -2
unsigned diff;
signed mean;
if (a > b) {
diff = a - b;
mean = b + (diff >> 1);
} else {
diff = b - a;
mean = a + (diff >> 1);
}