1

合計や乗算などのモジュラー演算を行うために、templateクラス (という名前)を実装しようとしています。Modular

int正常に動作しますが、またはint64_tなどのブースト整数型を渡そうとすると、コンパイラはよく理解できないいくつかのエラーを出力します。int128_tmpz_int

クラスコードは次のとおりです。

template <class T, int64_t modulus>
class Modular {
public:
    Modular() : num_(0) { }
    Modular(const T& num = 0) : num_(num % modulus) { }
    Modular(const Modular& other) : num_(other.num_) { }
    ~Modular() { }

    T get() const { return num_; }

    Modular& operator=(const Modular& other) { num_ = other.num_; return *this; }
    bool operator==(const Modular& other) { return num_ == other.num_; }
    bool operator!=(const Modular& other) { return num_ != other.num_; }
    Modular& operator++() { ++num_; num_ %= modulus; return *this; }
    Modular operator++(int) { Modular temp(*this); operator++(); return temp; }
    Modular& operator+=(const Modular& other) { num_ += other.num_; num_ %= modulus; return *this; }
    Modular& operator-=(const Modular& other) { num_ -= other.num_; num_ %= modulus; return *this; }
    Modular& operator*=(const Modular& other) { num_ *= other.num_; num_ %= modulus; return *this; }

    Modular& operator/=(const Modular& other)
    {
        if((num_ % other.num_) == 0)
            num_ /= other.num_;
        else
        {
            Modular temp(0);
            while(temp * other != num_)
                ++temp;
            num_ = temp.num_;
        }

        return *this;
    }

    Modular pow(const T& exp)
    {
        if(exp == 1)
            return *this;

        Modular square(num_ * num_ % modulus);

        if(exp & 1)
            return (*this) * square.pow(exp/2);
        else
            return square.pow(exp/2);
    }

protected:
    T num_;
};

template <class T, T modulus>
inline Modular<T, modulus> operator+(const Modular<T, modulus>& lhs, const Modular<T, modulus>& rhs)
{
    Modular<T, modulus> temp(lhs);
    temp += rhs;
    return temp;
}

template <class T, T modulus>
inline Modular<T, modulus> operator-(const Modular<T, modulus>& lhs, const Modular<T, modulus>& rhs)
{
    Modular<T, modulus> temp(lhs);
    temp -= rhs;
    return temp;
}

template <class T, T modulus>
inline Modular<T, modulus> operator*(const Modular<T, modulus>& lhs, const Modular<T, modulus>& rhs)
{
    Modular<T, modulus> temp(lhs);
    temp *= rhs;
    return temp;
}

template <class T, T modulus>
inline Modular<T, modulus> operator/(const Modular<T, modulus>& lhs, const Modular<T, modulus>& rhs)
{
    Modular<T, modulus> temp(lhs);
    temp /= rhs;
    return temp;
}

ここにありmain()ます:

#include <iostream>
#include <array>
#include <cstdint>
#include <boost/multiprecision/cpp_int.hpp>

using boost::multiprecision::int128_t;

int main()
{
    const int128_t n = 123;
    const int64_t mod = 456;

    typedef Modular<int128_t, mod> mint;

    const mint a = static_cast<int128_t)(789);
    const mint b = static_cast<int128_t)(12);

    mint result(0);

    for(mint x(1); x != mint(101); ++x){
        result += (a * x.pow(n+2) + b * x.pow(n+1) - x) / mint(x*x + x - mint(1));
    }
    std::cout << result.get();

    return 0;
}

そしてコンパイラ出力: http://pastebin.com/1fNgDedt

最初は使用const int128_t modしていましたが、コンパイラはそれをmod定義する必要があると言っていconstexprたので、それに置き換えましたが、理由がわかりませんし、最初のコンパイラのエラーがまったくわかりません。

4

1 に答える 1

3

特定のプラットフォームでは、プラットフォームが 128 ビットの組み込み整数型を提供しないため、boost はint128_tasを定義します。boost::multiprecision::number<>C++ では、整数データ型のみがテンプレート パラメーターとして許可されているためint128_t、 typedef の名前が eg のように見えるint64_tにもかかわらず、をテンプレートの 2 番目のパラメーターとして許可することはできません。

于 2013-09-08T08:49:31.400 に答える