Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  libm_tests.rs

  Sprache: Rust
 

#![cfg(all(not(feature = "std"), feature = "compact"))]

// These are adapted from libm, a port of musl libc's libm to Rust.
// libm can be found online [here](https://github.com/rust-lang/libm),
// and is similarly licensed under an Apache2.0/MIT license

use core::f64;
use minimal_lexical::libm;

#[test]
fn fabsf_sanity_test() {
    assert_eq!(libm::fabsf(-1.0), 1.0);
    assert_eq!(libm::fabsf(2.8), 2.8);
}

/// The spec: https://en.cppreference.com/w/cpp/numeric/math/fabs
#[test]
fn fabsf_spec_test() {
    assert!(libm::fabsf(f32::NAN).is_nan());
    for f in [0.0, -0.0].iter().copied() {
        assert_eq!(libm::fabsf(f), 0.0);
    }
    for f in [f32::INFINITY, f32::NEG_INFINITY].iter().copied() {
        assert_eq!(libm::fabsf(f), f32::INFINITY);
    }
}

#[test]
fn sqrtf_sanity_test() {
    assert_eq!(libm::sqrtf(100.0), 10.0);
    assert_eq!(libm::sqrtf(4.0), 2.0);
}

/// The spec: https://en.cppreference.com/w/cpp/numeric/math/sqrt
#[test]
fn sqrtf_spec_test() {
    // Not Asserted: FE_INVALID exception is raised if argument is negative.
    assert!(libm::sqrtf(-1.0).is_nan());
    assert!(libm::sqrtf(f32::NAN).is_nan());
    for f in [0.0, -0.0, f32::INFINITY].iter().copied() {
        assert_eq!(libm::sqrtf(f), f);
    }
}

const POS_ZERO: &[f64] = &[0.0];
const NEG_ZERO: &[f64] = &[-0.0];
const POS_ONE: &[f64] = &[1.0];
const NEG_ONE: &[f64] = &[-1.0];
const POS_FLOATS: &[f64] = &[99.0 / 70.0, f64::consts::E, f64::consts::PI];
const NEG_FLOATS: &[f64] = &[-99.0 / 70.0, -f64::consts::E, -f64::consts::PI];
const POS_SMALL_FLOATS: &[f64] = &[(1.0 / 2.0), f64::MIN_POSITIVE, f64::EPSILON];
const NEG_SMALL_FLOATS: &[f64] = &[-(1.0 / 2.0), -f64::MIN_POSITIVE, -f64::EPSILON];
const POS_EVENS: &[f64] = &[2.06.08.010.022.0100.0, f64::MAX];
const NEG_EVENS: &[f64] = &[f64::MIN, -100.0, -22.0, -10.0, -8.0, -6.0, -2.0];
const POS_ODDS: &[f64] = &[3.07.0];
const NEG_ODDS: &[f64] = &[-7.0, -3.0];
const NANS: &[f64] = &[f64::NAN];
const POS_INF: &[f64] = &[f64::INFINITY];
const NEG_INF: &[f64] = &[f64::NEG_INFINITY];

const ALL: &[&[f64]] = &[
    POS_ZERO,
    NEG_ZERO,
    NANS,
    NEG_SMALL_FLOATS,
    POS_SMALL_FLOATS,
    NEG_FLOATS,
    POS_FLOATS,
    NEG_EVENS,
    POS_EVENS,
    NEG_ODDS,
    POS_ODDS,
    NEG_INF,
    POS_INF,
    NEG_ONE,
    POS_ONE,
];
const POS: &[&[f64]] = &[POS_ZERO, POS_ODDS, POS_ONE, POS_FLOATS, POS_EVENS, POS_INF];
const NEG: &[&[f64]] = &[NEG_ZERO, NEG_ODDS, NEG_ONE, NEG_FLOATS, NEG_EVENS, NEG_INF];

fn powd(base: f64, exponent: f64, expected: f64) {
    let res = libm::powd(base, exponent);
    assert!(
        if expected.is_nan() {
            res.is_nan()
        } else {
            libm::powd(base, exponent) == expected
        },
        "{} ** {} was {} instead of {}",
        base,
        exponent,
        res,
        expected
    );
}

