Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/22: Рейтинг темы: голосов - 22, средняя оценка - 5.00
vampik
0 / 0 / 0
Регистрация: 30.03.2011
Сообщений: 41
1

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

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

Задача найти среднее арифметическое целых чисел (int).
Если просто складывать их и потом делить на количество происходит переполнение...
может кто подскажет алгоритм как это осуществить без переполнения а то я никак допереть не могу...

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.04.2012, 16:43
Ответы с готовыми решениями:

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

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

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

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

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

19
Heretiqu3
10 / 10 / 3
Регистрация: 19.04.2012
Сообщений: 20
20.04.2012, 16:44 2
Цитата Сообщение от vampik Посмотреть сообщение
Задача найти среднее арифметическое целых чисел (int).
Если просто складывать их и потом делить на количество происходит переполнение...
может кто подскажет алгоритм как это осуществить без переполнения а то я никак допереть не могу...
Код выложите свой, где не работает.
0
vampik
0 / 0 / 0
Регистрация: 30.03.2011
Сообщений: 41
20.04.2012, 16:51  [ТС] 3
Цитата Сообщение от Heretiqu3 Посмотреть сообщение
Код выложите свой, где не работает.
Есть массив из 1000 и более элементов нужно найти среднее...
Проект большой не вижу смысла выкладывать...
но факт в том что после того как я складываю некоторое количество элементов из массивов они выходят за пределы (сумма становится слишком большой)... поэтому результаты получаются неадекватными..
0
easybudda
Модератор
Эксперт CЭксперт С++
10148 / 6055 / 1522
Регистрация: 25.07.2009
Сообщений: 11,476
20.04.2012, 16:59 4
Складывайте их (значения) в переменную типа double, а то и long double, если всё так серьёзно. Целое число в качестве среднего арифметического - всё равно редкость...
0
vampik
0 / 0 / 0
Регистрация: 30.03.2011
Сообщений: 41
20.04.2012, 17:03  [ТС] 5
Цитата Сообщение от easybudda Посмотреть сообщение
Складывайте их (значения) в переменную типа double, а то и long double, если всё так серьёзно. Целое число в качестве среднего арифметического - всё равно редкость...
У меня пока что у массивов такая размерность...
а потом может стать и еще больше...
просто хотелось бы вообще быть независимым от переполнения...может кто-то какой-то алгоритм а то условно будет у меня 10000 элементов с большим значением... и там уже никакие типы не помогут...
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
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
Toshkarik
1150 / 867 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
20.04.2012, 17:27 7
Среднее арифметическое: http://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
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
20.04.2012, 17:29 8
Цитата Сообщение от Toshkarik Посмотреть сообщение
int a[ size *] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Это даже байт переполнить не может.
0
Toshkarik
1150 / 867 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
20.04.2012, 17:30 9
taras atavin, причем здесь это? Мы не складываем все переменные в одну, поэтому переполнения быть не может, так как среднее арифметическое максимум будет равно наибольшему элементу.
0
ProNoooob
77 / 77 / 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
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
20.04.2012, 17:34 11
Цитата Сообщение от Toshkarik Посмотреть сообщение
taras atavin, причем здесь это? Мы не складываем все переменные в одну.
Попытка деления сразу при работе в целом типе может приводить к нулевому результату, если количество усредняемых данных больше самих данных, дробные операции относительно дорогие, особенно деление, а если делить в конце, то он и мантиссу double побоится переполнить, у тебя же простейший случай, где переполнение и так не грозит.
0
Toshkarik
1150 / 867 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
20.04.2012, 17:36 12
Цитата Сообщение от taras atavin Посмотреть сообщение
Попытка деления сразу при работе в целом типе может приводить к нулевому результату, если количество усредняемых данных больше самих данных.
Вообще из этого ничего не понял, переформулируйте пожалуйста.
0
Nekto
342 / 287 / 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
Nick Alte
Эксперт С++
1648 / 1020 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
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
saserlend
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
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
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
thick_int
Заблокирован
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
easybudda
Модератор
Эксперт CЭксперт С++
10148 / 6055 / 1522
Регистрация: 25.07.2009
Сообщений: 11,476
20.04.2012, 19:59 18
taras atavin, не потому ли у Toshkarik сделано
Цитата Сообщение от Toshkarik Посмотреть сообщение
b += static_cast< double >( a[ i ] ) / size;
? И получается всё, как надо, а так-то любую идею можно забыдлокодить до полной непригодности...
1
Toshkarik
1150 / 867 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
20.04.2012, 20:00 19
Вы видели вообще мой код? Например что тип переменной double? И что там каст к double? Тем более я просто показал, что можно делить каждую переменную в отдельности для избежания переполнения. Если без каста, то тут уже достаточно привели примеров, использующий данный метод. Единственный пример показался не правильным из последнего поста предыдущей страницы, так как рекурсии нужно избегать при обработке большого количества данных.
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
20.04.2012, 20:02 20
Цитата Сообщение от taras atavin Посмотреть сообщение
s2/=a20;
То есть
C++
1
s2/=20;
Добавлено через 1 минуту
Цитата Сообщение от easybudda Посмотреть сообщение
не потому ли у Toshkarik сделано
дробные операции дороже целых равно разрядности.
0
20.04.2012, 20:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.04.2012, 20:02

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru