// Copyright © 2024 Mikhail Hogrefe
//
// This file is part of Malachite.
//
// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
// 3 of the License, or (at your option) any later version. See .
use malachite_base::assert_panic;
use malachite_base::num::basic::floats::PrimitiveFloat;
use malachite_base::num::comparison::traits::PartialOrdAbs;
use malachite_base::num::conversion::traits::{ExactFrom, SciMantissaAndExponent};
use malachite_base::num::float::NiceFloat;
use malachite_base::rounding_modes::RoundingMode::{self, *};
use malachite_base::test_util::generators::{
primitive_float_signed_pair_gen_var_1, primitive_float_signed_pair_gen_var_2,
};
use malachite_nz::natural::Natural;
use malachite_nz::test_util::generators::{
natural_gen_var_2, natural_rounding_mode_pair_gen_var_2,
};
use malachite_q::test_util::generators::{
rational_gen_var_1, rational_rounding_mode_pair_gen_var_4,
};
use malachite_q::Rational;
use std::cmp::Ordering::{self, *};
use std::panic::catch_unwind;
use std::str::FromStr;
#[test]
fn test_sci_mantissa_and_exponent() {
let test = |s: &str, mantissa: f32, exponent: i64| {
let n = Rational::from_str(s).unwrap();
let (actual_mantissa, actual_exponent) = (&n).sci_mantissa_and_exponent();
assert_eq!(NiceFloat(actual_mantissa), NiceFloat(mantissa));
assert_eq!(actual_exponent, exponent);
let (actual_mantissa, actual_exponent) = n.clone().sci_mantissa_and_exponent();
assert_eq!(NiceFloat(actual_mantissa), NiceFloat(mantissa));
assert_eq!(actual_exponent, exponent);
assert_eq!(NiceFloat((&n).sci_mantissa()), NiceFloat(mantissa));
assert_eq!(
SciMantissaAndExponent::::sci_exponent(&n),
exponent
);
assert_eq!(NiceFloat(n.clone().sci_mantissa()), NiceFloat(mantissa));
assert_eq!(
SciMantissaAndExponent::::sci_exponent(n.clone()),
exponent
);
let (actual_mantissa, actual_exponent) = (-n).sci_mantissa_and_exponent();
assert_eq!(NiceFloat(actual_mantissa), NiceFloat(mantissa));
assert_eq!(actual_exponent, exponent);
};
test("3", 1.5, 1);
test("123", 1.921875, 6);
test("1000000000", 1.8626451, 29);
test("16777216", 1.0, 24);
test("16777218", 1.0000001, 24);
test("16777217", 1.0, 24);
test("33554432", 1.0, 25);
test("33554436", 1.0000001, 25);
test("33554440", 1.0000002, 25);
test("33554433", 1.0, 25);
test("33554434", 1.0, 25);
test("33554435", 1.0000001, 25);
test("33554437", 1.0000001, 25);
test("33554438", 1.0000002, 25);
test("33554439", 1.0000002, 25);
test("340282346638528859811704183484516925439", 1.9999999, 127);
test("340282346638528859811704183484516925440", 1.9999999, 127);
test("340282346638528859811704183484516925441", 1.9999999, 127);
test(
"10000000000000000000000000000000000000000000000000000",
1.670478,
172,
);
test(
"14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
1.8920966,
458,
);
test("1/3", 1.3333334, -2);
test("1/1024", 1.0, -10);
test("22/7", 1.5714285, 1);
test("936851431250/1397", 1.2491208, 29);
}
#[test]
fn test_sci_mantissa_and_exponent_round() {
let test = |n: &str, rm: RoundingMode, out: Option<(f32, i64, Ordering)>| {
let r = Rational::from_str(n).unwrap();
let actual_out = r.clone().sci_mantissa_and_exponent_round(rm);
assert_eq!(
actual_out.map(|(m, e, o)| (NiceFloat(m), e, o)),
out.map(|(m, e, o)| (NiceFloat(m), e, o))
);
let actual_out = r.sci_mantissa_and_exponent_round_ref(rm);
assert_eq!(
actual_out.map(|(m, e, o)| (NiceFloat(m), e, o)),
out.map(|(m, e, o)| (NiceFloat(m), e, o))
);
let actual_out = (-r).sci_mantissa_and_exponent_round(rm);
assert_eq!(
actual_out.map(|(m, e, o)| (NiceFloat(m), e, o)),
out.map(|(m, e, o)| (NiceFloat(m), e, o))
);
};
test("3", Floor, Some((1.5, 1, Equal)));
test("3", Down, Some((1.5, 1, Equal)));
test("3", Ceiling, Some((1.5, 1, Equal)));
test("3", Up, Some((1.5, 1, Equal)));
test("3", Nearest, Some((1.5, 1, Equal)));
test("3", Exact, Some((1.5, 1, Equal)));
test("123", Floor, Some((1.921875, 6, Equal)));
test("123", Down, Some((1.921875, 6, Equal)));
test("123", Ceiling, Some((1.921875, 6, Equal)));
test("123", Up, Some((1.921875, 6, Equal)));
test("123", Nearest, Some((1.921875, 6, Equal)));
test("123", Exact, Some((1.921875, 6, Equal)));
test("1000000000", Floor, Some((1.8626451, 29, Equal)));
test("1000000000", Down, Some((1.8626451, 29, Equal)));
test("1000000000", Ceiling, Some((1.8626451, 29, Equal)));
test("1000000000", Up, Some((1.8626451, 29, Equal)));
test("1000000000", Nearest, Some((1.8626451, 29, Equal)));
test("1000000000", Exact, Some((1.8626451, 29, Equal)));
test("16777216", Floor, Some((1.0, 24, Equal)));
test("16777216", Down, Some((1.0, 24, Equal)));
test("16777216", Ceiling, Some((1.0, 24, Equal)));
test("16777216", Up, Some((1.0, 24, Equal)));
test("16777216", Nearest, Some((1.0, 24, Equal)));
test("16777216", Exact, Some((1.0, 24, Equal)));
test("16777218", Floor, Some((1.0000001, 24, Equal)));
test("16777218", Down, Some((1.0000001, 24, Equal)));
test("16777218", Ceiling, Some((1.0000001, 24, Equal)));
test("16777218", Up, Some((1.0000001, 24, Equal)));
test("16777218", Nearest, Some((1.0000001, 24, Equal)));
test("16777218", Exact, Some((1.0000001, 24, Equal)));
test("16777217", Floor, Some((1.0, 24, Less)));
test("16777217", Down, Some((1.0, 24, Less)));
test("16777217", Ceiling, Some((1.0000001, 24, Greater)));
test("16777217", Up, Some((1.0000001, 24, Greater)));
test("16777217", Nearest, Some((1.0, 24, Less)));
test("16777217", Exact, None);
test("33554432", Floor, Some((1.0, 25, Equal)));
test("33554432", Down, Some((1.0, 25, Equal)));
test("33554432", Ceiling, Some((1.0, 25, Equal)));
test("33554432", Up, Some((1.0, 25, Equal)));
test("33554432", Nearest, Some((1.0, 25, Equal)));
test("33554432", Exact, Some((1.0, 25, Equal)));
test("33554436", Floor, Some((1.0000001, 25, Equal)));
test("33554436", Down, Some((1.0000001, 25, Equal)));
test("33554436", Ceiling, Some((1.0000001, 25, Equal)));
test("33554436", Up, Some((1.0000001, 25, Equal)));
test("33554436", Nearest, Some((1.0000001, 25, Equal)));
test("33554436", Exact, Some((1.0000001, 25, Equal)));
test("33554440", Floor, Some((1.0000002, 25, Equal)));
test("33554440", Down, Some((1.0000002, 25, Equal)));
test("33554440", Ceiling, Some((1.0000002, 25, Equal)));
test("33554440", Up, Some((1.0000002, 25, Equal)));
test("33554440", Nearest, Some((1.0000002, 25, Equal)));
test("33554440", Exact, Some((1.0000002, 25, Equal)));
test("33554433", Floor, Some((1.0, 25, Less)));
test("33554433", Down, Some((1.0, 25, Less)));
test("33554433", Ceiling, Some((1.0000001, 25, Greater)));
test("33554433", Up, Some((1.0000001, 25, Greater)));
test("33554433", Nearest, Some((1.0, 25, Less)));
test("33554433", Exact, None);
test("33554434", Floor, Some((1.0, 25, Less)));
test("33554434", Down, Some((1.0, 25, Less)));
test("33554434", Ceiling, Some((1.0000001, 25, Greater)));
test("33554434", Up, Some((1.0000001, 25, Greater)));
test("33554434", Nearest, Some((1.0, 25, Less)));
test("33554434", Exact, None);
test("33554435", Floor, Some((1.0, 25, Less)));
test("33554435", Down, Some((1.0, 25, Less)));
test("33554435", Ceiling, Some((1.0000001, 25, Greater)));
test("33554435", Up, Some((1.0000001, 25, Greater)));
test("33554435", Nearest, Some((1.0000001, 25, Greater)));
test("33554435", Exact, None);
test("33554437", Floor, Some((1.0000001, 25, Less)));
test("33554437", Down, Some((1.0000001, 25, Less)));
test("33554437", Ceiling, Some((1.0000002, 25, Greater)));
test("33554437", Up, Some((1.0000002, 25, Greater)));
test("33554437", Nearest, Some((1.0000001, 25, Less)));
test("33554437", Exact, None);
test("33554438", Floor, Some((1.0000001, 25, Less)));
test("33554438", Down, Some((1.0000001, 25, Less)));
test("33554438", Ceiling, Some((1.0000002, 25, Greater)));
test("33554438", Up, Some((1.0000002, 25, Greater)));
test("33554438", Nearest, Some((1.0000002, 25, Greater)));
test("33554438", Exact, None);
test("33554439", Floor, Some((1.0000001, 25, Less)));
test("33554439", Down, Some((1.0000001, 25, Less)));
test("33554439", Ceiling, Some((1.0000002, 25, Greater)));
test("33554439", Up, Some((1.0000002, 25, Greater)));
test("33554439", Nearest, Some((1.0000002, 25, Greater)));
test("33554439", Exact, None);
test(
"340282346638528859811704183484516925439",
Floor,
Some((1.9999998, 127, Less)),
);
test(
"340282346638528859811704183484516925439",
Down,
Some((1.9999998, 127, Less)),
);
test(
"340282346638528859811704183484516925439",
Ceiling,
Some((1.9999999, 127, Greater)),
);
test(
"340282346638528859811704183484516925439",
Up,
Some((1.9999999, 127, Greater)),
);
test(
"340282346638528859811704183484516925439",
Nearest,
Some((1.9999999, 127, Greater)),
);
test("340282346638528859811704183484516925439", Exact, None);
test(
"340282346638528859811704183484516925440",
Floor,
Some((1.9999999, 127, Equal)),
);
test(
"340282346638528859811704183484516925440",
Down,
Some((1.9999999, 127, Equal)),
);
test(
"340282346638528859811704183484516925440",
Ceiling,
Some((1.9999999, 127, Equal)),
);
test(
"340282346638528859811704183484516925440",
Up,
Some((1.9999999, 127, Equal)),
);
test(
"340282346638528859811704183484516925440",
Nearest,
Some((1.9999999, 127, Equal)),
);
test(
"340282346638528859811704183484516925440",
Exact,
Some((1.9999999, 127, Equal)),
);
test(
"340282346638528859811704183484516925441",
Floor,
Some((1.9999999, 127, Less)),
);
test(
"340282346638528859811704183484516925441",
Down,
Some((1.9999999, 127, Less)),
);
test(
"340282346638528859811704183484516925441",
Ceiling,
Some((1.0, 128, Greater)),
);
test(
"340282346638528859811704183484516925441",
Up,
Some((1.0, 128, Greater)),
);
test(
"340282346638528859811704183484516925441",
Nearest,
Some((1.9999999, 127, Less)),
);
test("340282346638528859811704183484516925441", Exact, None);
test(
"10000000000000000000000000000000000000000000000000000",
Floor,
Some((1.6704779, 172, Less)),
);
test(
"10000000000000000000000000000000000000000000000000000",
Down,
Some((1.6704779, 172, Less)),
);
test(
"10000000000000000000000000000000000000000000000000000",
Ceiling,
Some((1.670478, 172, Greater)),
);
test(
"10000000000000000000000000000000000000000000000000000",
Up,
Some((1.670478, 172, Greater)),
);
test(
"10000000000000000000000000000000000000000000000000000",
Nearest,
Some((1.670478, 172, Greater)),
);
test(
"10000000000000000000000000000000000000000000000000000",
Exact,
None,
);
test(
"14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Floor,
Some((1.8920966, 458, Less)),
);
test(
"14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Down,
Some((1.8920966, 458, Less)),
);
test(
"14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Ceiling,
Some((1.8920968, 458, Greater)),
);
test(
"14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Up,
Some((1.8920968, 458, Greater)),
);
test(
"14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Nearest,
Some((1.8920966, 458, Less)),
);
test(
"14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Exact,
None,
);
test("1/3", Floor, Some((1.3333333, -2, Less)));
test("1/3", Ceiling, Some((1.3333334, -2, Greater)));
test("1/3", Down, Some((1.3333333, -2, Less)));
test("1/3", Up, Some((1.3333334, -2, Greater)));
test("1/3", Nearest, Some((1.3333334, -2, Greater)));
test("1/3", Exact, None);
test("1/1024", Floor, Some((1.0, -10, Equal)));
test("1/1024", Ceiling, Some((1.0, -10, Equal)));
test("1/1024", Down, Some((1.0, -10, Equal)));
test("1/1024", Up, Some((1.0, -10, Equal)));
test("1/1024", Nearest, Some((1.0, -10, Equal)));
test("1/1024", Exact, Some((1.0, -10, Equal)));
test("22/7", Floor, Some((1.5714285, 1, Less)));
test("22/7", Ceiling, Some((1.5714287, 1, Greater)));
test("22/7", Down, Some((1.5714285, 1, Less)));
test("22/7", Up, Some((1.5714287, 1, Greater)));
test("22/7", Nearest, Some((1.5714285, 1, Less)));
test("22/7", Exact, None);
test("936851431250/1397", Floor, Some((1.2491207, 29, Less)));
test("936851431250/1397", Ceiling, Some((1.2491208, 29, Greater)));
test("936851431250/1397", Down, Some((1.2491207, 29, Less)));
test("936851431250/1397", Up, Some((1.2491208, 29, Greater)));
test("936851431250/1397", Nearest, Some((1.2491208, 29, Greater)));
test("936851431250/1397", Exact, None);
test(
"1073741823/1099511627776",
Floor,
Some((1.9999999, -11, Less)),
);
test(
"1073741823/1099511627776",
Ceiling,
Some((1.0, -10, Greater)),
);
test(
"1073741823/1099511627776",
Down,
Some((1.9999999, -11, Less)),
);
test("1073741823/1099511627776", Up, Some((1.0, -10, Greater)));
test(
"1073741823/1099511627776",
Nearest,
Some((1.0, -10, Greater)),
);
test("1073741823/1099511627776", Exact, None);
test("-3", Floor, Some((1.5, 1, Equal)));
test("-3", Down, Some((1.5, 1, Equal)));
test("-3", Ceiling, Some((1.5, 1, Equal)));
test("-3", Up, Some((1.5, 1, Equal)));
test("-3", Nearest, Some((1.5, 1, Equal)));
test("-3", Exact, Some((1.5, 1, Equal)));
test("-123", Floor, Some((1.921875, 6, Equal)));
test("-123", Down, Some((1.921875, 6, Equal)));
test("-123", Ceiling, Some((1.921875, 6, Equal)));
test("-123", Up, Some((1.921875, 6, Equal)));
test("-123", Nearest, Some((1.921875, 6, Equal)));
test("-123", Exact, Some((1.921875, 6, Equal)));
test("-1000000000", Floor, Some((1.8626451, 29, Equal)));
test("-1000000000", Down, Some((1.8626451, 29, Equal)));
test("-1000000000", Ceiling, Some((1.8626451, 29, Equal)));
test("-1000000000", Up, Some((1.8626451, 29, Equal)));
test("-1000000000", Nearest, Some((1.8626451, 29, Equal)));
test("-1000000000", Exact, Some((1.8626451, 29, Equal)));
test("-16777216", Floor, Some((1.0, 24, Equal)));
test("-16777216", Down, Some((1.0, 24, Equal)));
test("-16777216", Ceiling, Some((1.0, 24, Equal)));
test("-16777216", Up, Some((1.0, 24, Equal)));
test("-16777216", Nearest, Some((1.0, 24, Equal)));
test("-16777216", Exact, Some((1.0, 24, Equal)));
test("-16777218", Floor, Some((1.0000001, 24, Equal)));
test("-16777218", Down, Some((1.0000001, 24, Equal)));
test("-16777218", Ceiling, Some((1.0000001, 24, Equal)));
test("-16777218", Up, Some((1.0000001, 24, Equal)));
test("-16777218", Nearest, Some((1.0000001, 24, Equal)));
test("-16777218", Exact, Some((1.0000001, 24, Equal)));
test("-16777217", Floor, Some((1.0, 24, Less)));
test("-16777217", Down, Some((1.0, 24, Less)));
test("-16777217", Ceiling, Some((1.0000001, 24, Greater)));
test("-16777217", Up, Some((1.0000001, 24, Greater)));
test("-16777217", Nearest, Some((1.0, 24, Less)));
test("-16777217", Exact, None);
test("-33554432", Floor, Some((1.0, 25, Equal)));
test("-33554432", Down, Some((1.0, 25, Equal)));
test("-33554432", Ceiling, Some((1.0, 25, Equal)));
test("-33554432", Up, Some((1.0, 25, Equal)));
test("-33554432", Nearest, Some((1.0, 25, Equal)));
test("-33554432", Exact, Some((1.0, 25, Equal)));
test("-33554436", Floor, Some((1.0000001, 25, Equal)));
test("-33554436", Down, Some((1.0000001, 25, Equal)));
test("-33554436", Ceiling, Some((1.0000001, 25, Equal)));
test("-33554436", Up, Some((1.0000001, 25, Equal)));
test("-33554436", Nearest, Some((1.0000001, 25, Equal)));
test("-33554436", Exact, Some((1.0000001, 25, Equal)));
test("-33554440", Floor, Some((1.0000002, 25, Equal)));
test("-33554440", Down, Some((1.0000002, 25, Equal)));
test("-33554440", Ceiling, Some((1.0000002, 25, Equal)));
test("-33554440", Up, Some((1.0000002, 25, Equal)));
test("-33554440", Nearest, Some((1.0000002, 25, Equal)));
test("-33554440", Exact, Some((1.0000002, 25, Equal)));
test("-33554433", Floor, Some((1.0, 25, Less)));
test("-33554433", Down, Some((1.0, 25, Less)));
test("-33554433", Ceiling, Some((1.0000001, 25, Greater)));
test("-33554433", Up, Some((1.0000001, 25, Greater)));
test("-33554433", Nearest, Some((1.0, 25, Less)));
test("-33554433", Exact, None);
test("-33554434", Floor, Some((1.0, 25, Less)));
test("-33554434", Down, Some((1.0, 25, Less)));
test("-33554434", Ceiling, Some((1.0000001, 25, Greater)));
test("-33554434", Up, Some((1.0000001, 25, Greater)));
test("-33554434", Nearest, Some((1.0, 25, Less)));
test("-33554434", Exact, None);
test("-33554435", Floor, Some((1.0, 25, Less)));
test("-33554435", Down, Some((1.0, 25, Less)));
test("-33554435", Ceiling, Some((1.0000001, 25, Greater)));
test("-33554435", Up, Some((1.0000001, 25, Greater)));
test("-33554435", Nearest, Some((1.0000001, 25, Greater)));
test("-33554435", Exact, None);
test("-33554437", Floor, Some((1.0000001, 25, Less)));
test("-33554437", Down, Some((1.0000001, 25, Less)));
test("-33554437", Ceiling, Some((1.0000002, 25, Greater)));
test("-33554437", Up, Some((1.0000002, 25, Greater)));
test("-33554437", Nearest, Some((1.0000001, 25, Less)));
test("-33554437", Exact, None);
test("-33554438", Floor, Some((1.0000001, 25, Less)));
test("-33554438", Down, Some((1.0000001, 25, Less)));
test("-33554438", Ceiling, Some((1.0000002, 25, Greater)));
test("-33554438", Up, Some((1.0000002, 25, Greater)));
test("-33554438", Nearest, Some((1.0000002, 25, Greater)));
test("-33554438", Exact, None);
test("-33554439", Floor, Some((1.0000001, 25, Less)));
test("-33554439", Down, Some((1.0000001, 25, Less)));
test("-33554439", Ceiling, Some((1.0000002, 25, Greater)));
test("-33554439", Up, Some((1.0000002, 25, Greater)));
test("-33554439", Nearest, Some((1.0000002, 25, Greater)));
test("-33554439", Exact, None);
test(
"-340282346638528859811704183484516925439",
Floor,
Some((1.9999998, 127, Less)),
);
test(
"-340282346638528859811704183484516925439",
Down,
Some((1.9999998, 127, Less)),
);
test(
"-340282346638528859811704183484516925439",
Ceiling,
Some((1.9999999, 127, Greater)),
);
test(
"-340282346638528859811704183484516925439",
Up,
Some((1.9999999, 127, Greater)),
);
test(
"-340282346638528859811704183484516925439",
Nearest,
Some((1.9999999, 127, Greater)),
);
test("-340282346638528859811704183484516925439", Exact, None);
test(
"-340282346638528859811704183484516925440",
Floor,
Some((1.9999999, 127, Equal)),
);
test(
"-340282346638528859811704183484516925440",
Down,
Some((1.9999999, 127, Equal)),
);
test(
"-340282346638528859811704183484516925440",
Ceiling,
Some((1.9999999, 127, Equal)),
);
test(
"-340282346638528859811704183484516925440",
Up,
Some((1.9999999, 127, Equal)),
);
test(
"-340282346638528859811704183484516925440",
Nearest,
Some((1.9999999, 127, Equal)),
);
test(
"-340282346638528859811704183484516925440",
Exact,
Some((1.9999999, 127, Equal)),
);
test(
"-340282346638528859811704183484516925441",
Floor,
Some((1.9999999, 127, Less)),
);
test(
"-340282346638528859811704183484516925441",
Down,
Some((1.9999999, 127, Less)),
);
test(
"-340282346638528859811704183484516925441",
Ceiling,
Some((1.0, 128, Greater)),
);
test(
"-340282346638528859811704183484516925441",
Up,
Some((1.0, 128, Greater)),
);
test(
"-340282346638528859811704183484516925441",
Nearest,
Some((1.9999999, 127, Less)),
);
test("-340282346638528859811704183484516925441", Exact, None);
test(
"-10000000000000000000000000000000000000000000000000000",
Floor,
Some((1.6704779, 172, Less)),
);
test(
"-10000000000000000000000000000000000000000000000000000",
Down,
Some((1.6704779, 172, Less)),
);
test(
"-10000000000000000000000000000000000000000000000000000",
Ceiling,
Some((1.670478, 172, Greater)),
);
test(
"-10000000000000000000000000000000000000000000000000000",
Up,
Some((1.670478, 172, Greater)),
);
test(
"-10000000000000000000000000000000000000000000000000000",
Nearest,
Some((1.670478, 172, Greater)),
);
test(
"-10000000000000000000000000000000000000000000000000000",
Exact,
None,
);
test(
"-14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Floor,
Some((1.8920966, 458, Less)),
);
test(
"-14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Down,
Some((1.8920966, 458, Less)),
);
test(
"-14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Ceiling,
Some((1.8920968, 458, Greater)),
);
test(
"-14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Up,
Some((1.8920968, 458, Greater)),
);
test(
"-14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Nearest,
Some((1.8920966, 458, Less)),
);
test(
"-14082550970654138785851080671018547544414440081606160064666506533805114137489745015963441\
66687102119468305028824490080062160433429798263165",
Exact,
None,
);
test("-1/3", Floor, Some((1.3333333, -2, Less)));
test("-1/3", Ceiling, Some((1.3333334, -2, Greater)));
test("-1/3", Down, Some((1.3333333, -2, Less)));
test("-1/3", Up, Some((1.3333334, -2, Greater)));
test("-1/3", Nearest, Some((1.3333334, -2, Greater)));
test("-1/3", Exact, None);
test("-1/1024", Floor, Some((1.0, -10, Equal)));
test("-1/1024", Ceiling, Some((1.0, -10, Equal)));
test("-1/1024", Down, Some((1.0, -10, Equal)));
test("-1/1024", Up, Some((1.0, -10, Equal)));
test("-1/1024", Nearest, Some((1.0, -10, Equal)));
test("-1/1024", Exact, Some((1.0, -10, Equal)));
test("-22/7", Floor, Some((1.5714285, 1, Less)));
test("-22/7", Ceiling, Some((1.5714287, 1, Greater)));
test("-22/7", Down, Some((1.5714285, 1, Less)));
test("-22/7", Up, Some((1.5714287, 1, Greater)));
test("-22/7", Nearest, Some((1.5714285, 1, Less)));
test("-22/7", Exact, None);
test("-936851431250/1397", Floor, Some((1.2491207, 29, Less)));
test(
"-936851431250/1397",
Ceiling,
Some((1.2491208, 29, Greater)),
);
test("-936851431250/1397", Down, Some((1.2491207, 29, Less)));
test("-936851431250/1397", Up, Some((1.2491208, 29, Greater)));
test(
"-936851431250/1397",
Nearest,
Some((1.2491208, 29, Greater)),
);
test("-936851431250/1397", Exact, None);
test(
"-1073741823/1099511627776",
Floor,
Some((1.9999999, -11, Less)),
);
test(
"-1073741823/1099511627776",
Ceiling,
Some((1.0, -10, Greater)),
);
test(
"-1073741823/1099511627776",
Down,
Some((1.9999999, -11, Less)),
);
test("-1073741823/1099511627776", Up, Some((1.0, -10, Greater)));
test(
"-1073741823/1099511627776",
Nearest,
Some((1.0, -10, Greater)),
);
test("-1073741823/1099511627776", Exact, None);
}
#[test]
fn test_from_sci_mantissa_and_exponent() {
let test = |mantissa: f32, exponent: i64, out: Option<&str>| {
assert_eq!(
<&Rational as SciMantissaAndExponent<_, _, _>>::from_sci_mantissa_and_exponent(
mantissa, exponent
),
out.map(|s| Rational::from_str(s).unwrap())
);
assert_eq!(
>::from_sci_mantissa_and_exponent(
mantissa, exponent
),
out.map(|s| Rational::from_str(s).unwrap())
);
};
test(1.5, 1, Some("3"));
test(1.51, 1, Some("6333399/2097152"));
test(1.921875, 6, Some("123"));
test(
1.670478,
172,
Some("10000000254586612611935772707803116801852191350456320"),
);
test(2.0, 1, None);
test(10.0, 1, None);
test(0.5, 1, None);
}
fn from_sci_mantissa_and_exponent_fail_helper()
where
Rational: SciMantissaAndExponent,
for<'a> &'a Rational: SciMantissaAndExponent,
{
assert_panic!(
<&Rational as SciMantissaAndExponent>::from_sci_mantissa_and_exponent(
T::ZERO,
0
)
);
assert_panic!(
>::from_sci_mantissa_and_exponent(T::ZERO, 0)
);
}
#[test]
fn from_sci_mantissa_and_exponent_fail() {
apply_fn_to_primitive_floats!(from_sci_mantissa_and_exponent_fail_helper);
}
fn sci_mantissa_and_exponent_properties_helper()
where
Rational: SciMantissaAndExponent,
for<'a> &'a Rational: SciMantissaAndExponent,
for<'a> &'a Natural: SciMantissaAndExponent,
{
rational_gen_var_1().test_properties(|n| {
let (mantissa, exponent) = (&n).sci_mantissa_and_exponent();
assert_eq!(NiceFloat((&n).sci_mantissa()), NiceFloat(mantissa));
assert_eq!((&n).sci_exponent(), exponent);
let (mantissa_alt, exponent_alt) = n.clone().sci_mantissa_and_exponent();
assert_eq!(NiceFloat(mantissa_alt), NiceFloat(mantissa));
assert_eq!(exponent_alt, exponent);
assert_eq!(NiceFloat(n.clone().sci_mantissa()), NiceFloat(mantissa));
assert_eq!(n.clone().sci_exponent(), exponent);
assert!(mantissa >= T::ONE);
assert!(mantissa < T::TWO);
assert_eq!(
n.sci_mantissa_and_exponent_round(Nearest)
.map(|(m, e, _): (T, i64, Ordering)| (NiceFloat(m), e)),
Some((NiceFloat(mantissa), exponent))
);
});
natural_gen_var_2().test_properties(|x| {
let (mantissa_1, exponent_1) = x.sci_mantissa_and_exponent();
let (mantissa_2, exponent_2) = (&Rational::from(x)).sci_mantissa_and_exponent();
assert_eq!(NiceFloat(mantissa_1), NiceFloat(mantissa_2));
assert_eq!(i64::exact_from(exponent_1), exponent_2);
});
}
#[test]
fn sci_mantissa_and_exponent_properties() {
apply_fn_to_primitive_floats!(sci_mantissa_and_exponent_properties_helper);
}
fn sci_mantissa_and_exponent_round_properties_helper()
where
Rational: SciMantissaAndExponent,
for<'a> &'a Rational: SciMantissaAndExponent,
{
rational_rounding_mode_pair_gen_var_4().test_properties(|(n, rm)| {
let result = n.sci_mantissa_and_exponent_round_ref::(rm);
assert_eq!(
n.clone()
.sci_mantissa_and_exponent_round::(rm)
.map(|(m, e, o)| (NiceFloat(m), e, o)),
result.map(|(m, e, o)| (NiceFloat(m), e, o))
);
if let Some((mantissa, exponent, o)) = result {
assert!(mantissa >= T::ONE);
assert!(mantissa < T::TWO);
let x = <&Rational as SciMantissaAndExponent<_, _, _>>::from_sci_mantissa_and_exponent(
mantissa, exponent,
)
.unwrap();
if rm == Exact {
assert_eq!(x.partial_cmp_abs(&n), Some(Equal));
}
assert_eq!(x.partial_cmp_abs(&n), Some(o));
match rm {
Floor | Down => assert_ne!(o, Greater),
Ceiling | Up => assert_ne!(o, Less),
Exact => assert_eq!(o, Equal),
_ => {}
}
}
});
rational_gen_var_1().test_properties(|n| {
let (floor_mantissa, floor_exponent, floor_o) =
n.sci_mantissa_and_exponent_round_ref::(Floor).unwrap();
assert_eq!(
n.sci_mantissa_and_exponent_round_ref::(Down).unwrap(),
(floor_mantissa, floor_exponent, floor_o)
);
let (ceiling_mantissa, ceiling_exponent, ceiling_o) =
n.sci_mantissa_and_exponent_round_ref::(Ceiling).unwrap();
assert_eq!(
n.sci_mantissa_and_exponent_round_ref::(Up).unwrap(),
(ceiling_mantissa, ceiling_exponent, ceiling_o)
);
let (nearest_mantissa, nearest_exponent, nearest_o) =
n.sci_mantissa_and_exponent_round_ref::(Nearest).unwrap();
if let Some((mantissa, exponent, o)) = n.sci_mantissa_and_exponent_round_ref::(Exact) {
assert_eq!(o, Equal);
assert_eq!(floor_mantissa, mantissa);
assert_eq!(ceiling_mantissa, mantissa);
assert_eq!(nearest_mantissa, mantissa);
assert_eq!(floor_exponent, exponent);
assert_eq!(ceiling_exponent, exponent);
assert_eq!(nearest_exponent, exponent);
} else {
assert_eq!(floor_o, Less);
assert_eq!(ceiling_o, Greater);
assert_ne!(
(floor_mantissa, floor_exponent),
(ceiling_mantissa, ceiling_exponent)
);
assert!(
(nearest_mantissa, nearest_exponent, nearest_o)
== (floor_mantissa, floor_exponent, floor_o)
|| (nearest_mantissa, nearest_exponent, nearest_o)
== (ceiling_mantissa, ceiling_exponent, ceiling_o)
);
if ceiling_mantissa == T::ONE {
assert_eq!(floor_mantissa, T::TWO.next_lower());
assert_eq!(floor_exponent, ceiling_exponent - 1);
} else {
assert_eq!(floor_mantissa, ceiling_mantissa.next_lower());
assert_eq!(floor_exponent, ceiling_exponent);
}
}
});
natural_rounding_mode_pair_gen_var_2().test_properties(|(x, rm)| {
assert_eq!(
x.sci_mantissa_and_exponent_round(rm)
.map(|(m, e, o): (T, u64, Ordering)| (NiceFloat(m), i64::exact_from(e), o)),
Rational::from(x)
.sci_mantissa_and_exponent_round(rm)
.map(|(m, e, o)| (NiceFloat(m), e, o))
);
});
}
#[test]
fn sci_mantissa_and_exponent_round_properties() {
apply_fn_to_primitive_floats!(sci_mantissa_and_exponent_round_properties_helper);
}
fn from_sci_mantissa_and_exponent_properties_helper()
where
Rational: SciMantissaAndExponent,
for<'a> &'a Rational: SciMantissaAndExponent,
{
primitive_float_signed_pair_gen_var_1::().test_properties(|(m, e)| {
let on =
<&Rational as SciMantissaAndExponent<_, _, _>>::from_sci_mantissa_and_exponent(m, e);
assert_eq!(
>::from_sci_mantissa_and_exponent(m, e),
on
);
assert_eq!(on.is_some(), m >= T::ONE && m < T::TWO);
});
primitive_float_signed_pair_gen_var_2::().test_properties(|(m, e)| {
let x =
<&Rational as SciMantissaAndExponent<_, _, _>>::from_sci_mantissa_and_exponent(m, e)
.unwrap();
assert!(m >= T::ONE && m < T::TWO);
let (m_alt, e_alt) = (&x).sci_mantissa_and_exponent();
assert_eq!(NiceFloat(m_alt), NiceFloat(m));
assert_eq!(e_alt, e);
});
}
#[test]
fn from_sci_mantissa_and_exponent_properties() {
apply_fn_to_primitive_floats!(from_sci_mantissa_and_exponent_properties_helper);
}