Кресты / Говнокод #11485 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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 vortexx1, (Updated )

Комментарии (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 то же самое?
    Ответить
    • потому что использование библиотечной 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), но точность приемлема только в некоторой окрестности. Кто какие методы ещё знает?
    Ответить

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

Из-за тебя ушел bormand, guest!

    А не использовать ли нам bbcode?


    8