fn powd_test_sets_as_base(sets: &[&[f64]], exponent: f64, expected: f64) {
    sets.iter().for_each(|s| s.iter().for_each(|val| powd(*val, exponent, expected)));
}

fn powd_test_sets_as_exponent(base: f64, sets: &[&[f64]], expected: f64) {
    sets.iter().for_each(|s| s.iter().for_each(|val| powd(base, *val, expected)));
}

fn powd_test_sets(sets: &[&[f64]], computed: &dyn Fn(f64) -> f64, expected: &dyn Fn(f64) -> f64) {
    sets.iter().for_each(|s| {
        s.iter().for_each(|val| {
            let exp = expected(*val);
            let res = computed(*val);

            assert!(
                if exp.is_nan() {
                    res.is_nan()
                } else {
                    exp == res
                },
                "test for {} was {} instead of {}",
                val,
                res,
                exp
            );
        })
    });
}

#[test]
fn powd_zero_as_exponent() {
    powd_test_sets_as_base(ALL, 0.01.0);
    powd_test_sets_as_base(ALL, -0.01.0);
}

#[test]
fn powd_one_as_base() {
    powd_test_sets_as_exponent(1.0, ALL, 1.0);
}

#[test]
fn powd_nan_inputs() {
    // NAN as the base:
    // (NAN ^ anything *but 0* should be NAN)
    powd_test_sets_as_exponent(f64::NAN, &ALL[2..], f64::NAN);

    // NAN as the exponent:
    // (anything *but 1* ^ NAN should be NAN)
    powd_test_sets_as_base(&ALL[..(ALL.len() - 2)], f64::NAN, f64::NAN);
}

#[test]
fn powd_infinity_as_base() {
    // Positive Infinity as the base:
    // (+Infinity ^ positive anything but 0 and NAN should be +Infinity)
    powd_test_sets_as_exponent(f64::INFINITY, &POS[1..], f64::INFINITY);

    // (+Infinity ^ negative anything except 0 and NAN should be 0.0)
    powd_test_sets_as_exponent(f64::INFINITY, &NEG[1..], 0.0);

    // Negative Infinity as the base:
    // (-Infinity ^ positive odd ints should be -Infinity)
    powd_test_sets_as_exponent(f64::NEG_INFINITY, &[POS_ODDS], f64::NEG_INFINITY);

    // (-Infinity ^ anything but odd ints should be == -0 ^ (-anything))
    // We can lump in pos/neg odd ints here because they don't seem to
    // cause panics (div by zero) in release mode (I think).
    powd_test_sets(ALL, &|v: f64| libm::powd(f64::NEG_INFINITY, v), &|v: f64| libm::powd(-0.0, -v));
}

#[test]
fn infinity_as_exponent() {
    // Positive/Negative base greater than 1:
    // (pos/neg > 1 ^ Infinity should be Infinity - note this excludes NAN as the base)
    powd_test_sets_as_base(&ALL[5..(ALL.len() - 2)], f64::INFINITY, f64::INFINITY);

    // (pos/neg > 1 ^ -Infinity should be 0.0)
    powd_test_sets_as_base(&ALL[5..ALL.len() - 2], f64::NEG_INFINITY, 0.0);

    // Positive/Negative base less than 1:
    let base_below_one = &[POS_ZERO, NEG_ZERO, NEG_SMALL_FLOATS, POS_SMALL_FLOATS];

    // (pos/neg < 1 ^ Infinity should be 0.0 - this also excludes NAN as the base)
    powd_test_sets_as_base(base_below_one, f64::INFINITY, 0.0);

    // (pos/neg < 1 ^ -Infinity should be Infinity)
    powd_test_sets_as_base(base_below_one, f64::NEG_INFINITY, f64::INFINITY);

    // Positive/Negative 1 as the base:
    // (pos/neg 1 ^ Infinity should be 1)
    powd_test_sets_as_base(&[NEG_ONE, POS_ONE], f64::INFINITY, 1.0);

    // (pos/neg 1 ^ -Infinity should be 1)
    powd_test_sets_as_base(&[NEG_ONE, POS_ONE], f64::NEG_INFINITY, 1.0);
}

