Вычисление среднего числа трех long long в си
Учитывая long long x, long long y и long long z, как можно вычислить ((x + y + z) / 3) с использованием полностью определенных операций в C, но исключая unsigned long long и более широкую арифметику?
Также я ограничен внесением изменений только внутри функции, которая должна найти среднее значение трех чисел.
Примечание: я уже пробовал искать решение, а также пробовал что-то вроде
#include <stdio.h>
long long average (long long a, long long b, long long c)
{
long long n=0;
n= a / 3 + b / 3 + c / 3 + (a % 3 + b % 3 + c % 3) / 3;
return n;
}
Ответы (4 шт):
может так попробовать?
const long long x1 = a >> 32;
const long long x2 = a & 0xFFFFFFFF;
const long long y1 = b >> 32;
const long long y2 = b & 0xFFFFFFFF;
const long long z1 = c >> 32;
const long long z2 = c & 0xFFFFFFFF;
res = (((x1 + y1 + z1) / 3) << 32) + (x2 + y2 + z2) / 3;
long long average (long long a, long long b, long long c)
{
int digits[100];
memset(digits, 0, sizeof(int) * 100);
// сложить 3 числа
int pos = 0;
int flag = 0;
while (a != 0 || b != 0 || c != 0) {
const int d1 = a % 10;
a /= 10;
const int d2 = b % 10;
b /= 10;
const int d3 = c % 10;
c /= 10;
const int res = d1 + d2 + d3 + flag;
flag = res / 10;
digits[pos++] = res % 10;
}
digits[pos++] = flag;
// разделить на 3
int digits_res[100];
int pos_res = 0;
int sum = 0;
for (int index = pos - 1; index >= 0; index--) {
const int digit = digits[index];
sum = sum * 10 + digit;
digits_res[pos_res++] = sum / 3;
sum = sum % 3;
}
// собрать в число
long long res = 0;
for (int index = 0; index < pos_res; index++)
res = res * 10 + digits_res[index];
return res;
}
Не воспроизводится.
Код:
#include <stdio.h>
#include <assert.h>
long long average (long long a, long long b, long long c)
{
long long n=0;
n= a / 3 + b / 3 + c / 3 + (a % 3 + b % 3 + c % 3) / 3;
return n;
}
int main(void)
{
long long a=9223372036854775800;
long long b=4611686018427387897;
long long c=3;
printf("%lld\n", average(a, b, c));
printf("%lld\n", 4611686018427387900);
assert (average ( 9223372036854775800, 4611686018427387897, 3 ) == 4611686018427387900 );
}
4611686018427387900
4611686018427387900
Ваш код не учитывает работу с отрицательными числами.
Пусть квадратные скобки [...] обозначают операцию отбрасывания дробной части вещественного числа, a, b, c — целые вещественные числа, тогда:
Введём обозначения:
Тогда получим:
Заметим, что x, y — целые числа, а модуль значения y/3 принадлежит полуинтервалу [0, 1). В зависимости от знаков значений x и y итоговый результат будет следующим:
x == 0 || y == 0 => result == x,
x > 0 && y > 0 => result == x,
x > 0 && y < 0 => result == x-1,
x < 0 && y > 0 => result == x+1,
x < 0 && y < 0 => result == x.
Таким образом, функция нахождения среднего значения будет выглядеть как-то так:
long long average(long long a, long long b, long long c)
{
long long rem_sum = a % 3 + b % 3 + c % 3;
long long x = a / 3 + b / 3 + c / 3 + rem_sum / 3;
long long y = rem_sum % 3;
int coef1 = -(x > 0 && y < 0);
int coef2 = +(x < 0 && y > 0);
return x + coef1 + coef2;
}
Ну, и несколько проверок:
#include <stdio.h>
long long average(long long a, long long b, long long c){...}
int main(void)
{
long long min = -9223372036854775807 - 1;
long long max = 9223372036854775807;
printf("%d", average(min, min, min) == min );
printf("%d", average(max, max, max) == max );
printf("%d", average(min, min+1, min+2) == min+1 );
printf("%d", average(max, max-1, max-2) == max-1 );
printf("%d", average(max, 1, 2) == max/3 + 1 );
printf("%d", average(max, -1, -2) == max/3 - 1 );
printf("%d", average(min, 1, 2) == -(max/3 - 1) );
printf("%d", average(min, -1, -2) == -(max/3 + 1) );
printf("%d", average(0, 0, 0) == 0 );
printf("%d", average(2, 2, 2) == 2 );
printf("\n");
printf("%d", average(9223372036854775800, 4611686018427387897, 3) == 4611686018427387900);
printf("%d", average(9223372036854775800, -6, -2) == 3074457345618258597);
printf("\n");
long long counter = 0;
long long first = -32;
long long last = 32;
for (long long a = first; a <= last; ++a)
for (long long b = first; b <= last; ++b)
for (long long c = first; c <= last; ++c)
{
long long res = (a + b + c) / 3;
if (average(a, b, c) != res)
++counter;
}
printf("Errors: %lld\n", counter);
}
1111111111
11
Errors: 0


