1. C++ / Говнокод #11485

    +4

    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
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    #include <iostream>
    using std::cin;
    using std::cout;
    using std::endl;
    
    #include <cmath>
    
    double mySqrt( float, float );
    
    int main() {
        float a, n;
        cin >> a >> n;
        
        cout << mySqrt( a, n ) << endl;
        return 0;    
    }
    
    double mySqrt( float a, float n ) {
        const double EPSILON = 0.00001;
        double precision;
        
        double x = 0, x_prev = 1.0;
        
        do {
            x = (x_prev * (n - 1.0) + a / pow( x_prev, n - 1.0 )) / n;
            precision = fabs( x - x_prev );
            
            x_prev = x;
        } while( precision > EPSILON );
        
        return x;
    }

    Студентота, да.
    Извлечение корней.

    Запостил: vortexx1, 28 Июля 2012

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

    • Где здесь говнокод, vortexx1?
      Самая обычная лаба. Причем многой студентоте до такого качества кода еще учиться и учиться...
      Ответить
      • Ну не говно, но попахивающие моменты есть. Цикл с постусловием, например.
        С другой стороны - капитанство ОП
        > Извлечение корней.
        Так что всё равно минус.
        Ответить
        • А что не так с постусловием, почему нельзя?
          Ответить
          • > А что не так с постусловием, почему нельзя?
            Ну цикл с постусловием обычно плохо читается. Хотя в данном случае он короткий, while стоит на той же строке, что и }, и после него не забыли поставить пустую строку. Так что тут все читается нормально.

            В случаях подобных данному, цикл с постусловием, имхо, вполне уместен, чего не скажешь о заполнении переменных мусором, которое пришлось бы применить ради входа в цикл с предусловием...
            Ответить
      • Можно было бы сообщить mySqrt такую сигнатуру:
        double mySqrt(double, double);

        Можно было бы считать приращение delta = x - x_prev и делать это так:
        ...
        double delta;
        double inv_n = 1.0 / n;
        double one_minus_n = 1.0 - n;
        ...
        do{
            delta = (a * pow(x_prev, one_minus_n) - x_prev) * inv_n;
            x_prev = x;
            x+=delta;
        } while(fabs(delta) < EPSILON);

        Можно было бы проверять, что a>=0.
        Можно было бы сделать mySqrt шабло

        А в остальном: парень, ты все сделал пральна, смело тащи преподу.
        Ответить
    • > a / pow( x_prev, n - 1.0 )

      Попросу студента самого реализовать pow, чтобы работало за O(1), пользоваться стандартной экспонентой и логарифмом нельзя (пусть сам пишет если надо).
      Ответить
    • То есть, вы имете ввиду, что здесь нельзя библиотечную pow использовать и надо написать свою?
      С fabs то же самое?
      Ответить
      • Товарищу TarasB.
        Ответить
      • потому что использование библиотечной pow это нонсенс — можно было бы написать pow(x, 0.5)
        Ответить
        • Ну здесь нонсенс скорее float n нежели pow(x, n-1.0). Т.к. этот метод вычисления корней неэффективен для нецелых n (как раз из-за того, что в любом случае придется использовать pow или его велосипедный аналог, который и без данного метода сам бы справился с вычислением корней).

          А вот если бы n был целым - тогда, возможно, имело бы смысл написать свою функцию pow, возводящую число в целую степень за O(log(n))...
          Ответить
    • Цикл - O(n). Это медленно. Целые степени за O(log(n)) можно считать, выражая их через суммы и разности степени 2ки. Разложение в ряд - О(1), но точность приемлема только в некоторой окрестности. Кто какие методы ещё знает?
      Ответить

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