#[test]
fn powd_zero_as_base() {
    // Positive Zero as the base:
    // (+0 ^ anything positive but 0 and NAN should be +0)
    powd_test_sets_as_exponent(0.0, &POS[1..], 0.0);

    // (+0 ^ anything negative but 0 and NAN should be Infinity)
    // (this should panic because we're dividing by zero)
    powd_test_sets_as_exponent(0.0, &NEG[1..], f64::INFINITY);

    // Negative Zero as the base:
    // (-0 ^ anything positive but 0, NAN, and odd ints should be +0)
    powd_test_sets_as_exponent(-0.0, &POS[3..], 0.0);

    // (-0 ^ anything negative but 0, NAN, and odd ints should be Infinity)
    // (should panic because of divide by zero)
    powd_test_sets_as_exponent(-0.0, &NEG[3..], f64::INFINITY);

    // (-0 ^ positive odd ints should be -0)
    powd_test_sets_as_exponent(-0.0, &[POS_ODDS], -0.0);

    // (-0 ^ negative odd ints should be -Infinity)
    // (should panic because of divide by zero)
    powd_test_sets_as_exponent(-0.0, &[NEG_ODDS], f64::NEG_INFINITY);
}

#[test]
fn special_cases() {
    // One as the exponent:
    // (anything ^ 1 should be anything - i.e. the base)
    powd_test_sets(ALL, &|v: f64| libm::powd(v, 1.0), &|v: f64| v);

    // Negative One as the exponent:
    // (anything ^ -1 should be 1/anything)
    powd_test_sets(ALL, &|v: f64| libm::powd(v, -1.0), &|v: f64| 1.0 / v);

    // Factoring -1 out:
    // (negative anything ^ integer should be (-1 ^ integer) * (positive anything ^ integer))
    [POS_ZERO, NEG_ZERO, POS_ONE, NEG_ONE, POS_EVENS, NEG_EVENS].iter().for_each(|int_set| {
        int_set.iter().for_each(|int| {
            powd_test_sets(ALL, &|v: f64| libm::powd(-v, *int), &|v: f64| {
                libm::powd(-1.0, *int) * libm::powd(v, *int)
            });
        })
    });

    // Negative base (imaginary results):
    // (-anything except 0 and Infinity ^ non-integer should be NAN)
    NEG[1..(NEG.len() - 1)].iter().for_each(|set| {
        set.iter().for_each(|val| {
            powd_test_sets(&ALL[3..7], &|v: f64| libm::powd(*val, v), &|_| f64::NAN);
        })
    });
}

#[test]
fn normal_cases() {
    assert_eq!(libm::powd(2.020.0), (1 << 20as f64);
    assert_eq!(libm::powd(-1.09.0), -1.0);
    assert!(libm::powd(-1.02.2).is_nan());
    assert!(libm::powd(-1.0, -1.14).is_nan());
}

#[test]
fn fabsd_sanity_test() {
    assert_eq!(libm::fabsd(-1.0), 1.0);
    assert_eq!(libm::fabsd(2.8), 2.8);
}

/// The spec: https://en.cppreference.com/w/cpp/numeric/math/fabs
#[test]
fn fabsd_spec_test() {
    assert!(libm::fabsd(f64::NAN).is_nan());
    for f in [0.0, -0.0].iter().copied() {
        assert_eq!(libm::fabsd(f), 0.0);
    }
    for f in [f64::INFINITY, f64::NEG_INFINITY].iter().copied() {
        assert_eq!(libm::fabsd(f), f64::INFINITY);
    }
}

#[test]
fn sqrtd_sanity_test() {
    assert_eq!(libm::sqrtd(100.0), 10.0);
    assert_eq!(libm::sqrtd(4.0), 2.0);
}

/// The spec: https://en.cppreference.com/w/cpp/numeric/math/sqrt
#[test]
fn sqrtd_spec_test() {
    // Not Asserted: FE_INVALID exception is raised if argument is negative.
    assert!(libm::sqrtd(-1.0).is_nan());
    assert!(libm::sqrtd(f64::NAN).is_nan());
    for f in [0.0, -0.0, f64::INFINITY].iter().copied() {
        assert_eq!(libm::sqrtd(f), f);
    }
}

Messung V0.5 in Prozent
C=63 H=95 G=80

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-06-23) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik