spirix 0.1.1

Two's complement floating-point arithmetic library
Documentation
use crate::core::integer::*;
use crate::core::undefined::*;
use crate::{Circle, CircleConstants, Integer, Scalar, ScalarConstants};
use core::ops::*;
use i256::I256;
use num_traits::{AsPrimitive, WrappingAdd, WrappingMul, WrappingNeg, WrappingSub};
#[allow(private_bounds)]
impl<
        F: Integer
            + FullInt
            + Shl<isize, Output = F>
            + Shr<isize, Output = F>
            + Shl<F, Output = F>
            + Shr<F, Output = F>
            + Shl<E, Output = F>
            + Shr<E, Output = F>
            + WrappingNeg
            + WrappingAdd
            + WrappingMul
            + WrappingSub,
        E: Integer
            + FullInt
            + Shl<isize, Output = E>
            + Shr<isize, Output = E>
            + Shl<E, Output = E>
            + Shr<E, Output = E>
            + Shl<F, Output = E>
            + Shr<F, Output = E>
            + WrappingNeg
            + WrappingAdd
            + WrappingMul
            + WrappingSub,
    > Scalar<F, E>
where
    Circle<F, E>: CircleConstants,
    Scalar<F, E>: ScalarConstants,
    u8: AsPrimitive<F>,
    u16: AsPrimitive<F>,
    u32: AsPrimitive<F>,
    u64: AsPrimitive<F>,
    u128: AsPrimitive<F>,
    usize: AsPrimitive<F>,
    i8: AsPrimitive<F>,
    i16: AsPrimitive<F>,
    i32: AsPrimitive<F>,
    i64: AsPrimitive<F>,
    i128: AsPrimitive<F>,
    isize: AsPrimitive<F>,
    I256: From<F>,
    u8: AsPrimitive<E>,
    u16: AsPrimitive<E>,
    u32: AsPrimitive<E>,
    u64: AsPrimitive<E>,
    u128: AsPrimitive<E>,
    usize: AsPrimitive<E>,
    i8: AsPrimitive<E>,
    i16: AsPrimitive<E>,
    i32: AsPrimitive<E>,
    i64: AsPrimitive<E>,
    i128: AsPrimitive<E>,
    isize: AsPrimitive<E>,
    I256: From<E>,
{
    /// Mathematical complex modulus operation for Scalar with Circle
    ///
    /// Performs complex modulus using the mathematical formula: For scalar s and complex number (a + bi), calculates: real = (s * a) % (a² + b²) imag = (s * b) % (a² + b²)
    ///
    /// Returns UNDEFINED if:
    /// - Either number is escaped
    /// - Both numbers are effectively zero
    /// - Denominator magnitude (a² + b²) is effectively zero
    pub(crate) fn scalar_modulus_circle(&self, denominator: &Circle<F, E>) -> Circle<F, E> {
        if !self.is_normal() || !denominator.is_normal() {
            // Mirrors scalar_modulus_scalar's rule order with Circle's magnitude treated as the period: 1) undefined, 2) zero anywhere, 3) transfinite numerator (distinguishes whether period is also transfinite), 4) vanished period (distinguishes whether numerator vanished), 5) infinite period, 6) exploded period (Circle magnitude is non-negative, so positive numerator → numerator; vanished+diff returns modulus), 7) vanished numerator with normal period. The earlier block returned INFINITY for infinite denominators (rule 5 violation) and copied self.fraction into real+imaginary as N1 (corrupted class — N0 magnitude bit lands at N1 vanished position).
            if self.is_undefined() {
                return Circle::<F, E> {
                    real: self.fraction,
                    imaginary: self.fraction,
                    exponent: self.exponent,
                };
            }
            if denominator.is_undefined() {
                return *denominator;
            }
            if self.is_zero() || denominator.is_zero() {
                return Circle::<F, E>::ZERO;
            }
            if self.is_transfinite() {
                let prefix: F = if denominator.is_transfinite() {
                    TRANSFINITE_MODULUS_TRANSFINITE.prefix.sa()
                } else {
                    TRANSFINITE_MODULUS.prefix.sa()
                };
                return Circle::<F, E> {
                    real: prefix,
                    imaginary: prefix,
                    exponent: Self::ambiguous_exponent(),
                };
            }
            if denominator.vanished() {
                let prefix: F = if self.vanished() {
                    VANISHED_MODULUS_VANISHED.prefix.sa()
                } else {
                    MODULUS_VANISHED.prefix.sa()
                };
                return Circle::<F, E> {
                    real: prefix,
                    imaginary: prefix,
                    exponent: Self::ambiguous_exponent(),
                };
            }
            if denominator.is_infinite() {
                let prefix: F = MODULUS_TRANSFINITE.prefix.sa();
                return Circle::<F, E> {
                    real: prefix,
                    imaginary: prefix,
                    exponent: Self::ambiguous_exponent(),
                };
            }
            // Exploded Circle period: magnitude is non-negative so positive scalar (any class) keeps numerator; negative scalar diverges.
            if denominator.exploded() {
                if !self.is_negative() {
                    return Circle::<F, E>::from_ri(*self, Scalar::<F, E>::ZERO);
                }
                if self.vanished() {
                    return *denominator;
                }
                let prefix: F = MODULUS_TRANSFINITE.prefix.sa();
                return Circle::<F, E> {
                    real: prefix,
                    imaginary: prefix,
                    exponent: Self::ambiguous_exponent(),
                };
            }
            // Vanished numerator with normal Circle period (other classes already handled). |↓|<|#| so |↓| % positive_circle = ↓ for positive scalar; negative diverges to modulus.
            if self.vanished() {
                if !self.is_negative() {
                    return Circle::<F, E>::from_ri(*self, Scalar::<F, E>::ZERO);
                }
                return *denominator;
            }
            // Fallthrough — shouldn't reach.
            return Circle::<F, E>::from_ri(*self, Scalar::<F, E>::ZERO);
        }
        // Calculate magnitude squared (a² + b²)
        let magnitude_squared = denominator
            .r()
            .square()
            .scalar_add_scalar(&denominator.i().square());

        // Calculate real = (s * a) % (a² + b²)
        let real = self
            .scalar_multiply_scalar(&denominator.r())
            .scalar_modulus_scalar(&magnitude_squared);

        // Calculate imag = (s * b) % (a² + b²)
        let imag = self
            .scalar_multiply_scalar(&denominator.i())
            .scalar_modulus_scalar(&magnitude_squared);

        Circle::<F, E>::from_ri(real, imag)
    }
    /// Component-wise modulo operation for Scalar with Circle
    ///
    /// Performs modulo separately on real and imaginary components: s ‰ (a + bi) = (s % a) + (s % b)i scalar.modulo(circle);
    ///
    /// Returns UNDEFINED if:
    /// - Either number is escaped
    /// - Both numbers are effectively zero
    pub(crate) fn scalar_modulo_circle(&self, denominator: &Circle<F, E>) -> Circle<F, E> {
        if !self.is_normal() || !denominator.is_normal() {
            if self.is_undefined() {
                return Circle::<F, E> {
                    real: self.fraction,
                    imaginary: self.fraction,
                    exponent: self.exponent,
                };
            }
            if denominator.is_undefined() {
                return *denominator;
            }
            if self.is_zero() || denominator.is_zero() {
                return Circle::<F, E>::ZERO;
            }
            if self.is_transfinite() {
                let prefix: F = TRANSFINITE_MODULO.prefix.sa();
                return Circle::<F, E> {
                    real: prefix,
                    imaginary: prefix,
                    exponent: Self::ambiguous_exponent(),
                };
            }
            if denominator.is_infinite() {
                return Circle::<F, E>::INFINITY;
            }
            if denominator.vanished() {
                let prefix: F = MODULO_VANISHED.prefix.sa();
                return Circle::<F, E> {
                    real: prefix,
                    imaginary: prefix,
                    exponent: Self::ambiguous_exponent(),
                };
            }
            return Circle::<F, E> {
                real: self.fraction,
                imaginary: self.fraction,
                exponent: self.exponent,
            };
        }
        Circle::<F, E>::from_ri(
            self.scalar_modulus_scalar(&denominator.r()),
            self.scalar_modulus_scalar(&denominator.i()),
        )
    }
}