// Copyright (C) 2026 Kiyotsugu Arai // SPDX-License-Identifier: LGPL-3.0-or-later // IntSpecialStates.cpp // Implementation of special-state handling for multiprecision integers #include #include namespace sangi { std::string IntSpecialStates::handleToString(const Int& value, int base) { // Do not handle normal values if (value.m_state == NumericState::Normal) { return ""; // Return an empty string to indicate that normal conversion should be performed } // String representation of special states 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: // Include error information 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) { // If either is NaN, return NaN if (lhs.isNaN() || rhs.isNaN()) { return Int::NaN(); } // Addition of infinities 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 is a finite value or +∞) 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 is a finite value or -∞) return Int::NegativeInfinity(); } if (rhs.m_state == NumericState::PositiveInfinity) { // x + (+∞) = +∞ (x is a finite value) return Int::PositiveInfinity(); } if (rhs.m_state == NumericState::NegativeInfinity) { // x + (-∞) = -∞ (x is a finite value) return Int::NegativeInfinity(); } // Other special states if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // Overflow, etc. Int result = Int::NaN(); result.m_error = NumericError::None; return result; } // This should be unreachable (addition of normal values is handled separately) return Int::NaN(); } Int IntSpecialStates::handleSubtraction(const Int& lhs, const Int& rhs) { // If either is NaN, return NaN if (lhs.isNaN() || rhs.isNaN()) { return Int::NaN(); } // Subtraction of infinities 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 is a finite value or -∞) 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 is a finite value or +∞) return Int::NegativeInfinity(); } if (rhs.m_state == NumericState::PositiveInfinity) { // x - (+∞) = -∞ (x is a finite value) return Int::NegativeInfinity(); } if (rhs.m_state == NumericState::NegativeInfinity) { // x - (-∞) = +∞ (x is a finite value) return Int::PositiveInfinity(); } // Other special states if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // Overflow, etc. Int result = Int::NaN(); result.m_error = NumericError::None; return result; } // This should be unreachable (subtraction of normal values is handled separately) return Int::NaN(); } Int IntSpecialStates::handleMultiplication(const Int& lhs, const Int& rhs) { // If either is NaN, return NaN if (lhs.isNaN() || rhs.isNaN()) { return Int::NaN(); } // Multiplication by zero if (lhs.m_sign == 0 || rhs.m_sign == 0) { // 0 * ∞ = NaN (undefined) if (lhs.isInfinite() || rhs.isInfinite()) { Int result = Int::NaN(); result.m_error = NumericError::ZeroTimesInfinity; return result; } // 0 * x = 0 (x is a finite value) return Int::Zero(); } // Multiplication with infinity if (lhs.isInfinite() || rhs.isInfinite()) { // Determine the sign int resultSign = lhs.m_sign * rhs.m_sign; // Set the result if (resultSign > 0) { return Int::PositiveInfinity(); } else { return Int::NegativeInfinity(); } } // Other special states if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // Overflow, etc. Int result = Int::NaN(); result.m_error = NumericError::None; return result; } // This should be unreachable (multiplication of normal values is handled separately) return Int::NaN(); } Int IntSpecialStates::handleDivision(const Int& lhs, const Int& rhs) { // If either is NaN, return NaN if (lhs.isNaN() || rhs.isNaN()) { return Int::NaN(); } // Division by zero if (rhs.m_sign == 0) { if (lhs.m_sign == 0) { // 0 / 0 = NaN (undefined) Int result = Int::NaN(); result.m_error = NumericError::DivideByZero; return result; } // x / 0 = ±∞ (depends on the sign of x) if (lhs.m_sign < 0) { return Int::NegativeInfinity(); } else { return Int::PositiveInfinity(); } } // Handling of infinity if (lhs.isInfinite()) { if (rhs.isInfinite()) { // ∞ / ∞ = NaN (undefined) Int result = Int::NaN(); result.m_error = NumericError::InfiniteIndeterminate; return result; } // ∞ / x = ±∞ (depends on the sign) int resultSign = lhs.m_sign * rhs.m_sign; if (resultSign > 0) { return Int::PositiveInfinity(); } else { return Int::NegativeInfinity(); } } // Dividing a finite value by infinity if (rhs.isInfinite()) { // x / ∞ = 0 (x is a finite value) return Int::Zero(); } // Other special states if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // Overflow, etc. Int result = Int::NaN(); result.m_error = NumericError::None; return result; } // This should be unreachable (division of normal values is handled separately) return Int::NaN(); } Int IntSpecialStates::handleModulo(const Int& lhs, const Int& rhs) { // If either is NaN, return NaN if (lhs.isNaN() || rhs.isNaN()) { return Int::NaN(); } // Modulo by zero if (rhs.m_sign == 0) { // x % 0 = NaN (undefined) Int result = Int::NaN(); result.m_error = NumericError::DivideByZero; return result; } // Handling of infinity if (lhs.isInfinite()) { // ∞ % x = NaN (undefined) Int result = Int::NaN(); result.m_error = NumericError::InfiniteIndeterminate; return result; } // Modulo of a finite value divided by infinity if (rhs.isInfinite()) { // x % ∞ = x (x is a finite value) return lhs; } // Other special states if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // Overflow, etc. Int result = Int::NaN(); result.m_error = NumericError::None; return result; } // This should be unreachable (modulo of normal values is handled separately) return Int::NaN(); } bool IntSpecialStates::compareLessThan(const Int& lhs, const Int& rhs) { // If either is NaN, always false if (lhs.isNaN() || rhs.isNaN()) { return false; } // Comparison of infinities 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 is always false } if (rhs.m_state == NumericState::NegativeInfinity) { return false; // x < -∞ is always false } // Other special states if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { // The ordering of special states is not defined return false; } // This should be unreachable (comparison of normal values is handled separately) return false; } bool IntSpecialStates::compareEqual(const Int& lhs, const Int& rhs) { // If either is NaN, always false if (lhs.isNaN() || rhs.isNaN()) { return false; } // Equal if both are in the same special state if (lhs.m_state != NumericState::Normal && lhs.m_state == rhs.m_state) { // For infinity, also consider the sign if (lhs.isInfinite()) { return lhs.m_sign == rhs.m_sign; } return true; } // Different special states, or a special state vs. a normal value, are not equal if (lhs.m_state != NumericState::Normal || rhs.m_state != NumericState::Normal) { return false; } // This should be unreachable (comparison of normal values is handled separately) return false; } } // namespace sangi