Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/56: Рейтинг темы: голосов - 56, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 30.03.2011
Сообщений: 41
1

Нахождение среднего арифметического без переполнения

20.04.2012, 16:43. Показов 10262. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Задача найти среднее арифметическое целых чисел (int).
Если просто складывать их и потом делить на количество происходит переполнение...
может кто подскажет алгоритм как это осуществить без переполнения а то я никак допереть не могу...
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.04.2012, 16:43
Ответы с готовыми решениями:

Нахождение среднего арифметического без учета максимального элемента
Подскажите где я накосячил, неправильно подсчитывает среднее арифметическое без мах елемента...

Нахождение среднего арифметического
Всем добрый день, я только начал изучать c++, столкнулся с проблемой: нужно вычислить вреднее...

Нахождение среднего арифметического
Здравствуйте! Такая задача:вводится последовательность из n целых чисел (это задание необходимо...

Нахождение среднего арифметического
Здравствуйте, помогите реализовать функцию среднего арифметического. Сама задача: Программа...

19
10 / 10 / 3
Регистрация: 19.04.2012
Сообщений: 20
20.04.2012, 16:44 2
Цитата Сообщение от vampik Посмотреть сообщение
Задача найти среднее арифметическое целых чисел (int).
Если просто складывать их и потом делить на количество происходит переполнение...
может кто подскажет алгоритм как это осуществить без переполнения а то я никак допереть не могу...
Код выложите свой, где не работает.
0
0 / 0 / 0
Регистрация: 30.03.2011
Сообщений: 41
20.04.2012, 16:51  [ТС] 3
Цитата Сообщение от Heretiqu3 Посмотреть сообщение
Код выложите свой, где не работает.
Есть массив из 1000 и более элементов нужно найти среднее...
Проект большой не вижу смысла выкладывать...
но факт в том что после того как я складываю некоторое количество элементов из массивов они выходят за пределы (сумма становится слишком большой)... поэтому результаты получаются неадекватными..
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
20.04.2012, 16:59 4
Складывайте их (значения) в переменную типа double, а то и long double, если всё так серьёзно. Целое число в качестве среднего арифметического - всё равно редкость...
0
0 / 0 / 0
Регистрация: 30.03.2011
Сообщений: 41
20.04.2012, 17:03  [ТС] 5
Цитата Сообщение от easybudda Посмотреть сообщение
Складывайте их (значения) в переменную типа double, а то и long double, если всё так серьёзно. Целое число в качестве среднего арифметического - всё равно редкость...
У меня пока что у массивов такая размерность...
а потом может стать и еще больше...
просто хотелось бы вообще быть независимым от переполнения...может кто-то какой-то алгоритм а то условно будет у меня 10000 элементов с большим значением... и там уже никакие типы не помогут...
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
20.04.2012, 17:23 6
Цитата Сообщение от vampik Посмотреть сообщение
Задача найти среднее арифметическое целых чисел (int).
Если просто складывать их и потом делить на количество происходит переполнение...
может кто подскажет алгоритм как это осуществить без переполнения а то я никак допереть не могу...
А сколько у тебя целых, какого они типа и какого реального диапазона? Если signed showt int складывать через преобразование в signed long int, то переполнение гарантировано не наступит при сложении 65535-ти слагаемых, так как удвоение разрядности расширяет диапазон квадратично, а удвоение диапазона происходит при повышении разрядности всегда на 1 бит. Мало? Эйси. Сложи по частям, каждую из сумм раздели, а потом найди средневзвешенное от этих средних. У тебя уже signed long int? Ну тогда складывай в __int64 (он же hyper), влезет больше 4-х миллиардов слагаемых. Уже hyper? Создай 128-ми битный тип, операторы для его сложения и деления и приведения hyper к нему и работай в этом типе.
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
20.04.2012, 17:27 7
Среднее арифметическое: https://www.cyberforum.ru/cgi-bin/latex.cgi?\frac{{x}_{1} + {x}_{2} + ... + {x}_{n}}{n} = \frac{{x}_{1}}{n} + \frac{{x}_{2}}{n} + ... + \frac{{x}_{n}}{n}
Думаю идея понятна.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
 
int main() {
  const int size = 10;
  int a[ size  ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  
  double b = 0;
  
  for ( int i = 0; i < 10; i++ )
     b += static_cast< double >( a[ i ] ) / size;
     
  std::cout << b << std::endl;
  
  return 0;
}
1
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
20.04.2012, 17:29 8
Цитата Сообщение от Toshkarik Посмотреть сообщение
int a[ size *] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Это даже байт переполнить не может.
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
20.04.2012, 17:30 9
taras atavin, причем здесь это? Мы не складываем все переменные в одну, поэтому переполнения быть не может, так как среднее арифметическое максимум будет равно наибольшему элементу.
0
79 / 79 / 8
Регистрация: 14.10.2009
Сообщений: 121
20.04.2012, 17:32 10
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "windows.h"
#include <stdlib.h>
#include <stdio.h>
 
double Hello(unsigned int *begin, unsigned int *end, int size)
{
    if((begin + 1) == end) //конец массива
        return (double)(*begin + *(begin + 1))/size;
    else if(begin + 2 == end) //конец массива, но в конце целых три эелемента
        return (double)(*begin + *(begin + 1) + *(begin + 2))/size;
    else                     // вычисляем потихоньку
        return (double)(*begin + *(begin + 1))/size + (double)Hello(begin + 2, end, size);
}
 
int main()
{
    unsigned int X[1000];
    unsigned int i;
    double result;
 
    srand(GetTickCount());
    for(i = 0; i < 1000; i++)
    {
        X[i] = rand() % 100;
    }
 
    result = Hello(X, &X[999], 1000);
 
    return 0;
}
вроде работает. Простая задачка.

А вообще если есть возможность, то такую математику лучше на лиспе писать.
Большинство его реализаций поддерживают длинную арифметику.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
20.04.2012, 17:34 11
Цитата Сообщение от Toshkarik Посмотреть сообщение
taras atavin, причем здесь это? Мы не складываем все переменные в одну.
Попытка деления сразу при работе в целом типе может приводить к нулевому результату, если количество усредняемых данных больше самих данных, дробные операции относительно дорогие, особенно деление, а если делить в конце, то он и мантиссу double побоится переполнить, у тебя же простейший случай, где переполнение и так не грозит.
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
20.04.2012, 17:36 12
Цитата Сообщение от taras atavin Посмотреть сообщение
Попытка деления сразу при работе в целом типе может приводить к нулевому результату, если количество усредняемых данных больше самих данных.
Вообще из этого ничего не понял, переформулируйте пожалуйста.
0
347 / 292 / 37
Регистрация: 23.03.2012
Сообщений: 838
20.04.2012, 17:42 13
C++
1
2
3
4
5
6
7
8
9
10
11
12
long double f(int * a, int size)
{
 int s=0;
 int ostatok=0;
 for (int i=0;i<size;i++)
  {
   ostatok+=a[i];
   s+=ostatok/size;
   ostatok=ostatok%size;
  }
 return s+1.0*ostatok/size;
}
0
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
20.04.2012, 18:05 14
C
1
2
3
4
5
6
7
8
9
10
11
12
13
int Mean(int *data, unsigned int size)  /*Среднее арифметическое с округлением вниз*/
{
    int mean = 0, accum = 0, delta;
    unsigned int i = 0;
    for(; i<size; ++i)
    {
        accum += data[i];
        delta = accum / size;
        mean += delta;
        accum -= delta*size;
    }
    return mean;
}
0
11 / 11 / 5
Регистрация: 25.11.2011
Сообщений: 147
20.04.2012, 19:10 15
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <math.h>
void main()
{
int a, b=0,c=0;
double d;
printf("chislo, 0 vihod\t\n");
do
{scanf("%d",&a);
c++;
d=b+a/c;
b+=a;
printf("shag %d result = %f\n", c, d); 
 }
while (a!=);
}
Не знаю может где ошибся, с телефона написал

Добавлено через 14 минут
while (a!=0); и d=(b+a)/c
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
20.04.2012, 19:40 16
Цитата Сообщение от Toshkarik Посмотреть сообщение
Вообще из этого ничего не понял, переформулируйте пожалуйста.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <iosream.h>
#include <math.h>
void main()
{
 int a[20]={1, 2, 4, 5, 7, 5, 8, 4, 3, 2, 9, 5, 4, 6, 2, 7, 4, 5, 1, 3};
 int i, s1,s2;
 for (i=0, s1=0, s2=0; i<20; ++i)
 {
  s1+=a[i]/20;
  s2+=a[i];
 }
 s2/=a20;
 std::cout<<"s1="<<s1<<", s2="<<s2<<endl;
 return 0;
}
выведет:
s1=0, s2=4
.
0
Заблокирован
20.04.2012, 19:57 17
А у меня эта задача ассоциируется вот с таким кодом:
Исходный массив должен быть дополнен нулями так, чтобы общее число элементов в этом новом массиве являлось некоторой степенью двойки.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
double average(int const arr[], size_t arrsize)
{
    int total = 0;
    try
    {
        for (size_t count(0); count < arrsize; ++count)
        {
            total += arr[count];
        }
    }
    catch (overflow_error &e)
    {
        return (average(arr, arrsize >> 2) + average(arr + (arrsize >> 2), arrsize >> 2)) / static_cast<double>(2);
    }
    return static_cast<double>(total) / static_cast<double>(arrsize);
}
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
20.04.2012, 19:59 18
taras atavin, не потому ли у Toshkarik сделано
Цитата Сообщение от Toshkarik Посмотреть сообщение
b += static_cast< double >( a[ i ] ) / size;
? И получается всё, как надо, а так-то любую идею можно забыдлокодить до полной непригодности...
1
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
20.04.2012, 20:00 19
Вы видели вообще мой код? Например что тип переменной double? И что там каст к double? Тем более я просто показал, что можно делить каждую переменную в отдельности для избежания переполнения. Если без каста, то тут уже достаточно привели примеров, использующий данный метод. Единственный пример показался не правильным из последнего поста предыдущей страницы, так как рекурсии нужно избегать при обработке большого количества данных.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
20.04.2012, 20:02 20
Цитата Сообщение от taras atavin Посмотреть сообщение
s2/=a20;
То есть
C++
1
s2/=20;
Добавлено через 1 минуту
Цитата Сообщение от easybudda Посмотреть сообщение
не потому ли у Toshkarik сделано
дробные операции дороже целых равно разрядности.
0
20.04.2012, 20:02
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.04.2012, 20:02
Помогаю со студенческими работами здесь

Нахождение среднего арифметического элементов массива
Необходимо решить задачу: Дан целочисленный массив из N элементов (N≤1000). Элементы...

Реализовать нахождение среднего арифметического элементов массива
Решите пожалуйста задачу на С++ Разработайте программу, в которой реализовано нахождение...

Нахождение среднего арифметического и геометрического двух чисел
Здравствуйте! Написал программу для нахождения среднего арифметического и геометрического двух...

Нахождение среднего арифметического трех целых чисел или суммы двух вещественных
#include &lt;iostream&gt; #include &lt;cmath&gt; int main() { float x,y; int a,b,c; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru