f256 0.11.2

Octuple-precision floating-point arithmetic.
Documentation
// ---------------------------------------------------------------------------
// Copyright:   (c) 2023 ff. Michael Amrhein (michael@adrhinum.de)
// License:     This program is part of a larger application. For license
//              details please read the file LICENSE.TXT provided together
//              with the application.
// ---------------------------------------------------------------------------
// $Source$
// $Revision$

//! Basic mathematical constants.

use crate::{f256, EXP_BIAS, U256};

/// Archimedes' constant (π)
///
/// 3.1415926535897932384626433832795028841971693993751058209749445923078164
pub const PI: f256 = f256 {
    bits: U256::new(
        85070776964233020888379420810864062491,
        174929234171320688473765933587459524450,
    ),
};

/// The full circle constant (τ = 2π)
///
/// 6.2831853071795864769252867665590057683943387987502116419498891846156328
pub const TAU: f256 = f256 {
    bits: U256::new(
        85071101482786679315106203966884638747,
        174929234171320688473765933587459524450,
    ),
};

/// 3π/2
///
/// 4.7123889803846898576939650749192543262957540990626587314624168884617246
pub const FRAC_3_PI_2: f256 = f256::new(
    0,
    2,
    U256::new(
        382314414047586946914081706939412,
        216267517358725132221168102048536696202,
    ),
);

/// π/2
///
/// 1.5707963267948966192313216916397514420985846996875529104874722961539082
pub const FRAC_PI_2: f256 = f256 {
    bits: U256::new(
        85070452445679362461652637654843486235,
        174929234171320688473765933587459524450,
    ),
};

/// π/3
///
/// 1.04719755119659774615421446109316762806572313312503527365831486410260547
pub const FRAC_PI_3: f256 = f256 {
    bits: U256::new(
        85070282528162007978565120285195957607,
        230046945087859946803635491535562420119,
    ),
};

/// π/4
///
/// 0.7853981633974483096156608458198757210492923498437764552437361480769541
pub const FRAC_PI_4: f256 = f256 {
    bits: U256::new(
        85070127927125704034925854498822909979,
        174929234171320688473765933587459524450,
    ),
};

/// π/6
///
/// 0.523598775598298873077107230546583814032861566562517636829157432051302735
pub const FRAC_PI_6: f256 = f256 {
    bits: U256::new(
        85069958009608349551838337129175381351,
        230046945087859946803635491535562420119,
    ),
};

/// π/8
///
/// 0.39269908169872415480783042290993786052464617492188822762186807403847705
pub const FRAC_PI_8: f256 = f256 {
    bits: U256::new(
        85069803408572045608199071342802333723,
        174929234171320688473765933587459524450,
    ),
};

/// 1/π
///
/// 0.318309886183790671537767526745028724068919291480912897495334688117793596
pub const FRAC_1_PI: f256 = f256 {
    bits: U256::new(
        85069706845875500327645499421189881510,
        206986278175927573935717840202627382231,
    ),
};

/// 2/π
///
/// 0.636619772367581343075535053490057448137838582961825794990669376235587193
pub const FRAC_2_PI: f256 = f256 {
    bits: U256::new(
        85070031364429158754372282577210457766,
        206986278175927573935717840202627382231,
    ),
};

/// sqrt(π)
///
/// 1.77245385090551602729816748334114518279754945612238712821380778985291128
pub const SQRT_PI: f256 = f256 {
    bits: U256::new(
        85070517887287421179178408574669870555,
        196081862527210367688260911531529420449,
    ),
};

/// 2/sqrt(π)
///
/// 1.12837916709551257389615890312154517168810125865799771368817144342128494
pub const FRAC_2_SQRT_PI: f256 = f256 {
    bits: U256::new(
        85070308873102583148344920635171925375,
        287655892912639724059401590396951075229,
    ),
};

/// sqrt(2)
///
/// 1.41421356237309504880168872420969807856967187537694807317667973799073247
pub const SQRT_2: f256 = f256 {
    bits: U256::new(
        85070401631667124460448299797938859689,
        116743028156957324320397937785460273254,
    ),
};

