1. Си / Говнокод #9947

    +133

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    #include <stdio.h>
    
    float abs(float a) { return a > 0 ? a : -a; }
    
    int main() {
        float x, e, step = 1, summ = step;
        int i = 0;
        
        scanf("%f, %f", (printf("x, e: "), &x), &e);
        
        do summ += (abs(step *= x / ++i) > e) ? step : 0; while (abs(step) > e);
        
        printf("summ = %f\n", summ);
        
        return 0;
    }

    вычисление суммы ряда (1 + x/1! + x^2/2! + ... + x^n/n!), с заданной точностью

    Запостил: igoreknog, 14 Апреля 2012

    Комментарии (7) RSS

    • Использование типа 'float' для выполнения выичслений - всегда говнокод. Тип 'float' в С/С++ существует только для целей экономии памяти, т.е. имеет право на осмысленное существование только в массовых долгохранимых структурах данных.

      Также стоит заметить, что основаная говнокодовость в данном случае заключается даже не в говностилистике кода, а нарушении классического правила работы с плавающими типами, известного каждому первокласснику: накопительное суммирование в плавающем аккумуляторе всегда следует начинать с минимальных по модулю значений.
      Ответить
      • Судя по всему это лаба, поэтому float даже лучше: сразу видно подводные камни.

        Имхо, тут оценка погрешности шагом - слишком топорно (не работает для x > 0).
        И 2 сравнения в цикле - перебор.

        По поводу "аккумулятора", вы предлагаете отсортировать ряд? Кэп намекает, что a(n+1) / a(n) = x / n+1 => ошибка в малых разрядах не успеет накопиться. К тому же, в данном случае существует оценка для остаточного члена (для удобства можно предварительно frexp). Или использовать отрицальные x, тогда, действительно, можно оценивать погрешность шагом.
        Ответить
        • Я предлагаю не отсортировать последовательность, а просто выполнять суммирование в обратном порядке - от последнего интересующего нас члена к первому. Понятно, что первые члены последовательности 'x^n/n!' в общем случае возрастают по модулю, но в то же время и понятно, что факториал растет быстрее показательной функции, т.е. с определенного момента члены последовательности начинают строго убывать по модулю. Поэтому накопление суммы от конца к началу имеет больше смысла.

          Надо лишь сначала определить последний интересующий нас член, пусть даже "холостым" прогоном как в оригинальном коде...
          Ответить
          • То есть в зависимости от х (он может и в (0;1) лежать): или в прямом или в обратном?
            Интересно, в каких-нибудь библиотеках так считают экспоненту.
            Ответить
            • Не совсем понимаю, почему "в зависимости от x" и причем здесь (0,1). Члены последовательности 'x^n/n!' начинают монотонно убывать начиная с некоторого 'n' независимо от того, где лежит 'x'.
              Ответить
    • scanf("%f, %f", (printf("x, e: "), &x), &e);

      Ого!
      Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий