multi_integer_as_integer.hpp

Back to Fixed-size integers

pastel/sys/integer/multi_integer/

#ifndef PASTELSYS_MULTI_INTEGER_AS_INTEGER_HPP
#define PASTELSYS_MULTI_INTEGER_AS_INTEGER_HPP

#include "pastel/sys/integer/multi_integer/multi_integer.h"

namespace Pastel
{

    // Fixed integer

    //! Returns the number of bits in 'that'.
    /*!
   Time complexity: O(1)
   Exception safety: nothrow
   */
    template <typename Integer_Settings>
    integer bits(const MultiInteger<Integer_Settings>& that)
    {
        return Integer_Settings::N;
    }

    // Integer

    template <typename Integer_Settings>
    void swap(
        MultiInteger<Integer_Settings>& left,
        MultiInteger<Integer_Settings>& right)
    {
        left.swap(right);
    }

    //! Returns whether 'that' is odd.
    /*!
   Time complexity: O(1)
   Exception safety: nothrow
   */
    template <typename Integer_Settings>
    bool odd(const MultiInteger<Integer_Settings>& that)
    {
        return that.bit(0);
    }

    //! Returns whether 'that' is even.
    /*!
   Time complexity: O(1)
   Exception safety: nothrow
   */
    template <typename Integer_Settings>
    bool even(const MultiInteger<Integer_Settings>& that)
    {
        return !odd(that);
    }

    // Ordered additive monoid

    //! Returns the absolute value of 'that'.
    /*!
   Time complexity: O(N)
   Exception safety: nothrow
   */
    template <typename Integer_Settings>
    MultiInteger<Integer_Settings> abs(
        const MultiInteger<Integer_Settings>& that)
    {
        return (!Integer_Settings::Signed || positive(that)) ? that : -that;
    }

    //! Returns whether 'that' is negative.
    /*!
   Time complexity: O(1)
   Exception safety: nothrow
   */
    template <typename Integer_Settings>
    bool negative(const MultiInteger<Integer_Settings>& that)
    {
        // Since the integer is in two's complement
        // form, we may look at the last word.
        return Integer_Settings::Signed &&
            twosComplementNegative(that.word(that.words() - 1));
    }

    //! Returns whether 'that' is positive.
    /*!
   Time complexity: O(N)
   Exception safety: nothrow
   */
    template <typename Integer_Settings>
    bool positive(const MultiInteger<Integer_Settings>& that)
    {
        return !negative(that) && !zero(that);
    }

    // Additive monoid

    //! Returns whether 'that' is zero.
    /*!
   Time complexity: O(N)
   Exception safety: nothrow
   */
    template <typename Integer_Settings>
    bool zero(const MultiInteger<Integer_Settings>& that)
    {
        using Word = typename Integer_Settings::Word;
        return std::all_of(
            that.cwordBegin(), that.cwordEnd(),
            [](const Word& word) {return word == 0;});
    }

    template <typename Integer_Settings>
    ScientificNotation asScientific(
        const MultiInteger<Integer_Settings>& that)
    {
        return {0, 0, 0};
    }

    // Multiplicative monoid

    template <typename Integer_Settings>
    bool one(const MultiInteger<Integer_Settings>& that)
    {
        return that == 1;
    }

    template <typename Integer_Settings>
    MultiInteger<Integer_Settings> pow(
        MultiInteger<Integer_Settings> that,
        integer p)
    {
        PENSURE_OP(p, >=, 0);
        return monoidPower(std::move(that), p);
    }

    // Printable

    template <typename Integer_Settings>
    std::string asString(
        const MultiInteger<Integer_Settings>& that)
    {
        return that.asString();
    }

}

#endif