/// 1/sqrt(2)
///
/// 0.707106781186547524400844362104849039284835937688474036588339868995366237
pub const FRAC_1_SQRT_2: f256 = f256 {
    bits: U256::new(
        85070077113113466033721516641918283433,
        116743028156957324320397937785460273254,
    ),
};

/// sqrt(5)
///
/// 2.23606797749978969640917366873127623544061835961152572427089724541052092
pub const SQRT_5: f256 = f256 {
    bits: U256::new(
        85070630034453927516731555118236173774,
        293111668962265138556237643962472537356,
    ),
};

/// Golden Ratio (φ = (1 + √5) / 2)
///
/// 1.61803398874989484820458683436563811772030917980576286213544862270526046
pub const PHI: f256 = f256 {
    bits: U256::new(
        85070467775177098303368163540225885646,
        293111668962265138556237643962472537356,
    ),
};

/// Euler's constant (γ)
///
/// 0.577215664901532860606512090082402431042159335939923598805767234884867725
pub const GAMMA: f256 = f256 {
    bits: U256::new(
        85069992808959086250767892500525883434,
        118855979546025341659232107741091106323,
    ),
};

/// Euler's number (e)
///
/// 2.71828182845904523536028747135266249775724709369995957496696762772407664
pub const E: f256 = f256 {
    bits: U256::new(
        85070708278124661195610032245162902759,
        222802656701688313363499752982718194317,
    ),
};

/// log₂(10)
///
/// 3.32192809488736234787031942948939017586483139302458061205475639581593478
pub const LOG2_10: f256 = f256 {
    bits: U256::new(
        85070806225331312509001490326926387637,
        334184565493856695912495380663507095645,
    ),
};

/// log₂(e)
///
/// 1.44269504088896340735992468100189213742664595415298593413544940693110923
pub const LOG2_E: f256 = f256 {
    bits: U256::new(
        85070410874435338483602230749821537571,
        223066862001648268900030815613626456629,
    ),
};

/// log₁₀(2)
///
/// 0.30102999566398119521373889472449302676818988146210854131042746112710819
pub const LOG10_2: f256 = f256 {
    bits: U256::new(
        85069684415295184869522113457298964847,
        194311423393590205950065478848290805498,
    ),
};

/// log₁₀(e)
///
/// 0.43429448190325182765112891891660508229439700580366656611445378316586465
pub const LOG10_E: f256 = f256 {
    bits: U256::new(
        85069857402488498475189653211593438630,
        164192268774284829881731129619354525426,
    ),
};

/// logₑ(2)
///
/// 0.69314718055994530941723212145817656807550013436025525412068000949339362
pub const LN_2: f256 = f256 {
    bits: U256::new(
        85070068052814656045284994940811804798,
        126058098762831240896900834817458532725,
    ),
};

/// logₑ(10)
///
/// 2.30258509299404568401799145468436420760110148862877297603332790096757261
pub const LN_10: f256 = f256 {
    bits: U256::new(
        85070640827472984379971325288035741786,
        129293958477818015387240946310013009982,
    ),
};

#[cfg(test)]
mod consts_tests {
    use super::*;

    #[test]
    fn test_pi() {
        assert_eq!(PI * f256::TWO, TAU);
        assert_eq!(PI / f256::TWO, FRAC_PI_2);
        assert_eq!(PI, FRAC_PI_2 + FRAC_PI_2);
        assert_eq!(PI + FRAC_PI_2, FRAC_3_PI_2);
        assert_eq!(PI / f256::from(3), FRAC_PI_3);
        assert_eq!(PI / f256::from(4), FRAC_PI_4);
        assert_eq!(PI / f256::from(6), FRAC_PI_6);
        assert_eq!(PI / f256::from(8), FRAC_PI_8);
        assert_eq!(f256::ONE / PI, FRAC_1_PI + FRAC_1_PI.ulp());
        assert_eq!(f256::TWO / PI, FRAC_2_PI + FRAC_2_PI.ulp());
    }

    #[test]
    fn test_phi() {
        assert_eq!(PHI + f256::ONE, PHI * PHI);
    }
}