Skip to content
Snippets Groups Projects
Select Git revision
  • bb32aeedd6c9d1d3441776c74c4ac330870408c2
  • jupyterhub-share-base-production default protected
  • maintenance-files protected
  • jupyterhub-share-base-dev1
  • 21-frontend-user-workshop-website-collection
  • jupyterhub-share-base-staging
  • jupyterhub-share-base-dev2
  • jupyterhub-login-frontend
  • tmp
  • tmp2
  • tmp3
  • jupyterhub-dev2-enum
  • 4-runtime-limitation-if-reservation-is-selected
  • 4-runtime-limitation-if-reservation-is-selected-2
  • archived-jupyterhub-files-production
  • archived-jupyterhub-jupyterjsc-production
  • archived-maintenance-files-production
  • archived-maintenance-files-staging
  • archive/master
  • archive/css_rework
20 results

dropdown-options.js

Blame
  • complex_number_class.cc 4.93 KiB
    #include <iostream>
    
    class complex_number
    {
    public:
        // If the constructor is meant to do nothing, let the compiler generate it
        constexpr complex_number() noexcept = default;
        // Same for the destructor
        ~complex_number() noexcept = default;
        // Constructor with real and imaginary parts
        constexpr complex_number(double re, double im) noexcept;
        // Constructor with only a real part. It "delegates" its work to the 
        // constructor above. See its implementation below
        constexpr complex_number(double re) noexcept;
        // Copy constructor with trivial member wise copy
        constexpr complex_number(const complex_number &c) noexcept = default;
        // Trivial assignment operator
        constexpr auto operator=(const complex_number& c) noexcept -> complex_number& = default;
        // Move constructor with trivial member wise move
        constexpr complex_number(complex_number &&c) noexcept = default;
        // Move assignment operator
        constexpr auto operator=(complex_number&& c) noexcept -> complex_number& = default;
        // Arithmetic operators changing the calling object
        constexpr auto operator+=(const complex_number&) noexcept -> complex_number&;
        constexpr auto operator-=(const complex_number&) noexcept -> complex_number&;
        constexpr auto operator*=(const complex_number&) noexcept -> complex_number&;
        // Accessor functions
        constexpr auto real() const noexcept -> double { return m_real; }
        constexpr auto imag() const noexcept -> double { return m_imag; }
        constexpr auto modulus() const noexcept -> double { return m_real * m_real + m_imag * m_imag; }
        // Non-member function which accesses private data
        // This is needed to write things like
        // double d; complex_number c; 
        // complex_number e = d*c;
        // Because the operator is called with the LHS as the refering object
        friend constexpr auto operator*(double x, const complex_number&) noexcept -> complex_number;
        // Teach ostream how to output your class
        friend auto operator<<(std::ostream& os, const complex_number& c) -> std::ostream&;
    
    private: 
        // Data variables. Private. Initialised.
        double m_real=0,m_imag=0;
    };
    // Note syntax for initialisation. You can assign to m_real and m_imag in the
    // function body, but the initialiser syntax is more compact.
    constexpr complex_number::complex_number(double re, double im) noexcept : m_real{re},m_imag{im} {}
    // This is a constructor which gets its work done by calling another constructor.
    // This is allowed since C++11.
    constexpr complex_number::complex_number(double re) noexcept : complex_number{re,0} {}
    // Note the compact notation for the return statement. The "type" of the
    // return value is, of course, known from the function signature. So, 
    // the compiler knows that it has to construct a complex_number from
    // whatever that comes after the keyword "return". Since we have 
    // only a set of braces with two arguments, it looks for a constructor
    // with two double arguments, and uses that.
    // The following functions are not member functions. They don't need to be.
    constexpr auto operator+(const complex_number& b, const complex_number& c) noexcept -> complex_number
    {
        return {b.real()+c.real(),b.imag()+c.imag()};
    }
    constexpr auto operator-(const complex_number& b, const complex_number& c) noexcept -> complex_number
    {
        return {b.real()-c.real(),b.imag()-c.imag()};
    }
    constexpr auto operator*(const complex_number& b, const complex_number& c) noexcept -> complex_number
    {
        return {b.real()*c.real()-b.imag()*c.imag(), b.real()*c.imag() + b.imag()*c.real()};
    }
    // Modifying operators do not construct a new object and return it, but
    // instead directly change the data in the calling object. Look how
    // the function returns the calling object through the "this" pointer!
    // This is needed to write nested statements like z=z1*(z2+=z1);
    constexpr auto complex_number::operator+=(const complex_number& c) noexcept -> complex_number&
    {
        m_real+=c.m_real;
        m_imag+=c.m_imag;
        return *this;
    }
    constexpr auto complex_number::operator-=(const complex_number& c) noexcept -> complex_number&
    {
        m_real-=c.m_real;
        m_imag-=c.m_imag;
        return *this;
    }
    constexpr auto complex_number::operator*=(const complex_number& c) noexcept -> complex_number&
    {
        // Temporary store for new real value
        double tmprl=m_real*c.m_real-m_imag*c.m_imag;
        // Calculate new imaginary value using old real and imaginary parts
        m_imag=m_real*c.m_imag+m_imag*c.m_real;
        m_real=tmprl;
        return *this;
    }
    constexpr auto operator*(double x, const complex_number& c) noexcept -> complex_number
    {
        return {x*c.m_real,x*c.m_imag};
    }
    auto operator<<(std::ostream& os, const complex_number& c) -> std::ostream&
    {
        os << c.m_real;
        if (c.m_imag>0) os << '+';
        os << c.m_imag << 'i';
        return os;
    }
    
    auto main() -> int
    {
        static_assert(complex_number { 0.1, -2.3 }.modulus() > 0, "");
        complex_number z0{0.3,0.84}, z;
        for (int i=0; i<10; ++i) {
            z = z*z + z0;
            std::cout << z << "\n";
        }
    }