3

+すべての一般的な算術関数 ( 、-*、および)/を備えた次の有理数 C++ クラスを作成しました。==!=

template <class T>
struct rationalNumber
{
    static_assert(!std::numeric_limits<T>::is_signed, "ERROR: Type T must be unsigned");
    static_assert(std::is_integral<T>::value, "ERROR: Type T must be integral");

    T numerator;
    T denominator;
    bool sign;

    rationalNumber(const int n = 0) : numerator(std::abs(n)), denominator(1), sign(std::signbit(n)) {}
    rationalNumber(const T n, const T d, const bool s = false) : numerator(n), denominator(d), sign(s) {}
    rationalNumber(const rationalNumber&) = default;
    rationalNumber& operator=(const rationalNumber&) = default;

    rationalNumber operator-() const
    {
        return rationalNumber(numerator, denominator, !sign);
    }

    void reduce()
    {
        T divisor = gcd(numerator, denominator);
        if (divisor != 1)
        {
            numerator /= divisor;
            denominator /= divisor;
        }
        else if (numerator == 0)
        {
            denominator = 1;
            sign = false;
        }

        assert(denominator != 0);
    }
};

using RN = rationalNumber<unsigned long long>;

浮動小数点演算を使用して残りの関係演算子 ( <><=>=) を実装することは実行可能ですか、それともエラーが発生しやすい結果につながるでしょうか?

クロス乗算は多くの場合整数オーバーフローにつながる可能性があるため、浮動小数点のみを考慮したことに注意してください。

4

1 に答える 1

3

はい、浮動小数点演算を使用して不等式のテストを実装することは可能です。そして、そうです、浮動小数点の精度が有限であるため、「エラーが発生しやすい結果」になる可能性があります。

実際には、浮動小数点を使用する必要はまったくありません。数学的には、"a/b > c/d" のテスト (a、b、c、d が正であると仮定) は、テスト "a d > b c" と同等です。符号なし変数では、モジュロ演算の影響を考慮する (または回避する) 必要があります (これは演習として残します) が、浮動小数点をまったく使用せずにテストを正確に実装することは非常に現実的です。

于 2015-02-16T09:08:35.267 に答える