// Copyright (C) 2026 Kiyotsugu Arai // SPDX-License-Identifier: LGPL-3.0-or-later // IntSpecialStates.cpp // 多倍長整数の特殊状態の処理の実装 #include #include namespace calx { std::string IntSpecialStates::handleToString(const Int& value, int base) { // 通常の値は処理しない if (value.m_state == NumericState::Normal) { return ""; // 空文字列を返し、通常の変換処理を行うことを示す } // 特殊状態の文字列表現 switch (value.m_state) { case NumericState::NaN: return "NaN"; case NumericState::PositiveInfinity: return "Infinity"; case NumericState::NegativeInfinity: return "-Infinity"; case NumericState::PositiveZero: return "0"; case NumericState::NegativeZero: return "-0"; case NumericState::Overflow: return "Overflow"; case NumericState::Underflow: return "Underflow"; case NumericState::Interrupted: return "Interrupted"; case NumericState::PrecisionLimit: return "PrecisionLimit"; case NumericState::NotConverged: return "NotConverged"; case NumericState::Divergent: return "Divergent"; case NumericState::Oscillating: return "Oscillating"; case NumericState::SlowConvergence: return "SlowConvergence"; case NumericState::TruncatedConvergence: return "TruncatedConvergence"; default: // エラー情報を含める if (value.m_error != NumericError::None) { std::stringstream ss; ss << "Error(" << static_cast(value.m_error) << ")"; return ss.str(); } return "UnknownState"; } } Int IntSpecialStates::handleAddition(const Int& lhs, const Int& rhs) { // どちらかがNaNの場合はNaNを返す if (lhs.isNaN() || rhs.isNaN()) { return Int::NaN(); } // 無限大同士の加算 if (lhs.m_state == NumericState::PositiveInfinity) { if (rhs.m_state == NumericState::NegativeInfinity) { // +∞ + (-∞) = NaN Int result = Int::NaN(); result.m_error = NumericError::InfiniteIndeterminate; return result; } // +∞ + x = +∞ (xは有限値または+∞) return Int::PositiveInfinity(); } if (lhs.m_state == NumericState::NegativeInfinity) { if (rhs.m_state == NumericState::PositiveInfinity) { // -∞ + (+∞) = NaN Int result = Int::NaN(); result.m_error = NumericError::InfiniteIndeterminate; return result; } // -∞ + x = -∞ (xは有限値または-∞) return Int::NegativeInfinity(); } if (rhs.m_state == NumericState::PositiveInfinity) { // x + (+∞) = +∞ (xは有限値) return Int::PositiveInfinity(); } if (rhs.m_state == NumericState::NegativeInfinity) { // x + (-∞) = -∞ (xは有限値) return Int::NegativeInfinity(); } // その他の特殊状態 if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // オーバーフローなど Int result = Int::NaN(); result.m_error = NumericError::None; return result; } // ここには到達しないはず(通常の値同士の加算は別途処理される) return Int::NaN(); } Int IntSpecialStates::handleSubtraction(const Int& lhs, const Int& rhs) { // どちらかがNaNの場合はNaNを返す if (lhs.isNaN() || rhs.isNaN()) { return Int::NaN(); } // 無限大同士の減算 if (lhs.m_state == NumericState::PositiveInfinity) { if (rhs.m_state == NumericState::PositiveInfinity) { // +∞ - (+∞) = NaN Int result = Int::NaN(); result.m_error = NumericError::InfiniteIndeterminate; return result; } // +∞ - x = +∞ (xは有限値または-∞) return Int::PositiveInfinity(); } if (lhs.m_state == NumericState::NegativeInfinity) { if (rhs.m_state == NumericState::NegativeInfinity) { // -∞ - (-∞) = NaN Int result = Int::NaN(); result.m_error = NumericError::InfiniteIndeterminate; return result; } // -∞ - x = -∞ (xは有限値または+∞) return Int::NegativeInfinity(); } if (rhs.m_state == NumericState::PositiveInfinity) { // x - (+∞) = -∞ (xは有限値) return Int::NegativeInfinity(); } if (rhs.m_state == NumericState::NegativeInfinity) { // x - (-∞) = +∞ (xは有限値) return Int::PositiveInfinity(); } // その他の特殊状態 if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // オーバーフローなど Int result = Int::NaN(); result.m_error = NumericError::None; return result; } // ここには到達しないはず(通常の値同士の減算は別途処理される) return Int::NaN(); } Int IntSpecialStates::handleMultiplication(const Int& lhs, const Int& rhs) { // どちらかがNaNの場合はNaNを返す if (lhs.isNaN() || rhs.isNaN()) { return Int::NaN(); } // ゼロとの乗算 if (lhs.m_sign == 0 || rhs.m_sign == 0) { // 0 * ∞ = NaN(未定義) if (lhs.isInfinite() || rhs.isInfinite()) { Int result = Int::NaN(); result.m_error = NumericError::ZeroTimesInfinity; return result; } // 0 * x = 0 (xは有限値) return Int::Zero(); } // 無限大との乗算 if (lhs.isInfinite() || rhs.isInfinite()) { // 符号の決定 int resultSign = lhs.m_sign * rhs.m_sign; // 結果の設定 if (resultSign > 0) { return Int::PositiveInfinity(); } else { return Int::NegativeInfinity(); } } // その他の特殊状態 if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // オーバーフローなど Int result = Int::NaN(); result.m_error = NumericError::None; return result; } // ここには到達しないはず(通常の値同士の乗算は別途処理される) return Int::NaN(); } Int IntSpecialStates::handleDivision(const Int& lhs, const Int& rhs) { // どちらかがNaNの場合はNaNを返す if (lhs.isNaN() || rhs.isNaN()) { return Int::NaN(); } // ゼロによる除算 if (rhs.m_sign == 0) { if (lhs.m_sign == 0) { // 0 / 0 = NaN(未定義) Int result = Int::NaN(); result.m_error = NumericError::DivideByZero; return result; } // x / 0 = ±∞ (xの符号に依存) if (lhs.m_sign < 0) { return Int::NegativeInfinity(); } else { return Int::PositiveInfinity(); } } // 無限大の処理 if (lhs.isInfinite()) { if (rhs.isInfinite()) { // ∞ / ∞ = NaN(未定義) Int result = Int::NaN(); result.m_error = NumericError::InfiniteIndeterminate; return result; } // ∞ / x = ±∞ (符号に依存) int resultSign = lhs.m_sign * rhs.m_sign; if (resultSign > 0) { return Int::PositiveInfinity(); } else { return Int::NegativeInfinity(); } } // 有限値を無限大で割る if (rhs.isInfinite()) { // x / ∞ = 0 (xは有限値) return Int::Zero(); } // その他の特殊状態 if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // オーバーフローなど Int result = Int::NaN(); result.m_error = NumericError::None; return result; } // ここには到達しないはず(通常の値同士の除算は別途処理される) return Int::NaN(); } Int IntSpecialStates::handleModulo(const Int& lhs, const Int& rhs) { // どちらかがNaNの場合はNaNを返す if (lhs.isNaN() || rhs.isNaN()) { return Int::NaN(); } // ゼロによる剰余 if (rhs.m_sign == 0) { // x % 0 = NaN(未定義) Int result = Int::NaN(); result.m_error = NumericError::DivideByZero; return result; } // 無限大の処理 if (lhs.isInfinite()) { // ∞ % x = NaN(未定義) Int result = Int::NaN(); result.m_error = NumericError::InfiniteIndeterminate; return result; } // 有限値を無限大で割った剰余 if (rhs.isInfinite()) { // x % ∞ = x (xは有限値) return lhs; } // その他の特殊状態 if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // オーバーフローなど Int result = Int::NaN(); result.m_error = NumericError::None; return result; } // ここには到達しないはず(通常の値同士の剰余は別途処理される) return Int::NaN(); } bool IntSpecialStates::compareLessThan(const Int& lhs, const Int& rhs) { // どちらかがNaNの場合は常にfalse if (lhs.isNaN() || rhs.isNaN()) { return false; } // 無限大の比較 if (lhs.m_state == NumericState::NegativeInfinity) { return rhs.m_state != NumericState::NegativeInfinity; // -∞ < x (x ≠ -∞) } if (rhs.m_state == NumericState::PositiveInfinity) { return lhs.m_state != NumericState::PositiveInfinity; // x < +∞ (x ≠ +∞) } if (lhs.m_state == NumericState::PositiveInfinity) { return false; // +∞ < x は常にfalse } if (rhs.m_state == NumericState::NegativeInfinity) { return false; // x < -∞ は常にfalse } // その他の特殊状態 if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // 特殊状態の順序は定義しない return false; } // ここには到達しないはず(通常の値同士の比較は別途処理される) return false; } bool IntSpecialStates::compareEqual(const Int& lhs, const Int& rhs) { // どちらかがNaNの場合は常にfalse if (lhs.isNaN() || rhs.isNaN()) { return false; } // 両方とも同じ特殊状態の場合は等しい if (lhs.m_state != NumericState::Normal && lhs.m_state == rhs.m_state) { // 無限大の場合は符号も考慮 if (lhs.isInfinite()) { return lhs.m_sign == rhs.m_sign; } return true; } // 異なる特殊状態または特殊状態と通常値は等しくない if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { return false; } // ここには到達しないはず(通常の値同士の比較は別途処理される) return false; } } // namespace calx