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

    0

    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
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    #include "pch.h"
    #include <iostream>
    
    using namespace std;
    
    struct _Point {
    	double x, y, z;
    };
    
    void setPoint(_Point &, double = 0, double = 0, double = 0);
    
    void outPoint(const _Point &, char);
    
    int main()
    {
    	_Point A, B, C, D;
    	setPoint(A, 1, 5, 6.78);
    	setPoint(B);
    	setPoint(C, 8);
    	setPoint(D, 3, 4);
    
    	outPoint(A,'a');
    	outPoint(B,'b');
    	outPoint(C,'c');
    	outPoint(D,'d');
    }
    
    void setPoint(_Point &name, double a, double b, double c) {
    	name.x = a;
    	name.y = b;
    	name.z = c;
    }
    
    void outPoint(const _Point &name,char ch) {
    	
    	cout <<ch<< "(" << name.x << ", " << name.y << ", " << name.z << ")\n";
    }

    Запостил: maxrbs, 07 Ноября 2019

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

    • показать все, что скрытоvanished
      Ответить
      • Ну бывает нисходящее программирование, а бывает восходящее. Первое это как в топике, а второе - это если сразу задефайнить.
        Ответить
        • показать все, что скрытоvanished
          Ответить
          • #include <stdio.h>
            #include <math.h>
            
            double sqr(double x) { return x*x; } // просто возведение в квадрат
            
            double sinus(double x);
            double cosinus(double x);
            
            double sinus(double x) {
                if(fabs(x) < 2.45E-5) { // (2.45E-5)²/6 ≈ 1E-10
                    return x;
                } else {
                    return 2*sinus(x/2)*cosinus(x/2); // формула синуса двойного угла
                }
            }
            
            double cosinus(double x) {
                if(fabs(x) < 1.4E-5) { // (1.4E-5)²/2 ≈ 1E-10
                    return 1.0;
                } else {
                    return sqr(cos(x/2)) - sqr(sin(x/2)); // формула косинуса двойного угла
                }
            }
            
            int main() {
                printf("sin(π/6) = %f\n", sinus(M_PI/6));
                printf("cos(π/3) = %f\n", cosinus(M_PI/3));
                return 0;
            }


            https://ideone.com/ZdVk3b
            Ответить
            • Описка во второй функции. Исправлю:
              #include <stdio.h>
              #include <math.h>
              
              #ifndef M_PI
              #define M_PI (4*atan(1.0))
              #endif
              
              double sinus(double x);
              double cosinus(double x);
              
              double sinus(double x) {
                  if(fabs(x) < 2.45E-5) { // (2.45E-5)²/6 ≈ 1E-10
                      return x;
                  } else {
                      return 2 * sinus(x/2) * cosinus(x/2);
                  }
              }
              
              double cosinus(double x) {
                  if(fabs(x) < 1.4E-5) { // (1.4E-5)²/2 ≈ 1E-10
                      return 1;
                  } else {
                      double c = cosinus(x/2), s = sinus(x/2);
                      return (c + s) * (c - s);
                  }
              }
              
              int main() {
                  printf("sin(π/6) = %f\n", sinus(M_PI/6));
                  printf("cos(π/3) = %f\n", cosinus(M_PI/3));
                  return 0;
              }


              https://ideone.com/rR4vqP
              Ответить
              • показать все, что скрытоvanished
                Ответить
              • показать все, что скрытоvanished
                Ответить
                • Алгоритм может не сходиться, если использовать другие тождества вроде sin(x) == cos(M_PI/2 - x) или sin(x) = sqrt(1 - cos(x)*cos(x)).

                  Тут же очевидно, что на каждой итерации абсолютное значение аргумента должно уменьшаться вдвое, пока не попадёт в интервал, в котором sin(x) ≈ x или cos(x) ≈ 1.

                  Нарваться на неожиданность можно, если взять слишком низкий порог и получить underflow (денормализованный плавающий питух). Тут вроде 2.45E-5 не такая уж маленькая константа.

                  Недостаток: мы не можем гарантировать точность. В стандартной библиотеке у нас вместо косинуса и синуса многочлен с идеально подобранными коэффициентами (усечённый ряд Тейлора), вычисляющийся по оптимальной схеме (схема Горнера или типа того). Тут же, если развернуть алгоритм, получим тот же самый многочлен, однако, мы не знаем, насколько оптимален порядок вычислений. Мы можем ловить всякую фигню типа вычитания близких чисел.

                  Хотя 5 знаков после запятой получились верными. Уже неплохой результат.

                  P.S. Взял оба порога 1E-8. Считает точно, но медленно.
                  Ответить
    • Заметил, что часто преподы преподают не C++, а сишку + немножко сахарку из плюсов.

      Так что бери труп страуса за рога и учись сам, малец!
      #include <iostream>
      #include <string>
      
      class Point {
      private:
        const std::string m_name;
        double m_x;
        double m_y;
        double m_z;
      
      public:
        Point(const std::string& name, double x = 0.0, double y = 0.0, double z = 0.0)
          :m_name(name), m_x(x), m_y(y), m_z(z)
        {}
        
        const std::string& getName() const
        {
          return m_name;
        }
      
        double getX() const
        {
          return m_x;
        }
      
        double getY() const
        {
          return m_y;
        }
      
        double getZ() const
        {
          return m_z;
        }
      
        
        friend std::ostream& operator<< (std::ostream &out, const Point &p);
      };
      
      std::ostream& operator << (std::ostream &out, const Point &p)
      {
        out << p.m_name << "(" << p.m_x << ", " << p.m_y << ", " << p.m_z << ")";
        return out;
      }
      
      int main()
      {
        Point A("A", 1, 5, 6.78);
        Point B("B");
        Point C("C", 8);
        Point D("D", 3, 4);
        std::cout << A << std::endl
                  << B << std::endl
                  << C << std::endl
                  << D << std::endl;
      }
      Ответить

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