Тема: Подскажите по С++

Ответить в теме
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 20 из 28
  1. Вверх #1
    Посетитель Аватар для Badboyskiller
    Пол
    Мужской
    Адрес
    Одесса
    Сообщений
    159
    Репутация
    13

    Red face Подскажите по С++

    Привет!Вопрос глупый,но я че-т не могу додуматься!Вобщем,у меня есть некоторое количество value элементов p.Как посчитать среднее арифметическое? Просто загвоздка в том,что кол-во элементов может меняться....И вот как посчитать среднее....Заранее премного благодарен!


  2. Вверх #2
    Не покидает форум Аватар для -=TigeR=-
    Пол
    Мужской
    Адрес
    Одесса
    Сообщений
    7,008
    Репутация
    1410
    ну так пересчитайте их количество...
    затем сложите их и разделите на количество...
    все...

  3. Вверх #3
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    а при чем тут С++?

  4. Вверх #4
    Посетитель Аватар для Badboyskiller
    Пол
    Мужской
    Адрес
    Одесса
    Сообщений
    159
    Репутация
    13
    В том-то и дело,что их количество - это переменная...И этот процесс надо написать на С++.

  5. Вверх #5
    Посетитель Аватар для крыс
    Пол
    Женский
    Сообщений
    369
    Репутация
    54
    массивами пользоваться не пробовали?
    а язык тут ни причем

  6. Вверх #6
    Посетитель
    Пол
    Мужской
    Сообщений
    466
    Репутация
    68
    Если задача задана (тафтология) в контексте изучения списков как алгоритмической структуры и способа динамического выделения памяти (переменное, неизвестное заранее к-во эл-тов), тогда надо делать список, чобы доказать... что способен

  7. Вверх #7
    Посетитель Аватар для IronChancellor
    Пол
    Мужской
    Адрес
    Odessa
    Возраст
    34
    Сообщений
    153
    Репутация
    33
    Считаем сколько памяти занимает программа, отбрасываем количество памяти, занятое всякими левыми переменными, оставшееся делим на размер одной переменной - получаем кол-во переменных =). Списки, списки..

    А вообще, если значения воодятся с клавиатуры или читаются из файла, то можно и пересчитать их во время ввода.
    I'm grey and lonely in my grey and lonely world.

  8. Вверх #8
    Частый гость Аватар для homo ludens
    Пол
    Мужской
    Сообщений
    751
    Репутация
    141
    omg!!
    Код:
    double mean(double* data,size_t sz)
    {
        double res=0;
        if(sz)
        {
           size_t i=sz;
           while(i--)
              res+=*data++;
           res/=sz; 
        }
        return res;
    }
    Блин, в коде меньше строк, чем в обсуждении.
    The future is already here - it is just unevenly distributed. (c) W. Gibson

  9. Вверх #9
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    мои два евроцента
    я бы первый параметр сделал бы const...

  10. Вверх #10
    Частый гость Аватар для homo ludens
    Пол
    Мужской
    Сообщений
    751
    Репутация
    141
    Цитата Сообщение от Ull9 Посмотреть сообщение
    мои два евроцента
    я бы первый параметр сделал бы const...
    Согласен. Блин, консты постоянно забываю, потом приходится вставлять по тексту.

    Кстати в моем коде есть еще одна интересная ошибка, которая теоретически может привести к некорректным вычислениям (при большом количестве данных). Массив надо сортировать перед суммированием и складывать начиная с меньших значений, иначе могут потеряться малые элементы. Естественно тогда уже либо без const, либо с копированием в промежуточный массив.

    Ситуация редко случающаяся, но предусмотреть надо было (если код не учебный).
    The future is already here - it is just unevenly distributed. (c) W. Gibson

  11. Вверх #11
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    отлично, а я до этого не додумался.

  12. Вверх #12
    Посетитель
    Пол
    Мужской
    Сообщений
    466
    Репутация
    68
    Цитата Сообщение от homo ludens Посмотреть сообщение
    omg!!
    Код:
    double mean(double* data,size_t sz)
    {
        double res=0;
        if(sz)
        {
           size_t i=sz;
           while(i--)
              res+=*data++;
           res/=sz; 
        }
        return res;
    }
    Блин, в коде меньше строк, чем в обсуждении.
    От у сишников манера каракули писать. res+=*data++ Чисто повыпендриваться друг перед другом в знании великого и могучего
    Автору темы от вашего примера пользы, думаю, никакой не будет, так как помня что собой представляют задачки по программированию тут бы ввод переменного количества элементов с клавиатуры показать бы надо.
    С чего вы решили, что человек, которому нужна помощь в подсчете среднего арифметического, уже знает, что в ваш double* data надо передавать массив, где сохранены элементы
    Лишь бы выпендреж тут устроить. Шли бы на профессиональные форумы и там устраивали

  13. Вверх #13
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    е мое,
    да что тут профессионального? банальшина.

    хотя...

  14. Вверх #14
    Посетитель
    Пол
    Мужской
    Сообщений
    466
    Репутация
    68
    И потери точности там, на мой взгляд не произойдет. Для того и 80-разрядный внутренний тип

  15. Вверх #15
    Постоялец форума Аватар для Newton
    Пол
    Мужской
    Адрес
    Calgary, Alberta
    Сообщений
    1,105
    Репутация
    825
    Цитата Сообщение от homo ludens Посмотреть сообщение
    (при большом количестве данных). Массив надо сортировать перед суммированием и складывать начиная с меньших значений, иначе могут потеряться малые элементы.
    т.е. может быть
    Код:
    double t = 1.0e+18 + 0.01 + 2;
    double t1 = 0.01 + 2 + 1.0e+18;
    
    ASSERT( fabs(t1 - t) <= 1.0e-15 );
    И будет срабатывать ASSERT?

    Просто, не понятно, как перестановка элементов может повлиять на ошибки округления?
    Моя хата з найкращого краю в світі.

  16. Вверх #16
    Частый гость Аватар для homo ludens
    Пол
    Мужской
    Сообщений
    751
    Репутация
    141
    Цитата Сообщение от Linn Посмотреть сообщение
    Лишь бы выпендреж тут устроить. Шли бы на профессиональные форумы и там устраивали
    Блин, ну если res+=*data++ - признак профессионализма и выпендрежа, то у меня просто слов нет...

    Цитата Сообщение от Newton Посмотреть сообщение
    т.е. может быть
    Просто, не понятно, как перестановка элементов может повлиять на ошибки округления?
    1.0+1e-20 будет равен 1.
    1.0+1e-20+1e-20+1e-20+1e-20+... будет равен 1 независимо от количества слагаемых.
    1e-20+1e-20+1e-20+1e-20+...+1 даст более точный результат.

    Цитата Сообщение от Linn Посмотреть сообщение
    И потери точности там, на мой взгляд не произойдет. Для того и 80-разрядный внутренний тип
    пример кода (извините мой французский + Керниган-Ричи)
    Код:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    
    double mean1(const double* data,size_t sz)
    {
        double res=0;
        if(sz)
        {
           size_t i=sz;
           while(i--)
              res+=*data++;
           res/=sz; 
        }
        return res;
    }
    
    static int dcomp(const void* d1,const void* d2)
    {
      double a = *(const double*)d1;
      double b = *(const double*)d2;
      return (a>b)-(a<b);
    }
    
    double mean2(double* data,size_t sz)
    {
        qsort(data,sz,sizeof(*data),dcomp);
        return mean1(data,sz);
    }
    
    double x[1000];
    
    #define XMAX	(sizeof(x)/sizeof(*x))
    int main(void)
    {
        x[0]=1;      
    
        for(size_t i=1;i<XMAX;i++)
          x[i]=1e-16;
        double r1=mean1(x,XMAX);
        double r2=mean2(x,XMAX);
        printf("nososrt:\t%a\nsort:\t%a\ndiff:\t%g\n",r1,r2,fabs(r1-r2));
        return 0;
    }
    результат предсказуем:

    nososrt: 0x1.0624dd2f1a9fcp-10
    sort: 0x1.0624dd2f1abc9p-10
    diff: 9.99634e-17

    ошибка есть причем всего на 1000 элементов.
    The future is already here - it is just unevenly distributed. (c) W. Gibson

  17. Вверх #17
    Постоялец форума Аватар для Newton
    Пол
    Мужской
    Адрес
    Calgary, Alberta
    Сообщений
    1,105
    Репутация
    825
    Спасибо, идея понятна.
    Т.е. если мы имеем очень много маленьких чисел, которые невозможно представить в десятичной записи с помощью 15-ти значащих знаков после запятой (т.е. все числа меньшие 1.0e-15), то прибавляя такие числа к 1.0, мы будем получать результат, который в принципе не представим типом double и эти числа будут обрезаться до 1.0. Но если мы сначала просуммируем маленькие числа, то при достаточном их количестве, сумма уже будет представима числом с 15-тью значащих знаков после запятой, и сложив с единицей, мы получим число отличное от 1.0.
    Да... тут нужно быть очень осторожным...
    Моя хата з найкращого краю в світі.

  18. Вверх #18
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    это известная фишка, тот кто работает с мат моделированием должен такие вешхи всегда помнить

  19. Вверх #19
    Цитата Сообщение от homo ludens Посмотреть сообщение
    omg!!
    Код:
    double mean(double* data,size_t sz)
    {
        double res=0;
        if(sz)
        {
           size_t i=sz;
           while(i--)
              res+=*data++;
           res/=sz; 
        }
        return res;
    }
    Блин, в коде меньше строк, чем в обсуждении.
    if(sz) - супер!
    Но я вредный!
    и сделаю sz = -1;
    Ловите результаты господа!

  20. Вверх #20
    Постоялец форума Аватар для Newton
    Пол
    Мужской
    Адрес
    Calgary, Alberta
    Сообщений
    1,105
    Репутация
    825
    так а что будет? sz - unsigned, значит битовое представление -1 будет интерпретироваться как битовое представление положительного числа. И в функции невозможно никак проверить, является ли переданное значение sz ошибкой (-1), или это действительно такое количество элементов...
    Хотя в данном случае, наверное можно было бы учесть размер double и проверить, чтоб

    Код:
     sz <= static_cast<unsigned>(-1) / sizeof(double)
    но это, мне кажется, уже проверка на дурачка. Да и компилятор предупредит, что происходит преобразование из signed в unsigned.
    Последний раз редактировалось Newton; 15.01.2008 в 23:46.
    Моя хата з найкращого краю в світі.


Ответить в теме
Страница 1 из 2 1 2 ПоследняяПоследняя

Социальные закладки

Социальные закладки

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения