// Copyright (C) 2026 Kiyotsugu Arai // SPDX-License-Identifier: LGPL-3.0-or-later // RationalTraits.hpp // Rational型のトレイト特殊化 #ifndef CALX_RATIONAL_TRAITS_HPP #define CALX_RATIONAL_TRAITS_HPP #include namespace calx { // 前方宣言 struct real_tag; template struct numeric_traits; template struct numeric_state_traits; // Rational型のnumeric_traits特殊化 template<> struct numeric_traits { using value_type = Rational; using category = real_tag; static constexpr bool is_supported = true; static constexpr bool is_complex = false; static constexpr bool is_integer = false; static constexpr bool is_floating_point = false; static Rational zero() { return Rational(); } static Rational one() { return Rational(1); } static Rational epsilon() { return Rational(); } // 有理数は稠密: 最小単位なし → 0 static Rational abs(const Rational& value) { return calx::abs(value); } /// ピボット選択: 高さ (max(|分子|, |分母|)) が小さい方が良いピボット /// 係数膨張を抑制する static bool pivotBetter(const Rational& a, const Rational& b) { return height(a) < height(b); } static Rational conj(const Rational& value) { return value; // 実数は共役が自分自身 } static Rational norm(const Rational& value) { return abs(value); } static bool isNaN(const Rational& value) { return value.isNaN(); } static bool isInfinite(const Rational& /*value*/) { return false; // Rational は無限大を持たない } static bool isFinite(const Rational& value) { return !value.isNaN(); } static int getSign(const Rational& value) { if (value.isNaN()) return 0; if (value.isZero()) return 0; return value.isNegative() ? -1 : 1; } }; // Rational型のnumeric_state_traits特殊化 template<> struct numeric_state_traits { static bool isNormal(const Rational& value) { return !value.isNaN() && !value.isZero(); } static bool isNaN(const Rational& value) { return value.isNaN(); } static bool isInfinite(const Rational& /*value*/) { return false; } static bool isDivergent(const Rational& /*value*/) { return false; } static bool isOverflow(const Rational& /*value*/) { return false; } static NumericState getState(const Rational& value) { if (value.isNaN()) return NumericState::NaN; return NumericState::Normal; } static NumericError getError(const Rational& value) { if (value.isNaN()) return NumericError::ExplicitNaN; return NumericError::None; } static int getSign(const Rational& value) { if (value.isNaN()) return 0; if (value.isZero()) return 0; return value.isNegative() ? -1 : 1; } }; } // namespace calx #endif // CALX_RATIONAL_TRAITS_HPP