use core::cmp::Ordering::{self, *};
use malachite_base::num::arithmetic::traits::{LogBase2, LogBase2Assign, PowerOf2, Reciprocal};
use malachite_base::num::basic::floats::PrimitiveFloat;
use malachite_base::num::basic::integers::PrimitiveInt;
use malachite_base::num::basic::traits::{
Infinity, NaN, NegativeInfinity, NegativeOne, NegativeZero, One, OneHalf, Two, Zero,
};
use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom};
use malachite_base::num::float::NiceFloat;
use malachite_base::num::logic::traits::SignificantBits;
use malachite_base::rounding_modes::RoundingMode::{self, *};
use malachite_base::rounding_modes::exhaustive::exhaustive_rounding_modes;
use malachite_base::test_util::generators::common::GenConfig;
use malachite_base::test_util::generators::{
primitive_float_gen, rounding_mode_gen, unsigned_gen_var_11,
unsigned_rounding_mode_pair_gen_var_3,
};
use malachite_float::arithmetic::log_base_2::{
primitive_float_log_base_2, primitive_float_log_base_2_rational,
};
use malachite_float::test_util::arithmetic::log_base_2::{
rug_log_base_2, rug_log_base_2_prec, rug_log_base_2_prec_round, rug_log_base_2_rational_prec,
rug_log_base_2_rational_prec_round, rug_log_base_2_round,
};
use malachite_float::test_util::common::{
parse_hex_string, rug_round_try_from_rounding_mode, to_hex_string,
};
use malachite_float::test_util::generators::{
float_gen, float_gen_var_12, float_rounding_mode_pair_gen_var_38,
float_rounding_mode_pair_gen_var_39, float_unsigned_pair_gen_var_1,
float_unsigned_pair_gen_var_4, float_unsigned_rounding_mode_triple_gen_var_23,
float_unsigned_rounding_mode_triple_gen_var_24,
rational_unsigned_rounding_mode_triple_gen_var_7,
};
use malachite_float::{ComparableFloat, ComparableFloatRef, Float};
use malachite_nz::platform::Limb;
use malachite_q::Rational;
use malachite_q::test_util::generators::{rational_gen, rational_unsigned_pair_gen_var_3};
use std::panic::catch_unwind;
use std::str::FromStr;
#[test]
fn test_log_base_2() {
let test = |s, s_hex, out: &str, out_hex: &str| {
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let log_base_2 = x.clone().log_base_2();
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
let log_base_2_alt = (&x).log_base_2();
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2),
ComparableFloatRef(&log_base_2_alt)
);
let mut log_base_2_alt = x.clone();
log_base_2_alt.log_base_2_assign();
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2),
ComparableFloatRef(&log_base_2_alt)
);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2(&rug::Float::exact_from(&x)))),
ComparableFloatRef(&log_base_2)
);
};
test("NaN", "NaN", "NaN", "NaN");
test("Infinity", "Infinity", "Infinity", "Infinity");
test("-Infinity", "-Infinity", "NaN", "NaN");
test("0.0", "0x0.0", "-Infinity", "-Infinity");
test("-0.0", "-0x0.0", "-Infinity", "-Infinity");
test("1.0", "0x1.0#1", "0.0", "0x0.0");
test("-1.0", "-0x1.0#1", "NaN", "NaN");
test("1.0", "0x1.0000000000000000000000000#100", "0.0", "0x0.0");
test("-1.0", "-0x1.0000000000000000000000000#100", "NaN", "NaN");
test("2.0", "0x2.0#1", "1.0", "0x1.0#1");
test("0.5", "0x0.8#1", "-1.0", "-0x1.0#1");
test("8.0", "0x8.0#1", "4.0", "0x4.0#1");
test("123.0", "0x7b.0#7", "6.94", "0x6.f#7");
test("-123.0", "-0x7b.0#7", "NaN", "NaN");
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1.6514961294723187",
"0x1.a6c873498ddf7#53",
);
test("-3.1415926535897931", "-0x3.243f6a8885a30#53", "NaN", "NaN");
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
"2.276171431827064627374502422303e-30",
"0x2.e2a8eca5705fc2eefa1ffb418E-25#100",
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
"-2.276171431827064627374502422308e-30",
"-0x2.e2a8eca5705fc2eefa1ffb420E-25#99",
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
"1.4426950408889634",
"0x1.71547652b82fe#53",
);
test("too_big", "0x4.0E+268435455#1", "1.0e9", "0x4.0E+7#1");
test("too_small", "0x1.0E-268435456#1", "-1.0e9", "-0x4.0E+7#1");
}
#[test]
fn test_log_base_2_prec() {
let test = |s, s_hex, prec: u64, out: &str, out_hex: &str, o_out: Ordering| {
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let (log_base_2, o) = x.clone().log_base_2_prec(prec);
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
assert_eq!(o, o_out);
let (log_base_2_alt, o_alt) = x.log_base_2_prec_ref(prec);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2),
ComparableFloatRef(&log_base_2_alt)
);
assert_eq!(o_alt, o);
let mut log_base_2_alt = x.clone();
let o_alt = log_base_2_alt.log_base_2_prec_assign(prec);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2),
ComparableFloatRef(&log_base_2_alt)
);
assert_eq!(o_alt, o);
let (rug_log_base_2, rug_o) = rug_log_base_2_prec(&rug::Float::exact_from(&x), prec);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
};
test("NaN", "NaN", 1, "NaN", "NaN", Equal);
test("Infinity", "Infinity", 1, "Infinity", "Infinity", Equal);
test("-Infinity", "-Infinity", 1, "NaN", "NaN", Equal);
test("0.0", "0x0.0", 1, "-Infinity", "-Infinity", Equal);
test("-0.0", "-0x0.0", 1, "-Infinity", "-Infinity", Equal);
test("1.0", "0x1.0#1", 1, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 10, "0.0", "0x0.0", Equal);
test("-1.0", "-0x1.0#1", 1, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 10, "NaN", "NaN", Equal);
test(
"1.0",
"0x1.0000000000000000000000000#100",
1,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
10,
"0.0",
"0x0.0",
Equal,
);
test("2.0", "0x2.0#1", 1, "1.0", "0x1.0#1", Equal);
test("0.5", "0x0.8#1", 1, "-1.0", "-0x1.0#1", Equal);
test("0.5", "0x0.8#1", 10, "-1.0", "-0x1.000#10", Equal);
test("8.0", "0x8.0#1", 1, "4.0", "0x4.0#1", Greater);
test("8.0", "0x8.0#1", 2, "3.0", "0x3.0#2", Equal);
test("123.0", "0x7b.0#7", 1, "8.0", "0x8.0#1", Greater);
test("123.0", "0x7b.0#7", 10, "6.945", "0x6.f2#10", Greater);
test("-123.0", "-0x7b.0#7", 1, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", 10, "NaN", "NaN", Equal);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
1,
"2.0",
"0x2.0#1",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
"1.652",
"0x1.a70#10",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
1,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
"NaN",
"NaN",
Equal,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
1,
"2.0e-30",
"0x2.0E-25#1",
Less,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
10,
"2.277e-30",
"0x2.e3E-25#10",
Greater,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
1,
"-2.0e-30",
"-0x2.0E-25#1",
Greater,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
10,
"-2.277e-30",
"-0x2.e3E-25#10",
Less,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
1,
"1.0",
"0x1.0#1",
Less,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
10,
"1.443",
"0x1.718#10",
Greater,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
1000,
"1.442695040888963330633973025111757859004911661730492706666153957426699136013312517094091\
499770864701151125538517194667712314473298294366791203412836830111218484997584382369906615\
056019456341283119154888560194586978546595239587905287284321020679486194205070157570202346\
3532938165168358726582406234612796",
"0x1.71547652b82fdbf024ffffda5e624f862a4c6d760af2e99ab795dd63b81b3d1e7d32d4382ee7c7c6f3807\
72942cbe61dec3221a245cbf1a949ac67ebd74cd1c0131dc85caee9ab6569a5cacfe962f00ecf2eccf35545708\
9729552aa51d0f89ca0488eaa5613b979a0f29e93eccab78a052a6776b441673a6cab92e622#1000",
Less,
);
}
#[test]
fn log_base_2_prec_fail() {
assert_panic!(Float::NAN.log_base_2_prec(0));
assert_panic!(Float::NAN.log_base_2_prec_ref(0));
assert_panic!({
let mut x = Float::NAN;
x.log_base_2_prec_assign(0)
});
}
#[test]
fn test_log_base_2_round() {
let test = |s, s_hex, rm, out: &str, out_hex: &str, o_out| {
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let (log_base_2, o) = x.clone().log_base_2_round(rm);
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
assert_eq!(o, o_out);
let (log_base_2_alt, o_alt) = x.log_base_2_round_ref(rm);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2),
ComparableFloatRef(&log_base_2_alt)
);
assert_eq!(o_alt, o);
let mut log_base_2_alt = x.clone();
let o_alt = log_base_2_alt.log_base_2_round_assign(rm);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2),
ComparableFloatRef(&log_base_2_alt)
);
assert_eq!(o_alt, o);
if let Ok(rug_rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_log_base_2, rug_o) = rug_log_base_2_round(&rug::Float::exact_from(&x), rug_rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
}
};
test("NaN", "NaN", Floor, "NaN", "NaN", Equal);
test("NaN", "NaN", Ceiling, "NaN", "NaN", Equal);
test("NaN", "NaN", Down, "NaN", "NaN", Equal);
test("NaN", "NaN", Up, "NaN", "NaN", Equal);
test("NaN", "NaN", Nearest, "NaN", "NaN", Equal);
test("NaN", "NaN", Exact, "NaN", "NaN", Equal);
test("Infinity", "Infinity", Floor, "Infinity", "Infinity", Equal);
test(
"Infinity", "Infinity", Ceiling, "Infinity", "Infinity", Equal,
);
test("Infinity", "Infinity", Down, "Infinity", "Infinity", Equal);
test("Infinity", "Infinity", Up, "Infinity", "Infinity", Equal);
test(
"Infinity", "Infinity", Nearest, "Infinity", "Infinity", Equal,
);
test("Infinity", "Infinity", Exact, "Infinity", "Infinity", Equal);
test("-Infinity", "-Infinity", Floor, "NaN", "NaN", Equal);
test("-Infinity", "-Infinity", Ceiling, "NaN", "NaN", Equal);
test("-Infinity", "-Infinity", Down, "NaN", "NaN", Equal);
test("-Infinity", "-Infinity", Up, "NaN", "NaN", Equal);
test("-Infinity", "-Infinity", Nearest, "NaN", "NaN", Equal);
test("-Infinity", "-Infinity", Exact, "NaN", "NaN", Equal);
test("0.0", "0x0.0", Floor, "-Infinity", "-Infinity", Equal);
test("0.0", "0x0.0", Ceiling, "-Infinity", "-Infinity", Equal);
test("0.0", "0x0.0", Down, "-Infinity", "-Infinity", Equal);
test("0.0", "0x0.0", Up, "-Infinity", "-Infinity", Equal);
test("0.0", "0x0.0", Nearest, "-Infinity", "-Infinity", Equal);
test("0.0", "0x0.0", Exact, "-Infinity", "-Infinity", Equal);
test("-0.0", "-0x0.0", Floor, "-Infinity", "-Infinity", Equal);
test("-0.0", "-0x0.0", Ceiling, "-Infinity", "-Infinity", Equal);
test("-0.0", "-0x0.0", Down, "-Infinity", "-Infinity", Equal);
test("-0.0", "-0x0.0", Up, "-Infinity", "-Infinity", Equal);
test("-0.0", "-0x0.0", Nearest, "-Infinity", "-Infinity", Equal);
test("-0.0", "-0x0.0", Exact, "-Infinity", "-Infinity", Equal);
test("1.0", "0x1.0#1", Floor, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", Ceiling, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", Down, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", Up, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", Nearest, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", Exact, "0.0", "0x0.0", Equal);
test("-1.0", "-0x1.0#1", Floor, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", Ceiling, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", Down, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", Up, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", Nearest, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", Exact, "NaN", "NaN", Equal);
test(
"1.0",
"0x1.0000000000000000000000000#100",
Floor,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
Ceiling,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
Down,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
Up,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
Nearest,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
Exact,
"0.0",
"0x0.0",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
Floor,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
Down,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
Up,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
Exact,
"NaN",
"NaN",
Equal,
);
test("2.0", "0x2.0#1", Floor, "1.0", "0x1.0#1", Equal);
test("2.0", "0x2.0#1", Ceiling, "1.0", "0x1.0#1", Equal);
test("2.0", "0x2.0#1", Down, "1.0", "0x1.0#1", Equal);
test("2.0", "0x2.0#1", Up, "1.0", "0x1.0#1", Equal);
test("2.0", "0x2.0#1", Nearest, "1.0", "0x1.0#1", Equal);
test("2.0", "0x2.0#1", Exact, "1.0", "0x1.0#1", Equal);
test("0.5", "0x0.8#1", Floor, "-1.0", "-0x1.0#1", Equal);
test("0.5", "0x0.8#1", Ceiling, "-1.0", "-0x1.0#1", Equal);
test("0.5", "0x0.8#1", Down, "-1.0", "-0x1.0#1", Equal);
test("0.5", "0x0.8#1", Up, "-1.0", "-0x1.0#1", Equal);
test("0.5", "0x0.8#1", Nearest, "-1.0", "-0x1.0#1", Equal);
test("0.5", "0x0.8#1", Exact, "-1.0", "-0x1.0#1", Equal);
test("8.0", "0x8.0#1", Floor, "2.0", "0x2.0#1", Less);
test("8.0", "0x8.0#1", Ceiling, "4.0", "0x4.0#1", Greater);
test("8.0", "0x8.0#1", Down, "2.0", "0x2.0#1", Less);
test("8.0", "0x8.0#1", Up, "4.0", "0x4.0#1", Greater);
test("8.0", "0x8.0#1", Nearest, "4.0", "0x4.0#1", Greater);
test("123.0", "0x7b.0#7", Floor, "6.94", "0x6.f#7", Less);
test("123.0", "0x7b.0#7", Ceiling, "7.0", "0x7.0#7", Greater);
test("123.0", "0x7b.0#7", Down, "6.94", "0x6.f#7", Less);
test("123.0", "0x7b.0#7", Up, "7.0", "0x7.0#7", Greater);
test("123.0", "0x7b.0#7", Nearest, "6.94", "0x6.f#7", Less);
test("-123.0", "-0x7b.0#7", Floor, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", Ceiling, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", Down, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", Up, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", Nearest, "NaN", "NaN", Equal);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Floor,
"1.6514961294723187",
"0x1.a6c873498ddf7#53",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Ceiling,
"1.6514961294723189",
"0x1.a6c873498ddf8#53",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Down,
"1.6514961294723187",
"0x1.a6c873498ddf7#53",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Up,
"1.6514961294723189",
"0x1.a6c873498ddf8#53",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Nearest,
"1.6514961294723187",
"0x1.a6c873498ddf7#53",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Floor,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Down,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Up,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"too_big",
"0x4.0E+268435455#1",
Nearest,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test(
"too_big",
"0x6.0E+268435455#2",
Nearest,
"1.0e9",
"0x4.0E+7#2",
Greater,
);
test(
"too_small",
"0x1.0E-268435456#1",
Nearest,
"-1.0e9",
"-0x4.0E+7#1",
Equal,
);
test(
"too_small",
"0x1.0E-268435456#2",
Nearest,
"-1.0e9",
"-0x4.0E+7#2",
Equal,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
Floor,
"2.276171431827064627374502422301e-30",
"0x2.e2a8eca5705fc2eefa1ffb414E-25#100",
Less,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
Ceiling,
"2.276171431827064627374502422303e-30",
"0x2.e2a8eca5705fc2eefa1ffb418E-25#100",
Greater,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
Down,
"2.276171431827064627374502422301e-30",
"0x2.e2a8eca5705fc2eefa1ffb414E-25#100",
Less,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
Up,
"2.276171431827064627374502422303e-30",
"0x2.e2a8eca5705fc2eefa1ffb418E-25#100",
Greater,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
Nearest,
"2.276171431827064627374502422303e-30",
"0x2.e2a8eca5705fc2eefa1ffb418E-25#100",
Greater,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
Floor,
"-2.276171431827064627374502422308e-30",
"-0x2.e2a8eca5705fc2eefa1ffb420E-25#99",
Less,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
Ceiling,
"-2.276171431827064627374502422303e-30",
"-0x2.e2a8eca5705fc2eefa1ffb418E-25#99",
Greater,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
Down,
"-2.276171431827064627374502422303e-30",
"-0x2.e2a8eca5705fc2eefa1ffb418E-25#99",
Greater,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
Up,
"-2.276171431827064627374502422308e-30",
"-0x2.e2a8eca5705fc2eefa1ffb420E-25#99",
Less,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
Nearest,
"-2.276171431827064627374502422308e-30",
"-0x2.e2a8eca5705fc2eefa1ffb420E-25#99",
Less,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
Floor,
"1.4426950408889632",
"0x1.71547652b82fd#53",
Less,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
Ceiling,
"1.4426950408889634",
"0x1.71547652b82fe#53",
Greater,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
Down,
"1.4426950408889632",
"0x1.71547652b82fd#53",
Less,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
Up,
"1.4426950408889634",
"0x1.71547652b82fe#53",
Greater,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
Nearest,
"1.4426950408889634",
"0x1.71547652b82fe#53",
Greater,
);
}
#[test]
fn log_base_2_round_fail() {
const THREE: Float = Float::const_from_unsigned(3);
assert_panic!(THREE.log_base_2_round(Exact));
assert_panic!(THREE.log_base_2_round_ref(Exact));
assert_panic!({
let mut x = THREE;
x.log_base_2_round_assign(Exact);
});
}
#[test]
fn test_log_base_2_prec_round() {
let test = |s, s_hex, prec: u64, rm, out: &str, out_hex: &str, o_out: Ordering| {
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let (log_base_2, o) = x.clone().log_base_2_prec_round(prec, rm);
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
assert_eq!(o, o_out);
let (log_base_2_alt, o_alt) = x.log_base_2_prec_round_ref(prec, rm);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2),
ComparableFloatRef(&log_base_2_alt)
);
assert_eq!(o_alt, o);
let mut log_base_2_alt = x.clone();
let o_alt = log_base_2_alt.log_base_2_prec_round_assign(prec, rm);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2),
ComparableFloatRef(&log_base_2_alt)
);
assert_eq!(o_alt, o);
if let Ok(rug_rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_log_base_2, rug_o) =
rug_log_base_2_prec_round(&rug::Float::exact_from(&x), prec, rug_rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
}
};
test("NaN", "NaN", 1, Floor, "NaN", "NaN", Equal);
test("NaN", "NaN", 1, Ceiling, "NaN", "NaN", Equal);
test("NaN", "NaN", 1, Down, "NaN", "NaN", Equal);
test("NaN", "NaN", 1, Up, "NaN", "NaN", Equal);
test("NaN", "NaN", 1, Nearest, "NaN", "NaN", Equal);
test("NaN", "NaN", 1, Exact, "NaN", "NaN", Equal);
test(
"Infinity", "Infinity", 1, Floor, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", 1, Ceiling, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", 1, Down, "Infinity", "Infinity", Equal,
);
test("Infinity", "Infinity", 1, Up, "Infinity", "Infinity", Equal);
test(
"Infinity", "Infinity", 1, Nearest, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", 1, Exact, "Infinity", "Infinity", Equal,
);
test("-Infinity", "-Infinity", 1, Floor, "NaN", "NaN", Equal);
test("-Infinity", "-Infinity", 1, Ceiling, "NaN", "NaN", Equal);
test("-Infinity", "-Infinity", 1, Down, "NaN", "NaN", Equal);
test("-Infinity", "-Infinity", 1, Up, "NaN", "NaN", Equal);
test("-Infinity", "-Infinity", 1, Nearest, "NaN", "NaN", Equal);
test("-Infinity", "-Infinity", 1, Exact, "NaN", "NaN", Equal);
test("0.0", "0x0.0", 1, Floor, "-Infinity", "-Infinity", Equal);
test("0.0", "0x0.0", 1, Ceiling, "-Infinity", "-Infinity", Equal);
test("0.0", "0x0.0", 1, Down, "-Infinity", "-Infinity", Equal);
test("0.0", "0x0.0", 1, Up, "-Infinity", "-Infinity", Equal);
test("0.0", "0x0.0", 1, Nearest, "-Infinity", "-Infinity", Equal);
test("0.0", "0x0.0", 1, Exact, "-Infinity", "-Infinity", Equal);
test("-0.0", "-0x0.0", 1, Floor, "-Infinity", "-Infinity", Equal);
test(
"-0.0",
"-0x0.0",
1,
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test("-0.0", "-0x0.0", 1, Down, "-Infinity", "-Infinity", Equal);
test("-0.0", "-0x0.0", 1, Up, "-Infinity", "-Infinity", Equal);
test(
"-0.0",
"-0x0.0",
1,
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test("-0.0", "-0x0.0", 1, Exact, "-Infinity", "-Infinity", Equal);
test("1.0", "0x1.0#1", 1, Floor, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 1, Ceiling, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 1, Down, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 1, Up, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 1, Nearest, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 1, Exact, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 10, Floor, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 10, Ceiling, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 10, Down, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 10, Up, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 10, Nearest, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", 10, Exact, "0.0", "0x0.0", Equal);
test("-1.0", "-0x1.0#1", 1, Floor, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 1, Ceiling, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 1, Down, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 1, Up, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 1, Nearest, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 1, Exact, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 10, Floor, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 10, Ceiling, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 10, Down, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 10, Up, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 10, Nearest, "NaN", "NaN", Equal);
test("-1.0", "-0x1.0#1", 10, Exact, "NaN", "NaN", Equal);
test(
"1.0",
"0x1.0000000000000000000000000#100",
1,
Floor,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
1,
Ceiling,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
1,
Down,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
1,
Up,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
1,
Nearest,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
1,
Exact,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
10,
Floor,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
10,
Ceiling,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
10,
Down,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
10,
Up,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
10,
Nearest,
"0.0",
"0x0.0",
Equal,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
10,
Exact,
"0.0",
"0x0.0",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
1,
Floor,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
1,
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
1,
Down,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
1,
Up,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
1,
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
1,
Exact,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
10,
Floor,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
10,
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
10,
Down,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
10,
Up,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
10,
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"-1.0",
"-0x1.0000000000000000000000000#100",
10,
Exact,
"NaN",
"NaN",
Equal,
);
test("2.0", "0x2.0#1", 1, Floor, "1.0", "0x1.0#1", Equal);
test("2.0", "0x2.0#1", 1, Ceiling, "1.0", "0x1.0#1", Equal);
test("2.0", "0x2.0#1", 1, Down, "1.0", "0x1.0#1", Equal);
test("2.0", "0x2.0#1", 1, Up, "1.0", "0x1.0#1", Equal);
test("2.0", "0x2.0#1", 1, Nearest, "1.0", "0x1.0#1", Equal);
test("2.0", "0x2.0#1", 1, Exact, "1.0", "0x1.0#1", Equal);
test("0.5", "0x0.8#1", 1, Floor, "-1.0", "-0x1.0#1", Equal);
test("0.5", "0x0.8#1", 1, Ceiling, "-1.0", "-0x1.0#1", Equal);
test("0.5", "0x0.8#1", 1, Down, "-1.0", "-0x1.0#1", Equal);
test("0.5", "0x0.8#1", 1, Up, "-1.0", "-0x1.0#1", Equal);
test("0.5", "0x0.8#1", 1, Nearest, "-1.0", "-0x1.0#1", Equal);
test("0.5", "0x0.8#1", 1, Exact, "-1.0", "-0x1.0#1", Equal);
test("8.0", "0x8.0#1", 1, Floor, "2.0", "0x2.0#1", Less);
test("8.0", "0x8.0#1", 1, Ceiling, "4.0", "0x4.0#1", Greater);
test("8.0", "0x8.0#1", 1, Down, "2.0", "0x2.0#1", Less);
test("8.0", "0x8.0#1", 1, Up, "4.0", "0x4.0#1", Greater);
test("8.0", "0x8.0#1", 1, Nearest, "4.0", "0x4.0#1", Greater);
test("8.0", "0x8.0#1", 2, Floor, "3.0", "0x3.0#2", Equal);
test("8.0", "0x8.0#1", 2, Ceiling, "3.0", "0x3.0#2", Equal);
test("8.0", "0x8.0#1", 2, Down, "3.0", "0x3.0#2", Equal);
test("8.0", "0x8.0#1", 2, Up, "3.0", "0x3.0#2", Equal);
test("8.0", "0x8.0#1", 2, Nearest, "3.0", "0x3.0#2", Equal);
test("8.0", "0x8.0#1", 2, Exact, "3.0", "0x3.0#2", Equal);
test("123.0", "0x7b.0#7", 1, Floor, "4.0", "0x4.0#1", Less);
test("123.0", "0x7b.0#7", 1, Ceiling, "8.0", "0x8.0#1", Greater);
test("123.0", "0x7b.0#7", 1, Down, "4.0", "0x4.0#1", Less);
test("123.0", "0x7b.0#7", 1, Up, "8.0", "0x8.0#1", Greater);
test("123.0", "0x7b.0#7", 1, Nearest, "8.0", "0x8.0#1", Greater);
test("123.0", "0x7b.0#7", 10, Floor, "6.94", "0x6.f0#10", Less);
test(
"123.0",
"0x7b.0#7",
10,
Ceiling,
"6.945",
"0x6.f2#10",
Greater,
);
test("123.0", "0x7b.0#7", 10, Down, "6.94", "0x6.f0#10", Less);
test("123.0", "0x7b.0#7", 10, Up, "6.945", "0x6.f2#10", Greater);
test(
"123.0",
"0x7b.0#7",
10,
Nearest,
"6.945",
"0x6.f2#10",
Greater,
);
test("-123.0", "-0x7b.0#7", 1, Floor, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", 1, Ceiling, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", 1, Down, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", 1, Up, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", 1, Nearest, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", 10, Floor, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", 10, Ceiling, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", 10, Down, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", 10, Up, "NaN", "NaN", Equal);
test("-123.0", "-0x7b.0#7", 10, Nearest, "NaN", "NaN", Equal);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
1,
Floor,
"1.0",
"0x1.0#1",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
1,
Ceiling,
"2.0",
"0x2.0#1",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
1,
Down,
"1.0",
"0x1.0#1",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
1,
Up,
"2.0",
"0x2.0#1",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
1,
Nearest,
"2.0",
"0x2.0#1",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Floor,
"1.65",
"0x1.a68#10",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Ceiling,
"1.652",
"0x1.a70#10",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Down,
"1.65",
"0x1.a68#10",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Up,
"1.652",
"0x1.a70#10",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Nearest,
"1.652",
"0x1.a70#10",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
1,
Floor,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
1,
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
1,
Down,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
1,
Up,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
1,
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Floor,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Down,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Up,
"NaN",
"NaN",
Equal,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
1,
Floor,
"2.0e-30",
"0x2.0E-25#1",
Less,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
10,
Floor,
"2.274e-30",
"0x2.e2E-25#10",
Less,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
1,
Ceiling,
"3.0e-30",
"0x4.0E-25#1",
Greater,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
10,
Ceiling,
"2.277e-30",
"0x2.e3E-25#10",
Greater,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
1,
Down,
"2.0e-30",
"0x2.0E-25#1",
Less,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
10,
Down,
"2.274e-30",
"0x2.e2E-25#10",
Less,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
1,
Up,
"3.0e-30",
"0x4.0E-25#1",
Greater,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
10,
Up,
"2.277e-30",
"0x2.e3E-25#10",
Greater,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
1,
Nearest,
"2.0e-30",
"0x2.0E-25#1",
Less,
);
test(
"1.000000000000000000000000000002",
"0x1.0000000000000000000000002#100",
10,
Nearest,
"2.277e-30",
"0x2.e3E-25#10",
Greater,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
1,
Floor,
"-3.0e-30",
"-0x4.0E-25#1",
Less,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
10,
Floor,
"-2.277e-30",
"-0x2.e3E-25#10",
Less,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
1,
Ceiling,
"-2.0e-30",
"-0x2.0E-25#1",
Greater,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
10,
Ceiling,
"-2.274e-30",
"-0x2.e2E-25#10",
Greater,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
1,
Down,
"-2.0e-30",
"-0x2.0E-25#1",
Greater,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
10,
Down,
"-2.274e-30",
"-0x2.e2E-25#10",
Greater,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
1,
Up,
"-3.0e-30",
"-0x4.0E-25#1",
Less,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
10,
Up,
"-2.277e-30",
"-0x2.e3E-25#10",
Less,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
1,
Nearest,
"-2.0e-30",
"-0x2.0E-25#1",
Greater,
);
test(
"0.999999999999999999999999999998",
"0x0.ffffffffffffffffffffffffe#99",
10,
Nearest,
"-2.277e-30",
"-0x2.e3E-25#10",
Less,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
1,
Floor,
"1.0",
"0x1.0#1",
Less,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
10,
Floor,
"1.441",
"0x1.710#10",
Less,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
1,
Ceiling,
"2.0",
"0x2.0#1",
Greater,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
10,
Ceiling,
"1.443",
"0x1.718#10",
Greater,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
1,
Down,
"1.0",
"0x1.0#1",
Less,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
10,
Down,
"1.441",
"0x1.710#10",
Less,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
1,
Up,
"2.0",
"0x2.0#1",
Greater,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
10,
Up,
"1.443",
"0x1.718#10",
Greater,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
1,
Nearest,
"1.0",
"0x1.0#1",
Less,
);
test(
"2.7182818284590451",
"0x2.b7e151628aed2#53",
10,
Nearest,
"1.443",
"0x1.718#10",
Greater,
);
}
#[test]
fn log_base_2_prec_round_fail() {
const THREE: Float = Float::const_from_unsigned(3);
assert_panic!(Float::one_prec(1).log_base_2_prec_round(0, Floor));
assert_panic!(Float::one_prec(1).log_base_2_prec_round_ref(0, Floor));
assert_panic!({
let mut x = Float::one_prec(1);
x.log_base_2_prec_round_assign(0, Floor)
});
assert_panic!(THREE.log_base_2_prec_round(1, Exact));
assert_panic!(THREE.log_base_2_prec_round_ref(1, Exact));
assert_panic!({
let mut x = THREE;
x.log_base_2_prec_round_assign(1, Exact)
});
}
fn rational_cross_check_cheap(x: &Float) -> bool {
x.get_exponent().is_some_and(|e| e.unsigned_abs() < 1 << 16)
}
#[allow(clippy::needless_pass_by_value)]
fn log_base_2_prec_round_properties_helper(x: Float, prec: u64, rm: RoundingMode) {
let (log_base_2, o) = x.clone().log_base_2_prec_round(prec, rm);
assert!(log_base_2.is_valid());
let (log_base_2_alt, o_alt) = x.log_base_2_prec_round_ref(prec, rm);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.log_base_2_prec_round_assign(prec, rm);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&log_base_2));
assert_eq!(o_alt, o);
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_log_base_2, rug_o) =
rug_log_base_2_prec_round(&rug::Float::exact_from(&x), prec, rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
}
if x.is_finite() && x != 0u32 && rational_cross_check_cheap(&x) {
let (log_base_2_alt, o_alt) =
Float::log_base_2_rational_prec_round_ref(&Rational::exact_from(&x), prec, rm);
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
assert_eq!(o_alt, o);
}
if x < 0u32 {
assert!(log_base_2.is_nan());
}
if log_base_2.is_normal() {
let e = i64::from(x.get_exponent().unwrap());
if o != Greater {
assert!(log_base_2 < e);
}
if o != Less {
assert!(log_base_2 >= e - 1);
}
}
if log_base_2.is_normal() {
assert_eq!(log_base_2.get_prec(), Some(prec));
if x > 1u32 && o > Less {
assert!(log_base_2 > 0u32);
} else if x > 0u32 && x < 1u32 && o < Greater {
assert!(log_base_2 < 0u32);
}
}
if o == Equal {
for rm in exhaustive_rounding_modes() {
let (s, oo) = x.log_base_2_prec_round_ref(prec, rm);
assert_eq!(
ComparableFloat(s.abs_negative_zero_ref()),
ComparableFloat(log_base_2.abs_negative_zero_ref())
);
assert_eq!(oo, Equal);
}
} else {
assert_panic!(x.log_base_2_prec_round_ref(prec, Exact));
}
}
#[test]
fn log_base_2_prec_round_properties() {
float_unsigned_rounding_mode_triple_gen_var_23().test_properties(|(x, prec, rm)| {
log_base_2_prec_round_properties_helper(x, prec, rm);
});
float_unsigned_rounding_mode_triple_gen_var_24().test_properties(|(x, prec, rm)| {
log_base_2_prec_round_properties_helper(x, prec, rm);
});
unsigned_rounding_mode_pair_gen_var_3().test_properties(|(prec, rm)| {
let (log_base_2, o) = Float::NAN.log_base_2_prec_round(prec, rm);
assert!(log_base_2.is_nan());
assert_eq!(o, Equal);
assert_eq!(
Float::INFINITY.log_base_2_prec_round(prec, rm),
(Float::INFINITY, Equal)
);
let (log_base_2, o) = Float::NEGATIVE_INFINITY.log_base_2_prec_round(prec, rm);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::NAN));
assert_eq!(o, Equal);
assert_eq!(
Float::ZERO.log_base_2_prec_round(prec, rm),
(Float::NEGATIVE_INFINITY, Equal)
);
assert_eq!(
Float::NEGATIVE_ZERO.log_base_2_prec_round(prec, rm),
(Float::NEGATIVE_INFINITY, Equal)
);
let (log_base_2, o) = Float::ONE.log_base_2_prec_round(prec, rm);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::ZERO));
assert_eq!(o, Equal);
let (log_base_2, o) = Float::NEGATIVE_ONE.log_base_2_prec_round(prec, rm);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::NAN));
assert_eq!(o, Equal);
});
}
#[allow(clippy::needless_pass_by_value)]
fn log_base_2_prec_properties_helper(x: Float, prec: u64) {
let (log_base_2, o) = x.clone().log_base_2_prec(prec);
assert!(log_base_2.is_valid());
let (log_base_2_alt, o_alt) = x.log_base_2_prec_ref(prec);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.log_base_2_prec_assign(prec);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&log_base_2));
assert_eq!(o_alt, o);
let (rug_log_base_2, rug_o) = rug_log_base_2_prec(&rug::Float::exact_from(&x), prec);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
let (log_base_2_alt, o_alt) = x.log_base_2_prec_round_ref(prec, Nearest);
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
assert_eq!(o_alt, o);
if x.is_finite() && x != 0u32 && rational_cross_check_cheap(&x) {
let (log_base_2_alt, o_alt) =
Float::log_base_2_rational_prec_ref(&Rational::exact_from(&x), prec);
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
assert_eq!(o_alt, o);
}
if x < 0u32 {
assert!(log_base_2.is_nan());
}
if log_base_2.is_normal() {
let e = i64::from(x.get_exponent().unwrap());
if o != Greater {
assert!(log_base_2 < e);
}
if o != Less {
assert!(log_base_2 >= e - 1);
}
}
if log_base_2.is_normal() {
assert_eq!(log_base_2.get_prec(), Some(prec));
if x > 1u32 && o > Less {
assert!(log_base_2 > 0u32);
} else if x > 0u32 && x < 1u32 && o < Greater {
assert!(log_base_2 < 0u32);
}
}
}
#[test]
fn log_base_2_prec_properties() {
float_unsigned_pair_gen_var_1().test_properties(|(x, prec)| {
log_base_2_prec_properties_helper(x, prec);
});
let mut config = GenConfig::new();
config.insert("mean_precision_n", 2048);
config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH);
float_unsigned_pair_gen_var_1().test_properties_with_config(&config, |(x, prec)| {
log_base_2_prec_properties_helper(x, prec);
});
float_unsigned_pair_gen_var_4().test_properties(|(x, prec)| {
log_base_2_prec_properties_helper(x, prec);
});
unsigned_gen_var_11().test_properties(|prec| {
let (log_base_2, o) = Float::NAN.log_base_2_prec(prec);
assert!(log_base_2.is_nan());
assert_eq!(o, Equal);
assert_eq!(
Float::ZERO.log_base_2_prec(prec),
(Float::NEGATIVE_INFINITY, Equal)
);
assert_eq!(
Float::NEGATIVE_ZERO.log_base_2_prec(prec),
(Float::NEGATIVE_INFINITY, Equal)
);
assert_eq!(
Float::INFINITY.log_base_2_prec(prec),
(Float::INFINITY, Equal)
);
let (log_base_2, o) = Float::NEGATIVE_INFINITY.log_base_2_prec(prec);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::NAN));
assert_eq!(o, Equal);
let (log_base_2, o) = Float::ONE.log_base_2_prec(prec);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::ZERO));
assert_eq!(o, Equal);
let (log_base_2, o) = Float::NEGATIVE_ONE.log_base_2_prec(prec);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::NAN));
assert_eq!(o, Equal);
});
}
#[allow(clippy::needless_pass_by_value)]
fn log_base_2_round_properties_helper(x: Float, rm: RoundingMode) {
let (log_base_2, o) = x.clone().log_base_2_round(rm);
assert!(log_base_2.is_valid());
let (log_base_2_alt, o_alt) = x.log_base_2_round_ref(rm);
assert!(log_base_2_alt.is_valid());
assert_eq!(o_alt, o);
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
let mut x_alt = x.clone();
let o_alt = x_alt.log_base_2_round_assign(rm);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&log_base_2));
assert_eq!(o_alt, o);
let (log_base_2_alt, o_alt) = x.log_base_2_prec_round_ref(x.significant_bits(), rm);
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
assert_eq!(o_alt, o);
if x < 0u32 {
assert!(log_base_2.is_nan());
}
if log_base_2.is_normal() {
let e = i64::from(x.get_exponent().unwrap());
if o != Greater {
assert!(log_base_2 < e);
}
if o != Less {
assert!(log_base_2 >= e - 1);
}
}
if log_base_2.is_normal() {
assert_eq!(log_base_2.get_prec(), Some(x.get_prec().unwrap()));
if x > 1u32 && o > Less {
assert!(log_base_2 > 0u32);
} else if x > 0u32 && x < 1u32 && o < Greater {
assert!(log_base_2 < 0u32);
}
}
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_log_base_2, rug_o) = rug_log_base_2_round(&rug::Float::exact_from(&x), rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
}
if o == Equal {
for rm in exhaustive_rounding_modes() {
let (s, oo) = x.log_base_2_round_ref(rm);
assert_eq!(
ComparableFloat(s.abs_negative_zero_ref()),
ComparableFloat(log_base_2.abs_negative_zero_ref())
);
assert_eq!(oo, Equal);
}
} else {
assert_panic!(x.log_base_2_round_ref(Exact));
}
}
#[test]
fn log_base_2_round_properties() {
float_rounding_mode_pair_gen_var_38().test_properties(|(x, rm)| {
log_base_2_round_properties_helper(x, rm);
});
float_rounding_mode_pair_gen_var_39().test_properties(|(x, rm)| {
log_base_2_round_properties_helper(x, rm);
});
rounding_mode_gen().test_properties(|rm| {
let (log_base_2, o) = Float::NAN.log_base_2_round(rm);
assert!(log_base_2.is_nan());
assert_eq!(o, Equal);
assert_eq!(
Float::ZERO.log_base_2_round(rm),
(Float::NEGATIVE_INFINITY, Equal)
);
assert_eq!(
Float::NEGATIVE_ZERO.log_base_2_round(rm),
(Float::NEGATIVE_INFINITY, Equal)
);
assert_eq!(
Float::INFINITY.log_base_2_round(rm),
(Float::INFINITY, Equal)
);
let (log_base_2, o) = Float::NEGATIVE_INFINITY.log_base_2_round(rm);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::NAN));
assert_eq!(o, Equal);
let (log_base_2, o) = Float::ONE.log_base_2_round(rm);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::ZERO));
assert_eq!(o, Equal);
let (log_base_2, o) = Float::NEGATIVE_ONE.log_base_2_round(rm);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::NAN));
assert_eq!(o, Equal);
});
}
#[allow(clippy::needless_pass_by_value)]
fn log_base_2_properties_helper(x: Float) {
let log_base_2 = x.clone().log_base_2();
assert!(log_base_2.is_valid());
let log_base_2_alt = (&x).log_base_2();
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
let mut x_alt = x.clone();
x_alt.log_base_2_assign();
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&log_base_2));
let log_base_2_alt = x.log_base_2_prec_round_ref(x.significant_bits(), Nearest).0;
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
let log_base_2_alt = x.log_base_2_prec_ref(x.significant_bits()).0;
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
let (log_base_2_alt, o) = x.log_base_2_round_ref(Nearest);
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
if x < 0u32 {
assert!(log_base_2.is_nan());
}
if log_base_2.is_normal() {
let e = i64::from(x.get_exponent().unwrap());
if o != Greater {
assert!(log_base_2 < e);
}
if o != Less {
assert!(log_base_2 >= e - 1);
}
}
let rug_log_base_2 = rug_log_base_2(&rug::Float::exact_from(&x));
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
}
#[test]
fn log_base_2_properties() {
float_gen().test_properties(|x| {
log_base_2_properties_helper(x);
});
float_gen_var_12().test_properties(|x| {
log_base_2_properties_helper(x);
});
}
#[test]
fn log_base_2_rational_prec_fail() {
assert_panic!(Float::log_base_2_rational_prec(Rational::ZERO, 0));
assert_panic!(Float::log_base_2_rational_prec(Rational::ONE, 0));
assert_panic!(Float::log_base_2_rational_prec(Rational::NEGATIVE_ONE, 0));
}
#[test]
fn log_base_2_rational_prec_ref_fail() {
assert_panic!(Float::log_base_2_rational_prec_ref(&Rational::ZERO, 0));
assert_panic!(Float::log_base_2_rational_prec_ref(&Rational::ONE, 0));
assert_panic!(Float::log_base_2_rational_prec_ref(
&Rational::NEGATIVE_ONE,
0
));
}
#[test]
fn log_base_2_rational_prec_round_fail() {
assert_panic!(Float::log_base_2_rational_prec_round(
Rational::ZERO,
0,
Floor
));
assert_panic!(Float::log_base_2_rational_prec_round(
Rational::ONE,
0,
Floor
));
assert_panic!(Float::log_base_2_rational_prec_round(
Rational::NEGATIVE_ONE,
0,
Floor
));
assert_panic!(Float::log_base_2_rational_prec_round(
Rational::from(123u32),
1,
Exact
));
assert_panic!(Float::log_base_2_rational_prec_round(
Rational::from_unsigneds(22u8, 7),
100,
Exact
));
assert_panic!(Float::log_base_2_rational_prec_round(
Rational::power_of_2(5i64),
1,
Exact
));
}
#[test]
fn log_base_2_rational_prec_round_ref_fail() {
assert_panic!(Float::log_base_2_rational_prec_round_ref(
&Rational::ZERO,
0,
Floor
));
assert_panic!(Float::log_base_2_rational_prec_round_ref(
&Rational::ONE,
0,
Floor
));
assert_panic!(Float::log_base_2_rational_prec_round_ref(
&Rational::NEGATIVE_ONE,
0,
Floor
));
assert_panic!(Float::log_base_2_rational_prec_round_ref(
&Rational::from(123u32),
1,
Exact
));
assert_panic!(Float::log_base_2_rational_prec_round_ref(
&Rational::from_unsigneds(22u8, 7),
100,
Exact
));
assert_panic!(Float::log_base_2_rational_prec_round_ref(
&Rational::power_of_2(5i64),
1,
Exact
));
}
#[allow(clippy::needless_pass_by_value)]
fn log_base_2_rational_prec_round_properties_helper(x: Rational, prec: u64, rm: RoundingMode) {
let (log_base_2, o) = Float::log_base_2_rational_prec_round(x.clone(), prec, rm);
assert!(log_base_2.is_valid());
let (log_base_2_alt, o_alt) = Float::log_base_2_rational_prec_round_ref(&x, prec, rm);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
assert_eq!(o_alt, o);
if let Ok(rug_rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_log_base_2, rug_o) = rug_log_base_2_rational_prec_round(&x, prec, rug_rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
}
if x != 0u32 {
let (log_base_2_alt, o_alt) =
Float::log_base_2_rational_prec_round((&x).reciprocal(), prec, -rm);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&(-log_base_2_alt).abs_negative_zero()),
ComparableFloatRef(&log_base_2.abs_negative_zero_ref())
);
assert_eq!(o_alt.reverse(), o);
}
if log_base_2.is_normal() {
assert_eq!(log_base_2.get_prec(), Some(prec));
if x > 1u32 && o > Less {
assert!(log_base_2 > 0u32);
} else if x < 1u32 && o < Greater {
assert!(log_base_2 < 0u32);
}
let e = x.floor_log_base_2_abs();
if o != Greater {
assert!(log_base_2 < e + 1);
}
if o != Less {
assert!(log_base_2 >= e);
}
}
if o == Equal {
for rm in exhaustive_rounding_modes() {
let (s, oo) = Float::log_base_2_rational_prec_round_ref(&x, prec, rm);
assert_eq!(
ComparableFloat(s.abs_negative_zero_ref()),
ComparableFloat(log_base_2.abs_negative_zero_ref())
);
assert_eq!(oo, Equal);
}
} else {
assert_panic!(Float::log_base_2_rational_prec_round_ref(&x, prec, Exact));
}
}
#[test]
fn log_base_2_rational_prec_round_properties() {
rational_unsigned_rounding_mode_triple_gen_var_7().test_properties(|(x, prec, rm)| {
log_base_2_rational_prec_round_properties_helper(x, prec, rm);
});
let mut config = GenConfig::new();
config.insert("mean_bits_n", 2048);
config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH);
rational_unsigned_rounding_mode_triple_gen_var_7().test_properties_with_config(
&config,
|(x, prec, rm)| {
log_base_2_rational_prec_round_properties_helper(x, prec, rm);
},
);
unsigned_rounding_mode_pair_gen_var_3().test_properties(|(prec, rm)| {
assert_eq!(
Float::log_base_2_rational_prec_round(Rational::ZERO, prec, rm),
(Float::NEGATIVE_INFINITY, Equal)
);
let (log_base_2, o) = Float::log_base_2_rational_prec_round(Rational::ONE, prec, rm);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::ZERO));
assert_eq!(o, Equal);
let (log_base_2, o) =
Float::log_base_2_rational_prec_round(Rational::NEGATIVE_ONE, prec, rm);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::NAN));
assert_eq!(o, Equal);
let (log_base_2, o) = Float::log_base_2_rational_prec_round(Rational::TWO, prec, rm);
assert_eq!(log_base_2, 1);
assert_eq!(o, Equal);
let (log_base_2, o) = Float::log_base_2_rational_prec_round(Rational::ONE_HALF, prec, rm);
assert_eq!(log_base_2, -1);
assert_eq!(o, Equal);
});
}
#[allow(clippy::needless_pass_by_value)]
fn log_base_2_rational_prec_properties_helper(x: Rational, prec: u64) {
let (log_base_2, o) = Float::log_base_2_rational_prec(x.clone(), prec);
assert!(log_base_2.is_valid());
let (log_base_2_alt, o_alt) = Float::log_base_2_rational_prec_ref(&x, prec);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
assert_eq!(o_alt, o);
let (log_base_2_alt, o_alt) = Float::log_base_2_rational_prec_round_ref(&x, prec, Nearest);
assert_eq!(
ComparableFloatRef(&log_base_2_alt),
ComparableFloatRef(&log_base_2)
);
assert_eq!(o_alt, o);
let (rug_log_base_2, rug_o) = rug_log_base_2_rational_prec(&x, prec);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
if x != 0u32 {
let (log_base_2_alt, o_alt) = Float::log_base_2_rational_prec((&x).reciprocal(), prec);
assert!(log_base_2_alt.is_valid());
assert_eq!(
ComparableFloatRef(&(-log_base_2_alt).abs_negative_zero()),
ComparableFloatRef(&log_base_2.abs_negative_zero_ref())
);
assert_eq!(o_alt.reverse(), o);
}
if log_base_2.is_normal() {
assert_eq!(log_base_2.get_prec(), Some(prec));
if x > 1u32 && o > Less {
assert!(log_base_2 > 0u32);
} else if x < 1u32 && o < Greater {
assert!(log_base_2 < 0u32);
}
let e = x.floor_log_base_2_abs();
if o != Greater {
assert!(log_base_2 < e + 1);
}
if o != Less {
assert!(log_base_2 >= e);
}
}
}
#[test]
fn log_base_2_rational_prec_properties() {
rational_unsigned_pair_gen_var_3().test_properties(|(x, prec)| {
log_base_2_rational_prec_properties_helper(x, prec);
});
let mut config = GenConfig::new();
config.insert("mean_bits_n", 2048);
config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH);
rational_unsigned_pair_gen_var_3().test_properties_with_config(&config, |(x, prec)| {
log_base_2_rational_prec_properties_helper(x, prec);
});
unsigned_gen_var_11().test_properties(|prec| {
assert_eq!(
Float::log_base_2_rational_prec(Rational::ZERO, prec),
(Float::NEGATIVE_INFINITY, Equal)
);
let (log_base_2, o) = Float::log_base_2_rational_prec(Rational::ONE, prec);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::ZERO));
assert_eq!(o, Equal);
let (log_base_2, o) = Float::log_base_2_rational_prec(Rational::NEGATIVE_ONE, prec);
assert_eq!(ComparableFloat(log_base_2), ComparableFloat(Float::NAN));
assert_eq!(o, Equal);
let (log_base_2, o) = Float::log_base_2_rational_prec(Rational::TWO, prec);
assert_eq!(log_base_2, 1);
assert_eq!(o, Equal);
let (log_base_2, o) = Float::log_base_2_rational_prec(Rational::ONE_HALF, prec);
assert_eq!(log_base_2, -1);
assert_eq!(o, Equal);
});
}
#[test]
fn test_log_base_2_rational_prec() {
let test = |s, prec, out, out_hex, out_o| {
let u = Rational::from_str(s).unwrap();
let (log_base_2, o) = Float::log_base_2_rational_prec(u.clone(), prec);
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
assert_eq!(o, out_o);
let (log_base_2, o) = Float::log_base_2_rational_prec_ref(&u, prec);
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
assert_eq!(o, out_o);
let (rug_log_base_2, rug_o) = rug_log_base_2_rational_prec(&u, prec);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
};
test("0", 1, "-Infinity", "-Infinity", Equal);
test("0", 10, "-Infinity", "-Infinity", Equal);
test("0", 100, "-Infinity", "-Infinity", Equal);
test("1", 1, "0.0", "0x0.0", Equal);
test("1", 10, "0.0", "0x0.0", Equal);
test("1", 100, "0.0", "0x0.0", Equal);
test("-1", 1, "NaN", "NaN", Equal);
test("-1", 10, "NaN", "NaN", Equal);
test("-1", 100, "NaN", "NaN", Equal);
test("-1/2", 1, "NaN", "NaN", Equal);
test("-1/2", 10, "NaN", "NaN", Equal);
test("-1/2", 100, "NaN", "NaN", Equal);
test("-22/7", 1, "NaN", "NaN", Equal);
test("-22/7", 10, "NaN", "NaN", Equal);
test("-22/7", 100, "NaN", "NaN", Equal);
test("2", 1, "1.0", "0x1.0#1", Equal);
test("2", 10, "1.0", "0x1.000#10", Equal);
test("2", 100, "1.0", "0x1.0000000000000000000000000#100", Equal);
test("1/2", 1, "-1.0", "-0x1.0#1", Equal);
test("1/2", 10, "-1.0", "-0x1.000#10", Equal);
test(
"1/2",
100,
"-1.0",
"-0x1.0000000000000000000000000#100",
Equal,
);
test("8", 1, "4.0", "0x4.0#1", Greater);
test("8", 10, "3.0", "0x3.00#10", Equal);
test("8", 100, "3.0", "0x3.0000000000000000000000000#100", Equal);
test("1/8", 1, "-4.0", "-0x4.0#1", Less);
test("1/8", 10, "-3.0", "-0x3.00#10", Equal);
test(
"1/8",
100,
"-3.0",
"-0x3.0000000000000000000000000#100",
Equal,
);
test("1024", 1, "8.0", "0x8.0#1", Less);
test("1024", 10, "10.0", "0xa.00#10", Equal);
test(
"1024",
100,
"10.0",
"0xa.000000000000000000000000#100",
Equal,
);
test("3/5", 1, "-0.5", "-0x0.8#1", Greater);
test("3/5", 10, "-0.737", "-0x0.bcc#10", Less);
test(
"3/5",
100,
"-0.7369655941662061664165804855416",
"-0x0.bca9c6f53897a45984a4c9f33#100",
Greater,
);
test("1/3", 1, "-2.0", "-0x2.0#1", Less);
test("1/3", 10, "-1.586", "-0x1.960#10", Less);
test(
"1/3",
100,
"-1.584962500721156181453738943947",
"-0x1.95c01a39fbd6879fa00b120a0#100",
Greater,
);
test("22/7", 1, "2.0", "0x2.0#1", Greater);
test("22/7", 10, "1.652", "0x1.a70#10", Greater);
test(
"22/7",
100,
"1.652076696579693148757393729494",
"0x1.a6ee7f964b22a0c5d02f629d4#100",
Less,
);
test("355/113", 1, "2.0", "0x2.0#1", Greater);
test("355/113", 10, "1.652", "0x1.a70#10", Greater);
test(
"355/113",
100,
"1.651496251976856700958521105235",
"0x1.a6c87557b50969b3fc2c87d7e#100",
Greater,
);
let test_big = |u: Rational, prec, out: &str, out_hex: &str, out_o| {
let (log_base_2, o) = Float::log_base_2_rational_prec(u.clone(), prec);
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
assert_eq!(o, out_o);
let (log_base_2, o) = Float::log_base_2_rational_prec_ref(&u, prec);
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
assert_eq!(o, out_o);
let (rug_log_base_2, rug_o) = rug_log_base_2_rational_prec(&u, prec);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
};
test_big(
Rational::power_of_2(1000i64),
1,
"1.0e3",
"0x4.0E+2#1",
Greater,
);
test_big(
Rational::power_of_2(1000i64),
10,
"1000.0",
"0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(-1000i64),
1,
"-1.0e3",
"-0x4.0E+2#1",
Less,
);
test_big(
Rational::power_of_2(-1000i64),
10,
"-1000.0",
"-0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
1,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
10,
"1.074e9",
"0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1),
10,
"1.074e9",
"0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1) * Rational::from_unsigneds(3u8, 2),
1,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(300u16, 199),
1,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(299u16, 200),
1,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
1,
"-1.0e9",
"-0x4.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
10,
"-1.074e9",
"-0x4.00E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 1),
10,
"-1.074e9",
"-0x4.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2),
10,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1001u16, 1000),
10,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1025u16, 1024),
10,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1024u16, 1023),
10,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
1,
"9.0e-302",
"0x1.0E-250#1",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
10,
"1.347e-301",
"0x1.718E-250#10",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
100,
"1.346414794256683307023036700644e-301",
"0x1.71547652b82fe1777d0ffda0eE-250#100",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
1,
"-9.0e-302",
"-0x1.0E-250#1",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
10,
"-1.347e-301",
"-0x1.718E-250#10",
Less,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
100,
"-1.346414794256683307023036700644e-301",
"-0x1.71547652b82fe1777d0ffda0eE-250#100",
Less,
);
test_big(
Rational::power_of_2(1i64 << 31),
1,
"2.0e9",
"0x8.0E+7#1",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
10,
"2.147e9",
"0x8.00E+7#10",
Equal,
);
}
#[test]
fn test_log_base_2_rational_prec_round() {
let test = |s, prec, rm, out, out_hex, out_o| {
let u = Rational::from_str(s).unwrap();
let (log_base_2, o) = Float::log_base_2_rational_prec_round(u.clone(), prec, rm);
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
assert_eq!(o, out_o);
let (log_base_2, o) = Float::log_base_2_rational_prec_round_ref(&u, prec, rm);
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
assert_eq!(o, out_o);
if let Ok(rug_rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_log_base_2, rug_o) = rug_log_base_2_rational_prec_round(&u, prec, rug_rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
}
};
test("0", 1, Floor, "-Infinity", "-Infinity", Equal);
test("0", 1, Ceiling, "-Infinity", "-Infinity", Equal);
test("0", 1, Down, "-Infinity", "-Infinity", Equal);
test("0", 1, Up, "-Infinity", "-Infinity", Equal);
test("0", 1, Nearest, "-Infinity", "-Infinity", Equal);
test("0", 1, Exact, "-Infinity", "-Infinity", Equal);
test("0", 10, Floor, "-Infinity", "-Infinity", Equal);
test("0", 10, Ceiling, "-Infinity", "-Infinity", Equal);
test("0", 10, Down, "-Infinity", "-Infinity", Equal);
test("0", 10, Up, "-Infinity", "-Infinity", Equal);
test("0", 10, Nearest, "-Infinity", "-Infinity", Equal);
test("0", 10, Exact, "-Infinity", "-Infinity", Equal);
test("0", 100, Floor, "-Infinity", "-Infinity", Equal);
test("0", 100, Ceiling, "-Infinity", "-Infinity", Equal);
test("0", 100, Down, "-Infinity", "-Infinity", Equal);
test("0", 100, Up, "-Infinity", "-Infinity", Equal);
test("0", 100, Nearest, "-Infinity", "-Infinity", Equal);
test("0", 100, Exact, "-Infinity", "-Infinity", Equal);
test("1", 1, Floor, "0.0", "0x0.0", Equal);
test("1", 1, Ceiling, "0.0", "0x0.0", Equal);
test("1", 1, Down, "0.0", "0x0.0", Equal);
test("1", 1, Up, "0.0", "0x0.0", Equal);
test("1", 1, Nearest, "0.0", "0x0.0", Equal);
test("1", 1, Exact, "0.0", "0x0.0", Equal);
test("1", 10, Floor, "0.0", "0x0.0", Equal);
test("1", 10, Ceiling, "0.0", "0x0.0", Equal);
test("1", 10, Down, "0.0", "0x0.0", Equal);
test("1", 10, Up, "0.0", "0x0.0", Equal);
test("1", 10, Nearest, "0.0", "0x0.0", Equal);
test("1", 10, Exact, "0.0", "0x0.0", Equal);
test("1", 100, Floor, "0.0", "0x0.0", Equal);
test("1", 100, Ceiling, "0.0", "0x0.0", Equal);
test("1", 100, Down, "0.0", "0x0.0", Equal);
test("1", 100, Up, "0.0", "0x0.0", Equal);
test("1", 100, Nearest, "0.0", "0x0.0", Equal);
test("1", 100, Exact, "0.0", "0x0.0", Equal);
test("-1", 1, Floor, "NaN", "NaN", Equal);
test("-1", 1, Ceiling, "NaN", "NaN", Equal);
test("-1", 1, Down, "NaN", "NaN", Equal);
test("-1", 1, Up, "NaN", "NaN", Equal);
test("-1", 1, Nearest, "NaN", "NaN", Equal);
test("-1", 1, Exact, "NaN", "NaN", Equal);
test("-1", 10, Floor, "NaN", "NaN", Equal);
test("-1", 10, Ceiling, "NaN", "NaN", Equal);
test("-1", 10, Down, "NaN", "NaN", Equal);
test("-1", 10, Up, "NaN", "NaN", Equal);
test("-1", 10, Nearest, "NaN", "NaN", Equal);
test("-1", 10, Exact, "NaN", "NaN", Equal);
test("-1", 100, Floor, "NaN", "NaN", Equal);
test("-1", 100, Ceiling, "NaN", "NaN", Equal);
test("-1", 100, Down, "NaN", "NaN", Equal);
test("-1", 100, Up, "NaN", "NaN", Equal);
test("-1", 100, Nearest, "NaN", "NaN", Equal);
test("-1", 100, Exact, "NaN", "NaN", Equal);
test("-1/2", 1, Floor, "NaN", "NaN", Equal);
test("-1/2", 1, Ceiling, "NaN", "NaN", Equal);
test("-1/2", 1, Down, "NaN", "NaN", Equal);
test("-1/2", 1, Up, "NaN", "NaN", Equal);
test("-1/2", 1, Nearest, "NaN", "NaN", Equal);
test("-1/2", 1, Exact, "NaN", "NaN", Equal);
test("-1/2", 10, Floor, "NaN", "NaN", Equal);
test("-1/2", 10, Ceiling, "NaN", "NaN", Equal);
test("-1/2", 10, Down, "NaN", "NaN", Equal);
test("-1/2", 10, Up, "NaN", "NaN", Equal);
test("-1/2", 10, Nearest, "NaN", "NaN", Equal);
test("-1/2", 10, Exact, "NaN", "NaN", Equal);
test("-1/2", 100, Floor, "NaN", "NaN", Equal);
test("-1/2", 100, Ceiling, "NaN", "NaN", Equal);
test("-1/2", 100, Down, "NaN", "NaN", Equal);
test("-1/2", 100, Up, "NaN", "NaN", Equal);
test("-1/2", 100, Nearest, "NaN", "NaN", Equal);
test("-1/2", 100, Exact, "NaN", "NaN", Equal);
test("-22/7", 1, Floor, "NaN", "NaN", Equal);
test("-22/7", 1, Ceiling, "NaN", "NaN", Equal);
test("-22/7", 1, Down, "NaN", "NaN", Equal);
test("-22/7", 1, Up, "NaN", "NaN", Equal);
test("-22/7", 1, Nearest, "NaN", "NaN", Equal);
test("-22/7", 1, Exact, "NaN", "NaN", Equal);
test("-22/7", 10, Floor, "NaN", "NaN", Equal);
test("-22/7", 10, Ceiling, "NaN", "NaN", Equal);
test("-22/7", 10, Down, "NaN", "NaN", Equal);
test("-22/7", 10, Up, "NaN", "NaN", Equal);
test("-22/7", 10, Nearest, "NaN", "NaN", Equal);
test("-22/7", 10, Exact, "NaN", "NaN", Equal);
test("-22/7", 100, Floor, "NaN", "NaN", Equal);
test("-22/7", 100, Ceiling, "NaN", "NaN", Equal);
test("-22/7", 100, Down, "NaN", "NaN", Equal);
test("-22/7", 100, Up, "NaN", "NaN", Equal);
test("-22/7", 100, Nearest, "NaN", "NaN", Equal);
test("-22/7", 100, Exact, "NaN", "NaN", Equal);
test("2", 1, Floor, "1.0", "0x1.0#1", Equal);
test("2", 1, Ceiling, "1.0", "0x1.0#1", Equal);
test("2", 1, Down, "1.0", "0x1.0#1", Equal);
test("2", 1, Up, "1.0", "0x1.0#1", Equal);
test("2", 1, Nearest, "1.0", "0x1.0#1", Equal);
test("2", 1, Exact, "1.0", "0x1.0#1", Equal);
test("2", 10, Floor, "1.0", "0x1.000#10", Equal);
test("2", 10, Ceiling, "1.0", "0x1.000#10", Equal);
test("2", 10, Down, "1.0", "0x1.000#10", Equal);
test("2", 10, Up, "1.0", "0x1.000#10", Equal);
test("2", 10, Nearest, "1.0", "0x1.000#10", Equal);
test("2", 10, Exact, "1.0", "0x1.000#10", Equal);
test(
"2",
100,
Floor,
"1.0",
"0x1.0000000000000000000000000#100",
Equal,
);
test(
"2",
100,
Ceiling,
"1.0",
"0x1.0000000000000000000000000#100",
Equal,
);
test(
"2",
100,
Down,
"1.0",
"0x1.0000000000000000000000000#100",
Equal,
);
test(
"2",
100,
Up,
"1.0",
"0x1.0000000000000000000000000#100",
Equal,
);
test(
"2",
100,
Nearest,
"1.0",
"0x1.0000000000000000000000000#100",
Equal,
);
test(
"2",
100,
Exact,
"1.0",
"0x1.0000000000000000000000000#100",
Equal,
);
test("1/2", 1, Floor, "-1.0", "-0x1.0#1", Equal);
test("1/2", 1, Ceiling, "-1.0", "-0x1.0#1", Equal);
test("1/2", 1, Down, "-1.0", "-0x1.0#1", Equal);
test("1/2", 1, Up, "-1.0", "-0x1.0#1", Equal);
test("1/2", 1, Nearest, "-1.0", "-0x1.0#1", Equal);
test("1/2", 1, Exact, "-1.0", "-0x1.0#1", Equal);
test("1/2", 10, Floor, "-1.0", "-0x1.000#10", Equal);
test("1/2", 10, Ceiling, "-1.0", "-0x1.000#10", Equal);
test("1/2", 10, Down, "-1.0", "-0x1.000#10", Equal);
test("1/2", 10, Up, "-1.0", "-0x1.000#10", Equal);
test("1/2", 10, Nearest, "-1.0", "-0x1.000#10", Equal);
test("1/2", 10, Exact, "-1.0", "-0x1.000#10", Equal);
test(
"1/2",
100,
Floor,
"-1.0",
"-0x1.0000000000000000000000000#100",
Equal,
);
test(
"1/2",
100,
Ceiling,
"-1.0",
"-0x1.0000000000000000000000000#100",
Equal,
);
test(
"1/2",
100,
Down,
"-1.0",
"-0x1.0000000000000000000000000#100",
Equal,
);
test(
"1/2",
100,
Up,
"-1.0",
"-0x1.0000000000000000000000000#100",
Equal,
);
test(
"1/2",
100,
Nearest,
"-1.0",
"-0x1.0000000000000000000000000#100",
Equal,
);
test(
"1/2",
100,
Exact,
"-1.0",
"-0x1.0000000000000000000000000#100",
Equal,
);
test("8", 1, Floor, "2.0", "0x2.0#1", Less);
test("8", 1, Ceiling, "4.0", "0x4.0#1", Greater);
test("8", 1, Down, "2.0", "0x2.0#1", Less);
test("8", 1, Up, "4.0", "0x4.0#1", Greater);
test("8", 1, Nearest, "4.0", "0x4.0#1", Greater);
test("8", 10, Floor, "3.0", "0x3.00#10", Equal);
test("8", 10, Ceiling, "3.0", "0x3.00#10", Equal);
test("8", 10, Down, "3.0", "0x3.00#10", Equal);
test("8", 10, Up, "3.0", "0x3.00#10", Equal);
test("8", 10, Nearest, "3.0", "0x3.00#10", Equal);
test("8", 10, Exact, "3.0", "0x3.00#10", Equal);
test(
"8",
100,
Floor,
"3.0",
"0x3.0000000000000000000000000#100",
Equal,
);
test(
"8",
100,
Ceiling,
"3.0",
"0x3.0000000000000000000000000#100",
Equal,
);
test(
"8",
100,
Down,
"3.0",
"0x3.0000000000000000000000000#100",
Equal,
);
test(
"8",
100,
Up,
"3.0",
"0x3.0000000000000000000000000#100",
Equal,
);
test(
"8",
100,
Nearest,
"3.0",
"0x3.0000000000000000000000000#100",
Equal,
);
test(
"8",
100,
Exact,
"3.0",
"0x3.0000000000000000000000000#100",
Equal,
);
test("1/8", 1, Floor, "-4.0", "-0x4.0#1", Less);
test("1/8", 1, Ceiling, "-2.0", "-0x2.0#1", Greater);
test("1/8", 1, Down, "-2.0", "-0x2.0#1", Greater);
test("1/8", 1, Up, "-4.0", "-0x4.0#1", Less);
test("1/8", 1, Nearest, "-4.0", "-0x4.0#1", Less);
test("1/8", 10, Floor, "-3.0", "-0x3.00#10", Equal);
test("1/8", 10, Ceiling, "-3.0", "-0x3.00#10", Equal);
test("1/8", 10, Down, "-3.0", "-0x3.00#10", Equal);
test("1/8", 10, Up, "-3.0", "-0x3.00#10", Equal);
test("1/8", 10, Nearest, "-3.0", "-0x3.00#10", Equal);
test("1/8", 10, Exact, "-3.0", "-0x3.00#10", Equal);
test(
"1/8",
100,
Floor,
"-3.0",
"-0x3.0000000000000000000000000#100",
Equal,
);
test(
"1/8",
100,
Ceiling,
"-3.0",
"-0x3.0000000000000000000000000#100",
Equal,
);
test(
"1/8",
100,
Down,
"-3.0",
"-0x3.0000000000000000000000000#100",
Equal,
);
test(
"1/8",
100,
Up,
"-3.0",
"-0x3.0000000000000000000000000#100",
Equal,
);
test(
"1/8",
100,
Nearest,
"-3.0",
"-0x3.0000000000000000000000000#100",
Equal,
);
test(
"1/8",
100,
Exact,
"-3.0",
"-0x3.0000000000000000000000000#100",
Equal,
);
test("1024", 1, Floor, "8.0", "0x8.0#1", Less);
test("1024", 1, Ceiling, "2.0e1", "0x1.0E+1#1", Greater);
test("1024", 1, Down, "8.0", "0x8.0#1", Less);
test("1024", 1, Up, "2.0e1", "0x1.0E+1#1", Greater);
test("1024", 1, Nearest, "8.0", "0x8.0#1", Less);
test("1024", 10, Floor, "10.0", "0xa.00#10", Equal);
test("1024", 10, Ceiling, "10.0", "0xa.00#10", Equal);
test("1024", 10, Down, "10.0", "0xa.00#10", Equal);
test("1024", 10, Up, "10.0", "0xa.00#10", Equal);
test("1024", 10, Nearest, "10.0", "0xa.00#10", Equal);
test("1024", 10, Exact, "10.0", "0xa.00#10", Equal);
test(
"1024",
100,
Floor,
"10.0",
"0xa.000000000000000000000000#100",
Equal,
);
test(
"1024",
100,
Ceiling,
"10.0",
"0xa.000000000000000000000000#100",
Equal,
);
test(
"1024",
100,
Down,
"10.0",
"0xa.000000000000000000000000#100",
Equal,
);
test(
"1024",
100,
Up,
"10.0",
"0xa.000000000000000000000000#100",
Equal,
);
test(
"1024",
100,
Nearest,
"10.0",
"0xa.000000000000000000000000#100",
Equal,
);
test(
"1024",
100,
Exact,
"10.0",
"0xa.000000000000000000000000#100",
Equal,
);
test("3/5", 1, Floor, "-1.0", "-0x1.0#1", Less);
test("3/5", 1, Ceiling, "-0.5", "-0x0.8#1", Greater);
test("3/5", 1, Down, "-0.5", "-0x0.8#1", Greater);
test("3/5", 1, Up, "-1.0", "-0x1.0#1", Less);
test("3/5", 1, Nearest, "-0.5", "-0x0.8#1", Greater);
test("3/5", 10, Floor, "-0.737", "-0x0.bcc#10", Less);
test("3/5", 10, Ceiling, "-0.736", "-0x0.bc8#10", Greater);
test("3/5", 10, Down, "-0.736", "-0x0.bc8#10", Greater);
test("3/5", 10, Up, "-0.737", "-0x0.bcc#10", Less);
test("3/5", 10, Nearest, "-0.737", "-0x0.bcc#10", Less);
test(
"3/5",
100,
Floor,
"-0.7369655941662061664165804855424",
"-0x0.bca9c6f53897a45984a4c9f34#100",
Less,
);
test(
"3/5",
100,
Ceiling,
"-0.7369655941662061664165804855416",
"-0x0.bca9c6f53897a45984a4c9f33#100",
Greater,
);
test(
"3/5",
100,
Down,
"-0.7369655941662061664165804855416",
"-0x0.bca9c6f53897a45984a4c9f33#100",
Greater,
);
test(
"3/5",
100,
Up,
"-0.7369655941662061664165804855424",
"-0x0.bca9c6f53897a45984a4c9f34#100",
Less,
);
test(
"3/5",
100,
Nearest,
"-0.7369655941662061664165804855416",
"-0x0.bca9c6f53897a45984a4c9f33#100",
Greater,
);
test("1/3", 1, Floor, "-2.0", "-0x2.0#1", Less);
test("1/3", 1, Ceiling, "-1.0", "-0x1.0#1", Greater);
test("1/3", 1, Down, "-1.0", "-0x1.0#1", Greater);
test("1/3", 1, Up, "-2.0", "-0x2.0#1", Less);
test("1/3", 1, Nearest, "-2.0", "-0x2.0#1", Less);
test("1/3", 10, Floor, "-1.586", "-0x1.960#10", Less);
test("1/3", 10, Ceiling, "-1.584", "-0x1.958#10", Greater);
test("1/3", 10, Down, "-1.584", "-0x1.958#10", Greater);
test("1/3", 10, Up, "-1.586", "-0x1.960#10", Less);
test("1/3", 10, Nearest, "-1.586", "-0x1.960#10", Less);
test(
"1/3",
100,
Floor,
"-1.584962500721156181453738943949",
"-0x1.95c01a39fbd6879fa00b120a2#100",
Less,
);
test(
"1/3",
100,
Ceiling,
"-1.584962500721156181453738943947",
"-0x1.95c01a39fbd6879fa00b120a0#100",
Greater,
);
test(
"1/3",
100,
Down,
"-1.584962500721156181453738943947",
"-0x1.95c01a39fbd6879fa00b120a0#100",
Greater,
);
test(
"1/3",
100,
Up,
"-1.584962500721156181453738943949",
"-0x1.95c01a39fbd6879fa00b120a2#100",
Less,
);
test(
"1/3",
100,
Nearest,
"-1.584962500721156181453738943947",
"-0x1.95c01a39fbd6879fa00b120a0#100",
Greater,
);
test("22/7", 1, Floor, "1.0", "0x1.0#1", Less);
test("22/7", 1, Ceiling, "2.0", "0x2.0#1", Greater);
test("22/7", 1, Down, "1.0", "0x1.0#1", Less);
test("22/7", 1, Up, "2.0", "0x2.0#1", Greater);
test("22/7", 1, Nearest, "2.0", "0x2.0#1", Greater);
test("22/7", 10, Floor, "1.65", "0x1.a68#10", Less);
test("22/7", 10, Ceiling, "1.652", "0x1.a70#10", Greater);
test("22/7", 10, Down, "1.65", "0x1.a68#10", Less);
test("22/7", 10, Up, "1.652", "0x1.a70#10", Greater);
test("22/7", 10, Nearest, "1.652", "0x1.a70#10", Greater);
test(
"22/7",
100,
Floor,
"1.652076696579693148757393729494",
"0x1.a6ee7f964b22a0c5d02f629d4#100",
Less,
);
test(
"22/7",
100,
Ceiling,
"1.652076696579693148757393729495",
"0x1.a6ee7f964b22a0c5d02f629d6#100",
Greater,
);
test(
"22/7",
100,
Down,
"1.652076696579693148757393729494",
"0x1.a6ee7f964b22a0c5d02f629d4#100",
Less,
);
test(
"22/7",
100,
Up,
"1.652076696579693148757393729495",
"0x1.a6ee7f964b22a0c5d02f629d6#100",
Greater,
);
test(
"22/7",
100,
Nearest,
"1.652076696579693148757393729494",
"0x1.a6ee7f964b22a0c5d02f629d4#100",
Less,
);
test("355/113", 1, Floor, "1.0", "0x1.0#1", Less);
test("355/113", 1, Ceiling, "2.0", "0x2.0#1", Greater);
test("355/113", 1, Down, "1.0", "0x1.0#1", Less);
test("355/113", 1, Up, "2.0", "0x2.0#1", Greater);
test("355/113", 1, Nearest, "2.0", "0x2.0#1", Greater);
test("355/113", 10, Floor, "1.65", "0x1.a68#10", Less);
test("355/113", 10, Ceiling, "1.652", "0x1.a70#10", Greater);
test("355/113", 10, Down, "1.65", "0x1.a68#10", Less);
test("355/113", 10, Up, "1.652", "0x1.a70#10", Greater);
test("355/113", 10, Nearest, "1.652", "0x1.a70#10", Greater);
test(
"355/113",
100,
Floor,
"1.651496251976856700958521105234",
"0x1.a6c87557b50969b3fc2c87d7c#100",
Less,
);
test(
"355/113",
100,
Ceiling,
"1.651496251976856700958521105235",
"0x1.a6c87557b50969b3fc2c87d7e#100",
Greater,
);
test(
"355/113",
100,
Down,
"1.651496251976856700958521105234",
"0x1.a6c87557b50969b3fc2c87d7c#100",
Less,
);
test(
"355/113",
100,
Up,
"1.651496251976856700958521105235",
"0x1.a6c87557b50969b3fc2c87d7e#100",
Greater,
);
test(
"355/113",
100,
Nearest,
"1.651496251976856700958521105235",
"0x1.a6c87557b50969b3fc2c87d7e#100",
Greater,
);
let test_big = |u: Rational, prec, rm, out: &str, out_hex: &str, out_o| {
let (log_base_2, o) = Float::log_base_2_rational_prec_round(u.clone(), prec, rm);
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
assert_eq!(o, out_o);
let (log_base_2, o) = Float::log_base_2_rational_prec_round_ref(&u, prec, rm);
assert!(log_base_2.is_valid());
assert_eq!(log_base_2.to_string(), out);
assert_eq!(to_hex_string(&log_base_2), out_hex);
assert_eq!(o, out_o);
if let Ok(rug_rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_log_base_2, rug_o) = rug_log_base_2_rational_prec_round(&u, prec, rug_rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_log_base_2)),
ComparableFloatRef(&log_base_2),
);
assert_eq!(rug_o, o);
}
};
test_big(
Rational::power_of_2(1000i64),
1,
Floor,
"5.0e2",
"0x2.0E+2#1",
Less,
);
test_big(
Rational::power_of_2(1000i64),
1,
Ceiling,
"1.0e3",
"0x4.0E+2#1",
Greater,
);
test_big(
Rational::power_of_2(1000i64),
1,
Down,
"5.0e2",
"0x2.0E+2#1",
Less,
);
test_big(
Rational::power_of_2(1000i64),
1,
Up,
"1.0e3",
"0x4.0E+2#1",
Greater,
);
test_big(
Rational::power_of_2(1000i64),
1,
Nearest,
"1.0e3",
"0x4.0E+2#1",
Greater,
);
test_big(
Rational::power_of_2(1000i64),
10,
Floor,
"1000.0",
"0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(1000i64),
10,
Ceiling,
"1000.0",
"0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(1000i64),
10,
Down,
"1000.0",
"0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(1000i64),
10,
Up,
"1000.0",
"0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(1000i64),
10,
Nearest,
"1000.0",
"0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(1000i64),
10,
Exact,
"1000.0",
"0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(-1000i64),
1,
Floor,
"-1.0e3",
"-0x4.0E+2#1",
Less,
);
test_big(
Rational::power_of_2(-1000i64),
1,
Ceiling,
"-5.0e2",
"-0x2.0E+2#1",
Greater,
);
test_big(
Rational::power_of_2(-1000i64),
1,
Down,
"-5.0e2",
"-0x2.0E+2#1",
Greater,
);
test_big(
Rational::power_of_2(-1000i64),
1,
Up,
"-1.0e3",
"-0x4.0E+2#1",
Less,
);
test_big(
Rational::power_of_2(-1000i64),
1,
Nearest,
"-1.0e3",
"-0x4.0E+2#1",
Less,
);
test_big(
Rational::power_of_2(-1000i64),
10,
Floor,
"-1000.0",
"-0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(-1000i64),
10,
Ceiling,
"-1000.0",
"-0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(-1000i64),
10,
Down,
"-1000.0",
"-0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(-1000i64),
10,
Up,
"-1000.0",
"-0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(-1000i64),
10,
Nearest,
"-1000.0",
"-0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(-1000i64),
10,
Exact,
"-1000.0",
"-0x3e8.0#10",
Equal,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
1,
Floor,
"5.0e8",
"0x2.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
1,
Ceiling,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
1,
Down,
"5.0e8",
"0x2.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
1,
Up,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
1,
Nearest,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
10,
Floor,
"1.073e9",
"0x3.ffE+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
10,
Ceiling,
"1.074e9",
"0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
10,
Down,
"1.073e9",
"0x3.ffE+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
10,
Up,
"1.074e9",
"0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT)),
10,
Nearest,
"1.074e9",
"0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1),
10,
Floor,
"1.073e9",
"0x3.ffE+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1),
10,
Ceiling,
"1.074e9",
"0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1),
10,
Down,
"1.073e9",
"0x3.ffE+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1),
10,
Up,
"1.074e9",
"0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1),
10,
Nearest,
"1.074e9",
"0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1) * Rational::from_unsigneds(3u8, 2),
1,
Floor,
"5.0e8",
"0x2.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1) * Rational::from_unsigneds(3u8, 2),
1,
Ceiling,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1) * Rational::from_unsigneds(3u8, 2),
1,
Down,
"5.0e8",
"0x2.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1) * Rational::from_unsigneds(3u8, 2),
1,
Up,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1) * Rational::from_unsigneds(3u8, 2),
1,
Nearest,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(300u16, 199),
1,
Floor,
"5.0e8",
"0x2.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(300u16, 199),
1,
Ceiling,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(300u16, 199),
1,
Down,
"5.0e8",
"0x2.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(300u16, 199),
1,
Up,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(300u16, 199),
1,
Nearest,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(299u16, 200),
1,
Floor,
"5.0e8",
"0x2.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(299u16, 200),
1,
Ceiling,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(299u16, 200),
1,
Down,
"5.0e8",
"0x2.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(299u16, 200),
1,
Up,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MAX_EXPONENT) - 1)
* Rational::from_unsigneds(299u16, 200),
1,
Nearest,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
1,
Floor,
"-1.0e9",
"-0x4.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
1,
Ceiling,
"-5.0e8",
"-0x2.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
1,
Down,
"-5.0e8",
"-0x2.0E+7#1",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
1,
Up,
"-1.0e9",
"-0x4.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
1,
Nearest,
"-1.0e9",
"-0x4.0E+7#1",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
10,
Floor,
"-1.074e9",
"-0x4.00E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
10,
Ceiling,
"-1.073e9",
"-0x3.ffE+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
10,
Down,
"-1.073e9",
"-0x3.ffE+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
10,
Up,
"-1.074e9",
"-0x4.00E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT)),
10,
Nearest,
"-1.074e9",
"-0x4.00E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 1),
10,
Floor,
"-1.074e9",
"-0x4.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 1),
10,
Ceiling,
"-1.074e9",
"-0x4.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 1),
10,
Down,
"-1.074e9",
"-0x4.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 1),
10,
Up,
"-1.074e9",
"-0x4.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 1),
10,
Nearest,
"-1.074e9",
"-0x4.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 1),
10,
Exact,
"-1.074e9",
"-0x4.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2),
10,
Floor,
"-1.076e9",
"-0x4.02E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2),
10,
Ceiling,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2),
10,
Down,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2),
10,
Up,
"-1.076e9",
"-0x4.02E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2),
10,
Nearest,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1001u16, 1000),
10,
Floor,
"-1.076e9",
"-0x4.02E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1001u16, 1000),
10,
Ceiling,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1001u16, 1000),
10,
Down,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1001u16, 1000),
10,
Up,
"-1.076e9",
"-0x4.02E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1001u16, 1000),
10,
Nearest,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1025u16, 1024),
10,
Floor,
"-1.076e9",
"-0x4.02E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1025u16, 1024),
10,
Ceiling,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1025u16, 1024),
10,
Down,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1025u16, 1024),
10,
Up,
"-1.076e9",
"-0x4.02E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1025u16, 1024),
10,
Nearest,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1024u16, 1023),
10,
Floor,
"-1.076e9",
"-0x4.02E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1024u16, 1023),
10,
Ceiling,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1024u16, 1023),
10,
Down,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1024u16, 1023),
10,
Up,
"-1.076e9",
"-0x4.02E+7#10",
Less,
);
test_big(
Rational::power_of_2(i64::from(Float::MIN_EXPONENT) - 2)
* Rational::from_unsigneds(1024u16, 1023),
10,
Nearest,
"-1.074e9",
"-0x4.00E+7#10",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
1,
Floor,
"9.0e-302",
"0x1.0E-250#1",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
1,
Ceiling,
"2.0e-301",
"0x2.0E-250#1",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
1,
Down,
"9.0e-302",
"0x1.0E-250#1",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
1,
Up,
"2.0e-301",
"0x2.0E-250#1",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
1,
Nearest,
"9.0e-302",
"0x1.0E-250#1",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
10,
Floor,
"1.345e-301",
"0x1.710E-250#10",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
10,
Ceiling,
"1.347e-301",
"0x1.718E-250#10",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
10,
Down,
"1.345e-301",
"0x1.710E-250#10",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
10,
Up,
"1.347e-301",
"0x1.718E-250#10",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
10,
Nearest,
"1.347e-301",
"0x1.718E-250#10",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
100,
Floor,
"1.346414794256683307023036700642e-301",
"0x1.71547652b82fe1777d0ffda0cE-250#100",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
100,
Ceiling,
"1.346414794256683307023036700644e-301",
"0x1.71547652b82fe1777d0ffda0eE-250#100",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
100,
Down,
"1.346414794256683307023036700642e-301",
"0x1.71547652b82fe1777d0ffda0cE-250#100",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
100,
Up,
"1.346414794256683307023036700644e-301",
"0x1.71547652b82fe1777d0ffda0eE-250#100",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-1000i64),
100,
Nearest,
"1.346414794256683307023036700644e-301",
"0x1.71547652b82fe1777d0ffda0eE-250#100",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
1,
Floor,
"-2.0e-301",
"-0x2.0E-250#1",
Less,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
1,
Ceiling,
"-9.0e-302",
"-0x1.0E-250#1",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
1,
Down,
"-9.0e-302",
"-0x1.0E-250#1",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
1,
Up,
"-2.0e-301",
"-0x2.0E-250#1",
Less,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
1,
Nearest,
"-9.0e-302",
"-0x1.0E-250#1",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
10,
Floor,
"-1.347e-301",
"-0x1.718E-250#10",
Less,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
10,
Ceiling,
"-1.345e-301",
"-0x1.710E-250#10",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
10,
Down,
"-1.345e-301",
"-0x1.710E-250#10",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
10,
Up,
"-1.347e-301",
"-0x1.718E-250#10",
Less,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
10,
Nearest,
"-1.347e-301",
"-0x1.718E-250#10",
Less,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
100,
Floor,
"-1.346414794256683307023036700644e-301",
"-0x1.71547652b82fe1777d0ffda0eE-250#100",
Less,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
100,
Ceiling,
"-1.346414794256683307023036700642e-301",
"-0x1.71547652b82fe1777d0ffda0cE-250#100",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
100,
Down,
"-1.346414794256683307023036700642e-301",
"-0x1.71547652b82fe1777d0ffda0cE-250#100",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
100,
Up,
"-1.346414794256683307023036700644e-301",
"-0x1.71547652b82fe1777d0ffda0eE-250#100",
Less,
);
test_big(
Rational::ONE - Rational::power_of_2(-1000i64),
100,
Nearest,
"-1.346414794256683307023036700644e-301",
"-0x1.71547652b82fe1777d0ffda0eE-250#100",
Less,
);
test_big(
Rational::power_of_2(1i64 << 31),
1,
Floor,
"2.0e9",
"0x8.0E+7#1",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
1,
Ceiling,
"2.0e9",
"0x8.0E+7#1",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
1,
Down,
"2.0e9",
"0x8.0E+7#1",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
1,
Up,
"2.0e9",
"0x8.0E+7#1",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
1,
Nearest,
"2.0e9",
"0x8.0E+7#1",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
1,
Exact,
"2.0e9",
"0x8.0E+7#1",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
10,
Floor,
"2.147e9",
"0x8.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
10,
Ceiling,
"2.147e9",
"0x8.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
10,
Down,
"2.147e9",
"0x8.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
10,
Up,
"2.147e9",
"0x8.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
10,
Nearest,
"2.147e9",
"0x8.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(1i64 << 31),
10,
Exact,
"2.147e9",
"0x8.00E+7#10",
Equal,
);
test_big(
Rational::power_of_2(100000i64) + Rational::ONE,
1,
Floor,
"7.0e4",
"0x1.0E+4#1",
Less,
);
test_big(
Rational::power_of_2(100000i64) + Rational::ONE,
5,
Floor,
"9.8e4",
"0x1.8E+4#5",
Less,
);
test_big(
Rational::power_of_2(100000i64) + Rational::ONE,
1,
Ceiling,
"1.0e5",
"0x2.0E+4#1",
Greater,
);
test_big(
Rational::power_of_2(100000i64) + Rational::ONE,
5,
Ceiling,
"1.0e5",
"0x1.9E+4#5",
Greater,
);
test_big(
Rational::power_of_2(100000i64) + Rational::ONE,
1,
Nearest,
"1.0e5",
"0x2.0E+4#1",
Greater,
);
test_big(
Rational::power_of_2(100000i64) + Rational::ONE,
5,
Nearest,
"9.8e4",
"0x1.8E+4#5",
Less,
);
test_big(
Rational::power_of_2(100000i64) - Rational::power_of_2(-5i64),
1,
Floor,
"7.0e4",
"0x1.0E+4#1",
Less,
);
test_big(
Rational::power_of_2(100000i64) - Rational::power_of_2(-5i64),
5,
Floor,
"9.8e4",
"0x1.8E+4#5",
Less,
);
test_big(
Rational::power_of_2(100000i64) - Rational::power_of_2(-5i64),
1,
Ceiling,
"1.0e5",
"0x2.0E+4#1",
Greater,
);
test_big(
Rational::power_of_2(100000i64) - Rational::power_of_2(-5i64),
5,
Ceiling,
"1.0e5",
"0x1.9E+4#5",
Greater,
);
test_big(
Rational::power_of_2(100000i64) - Rational::power_of_2(-5i64),
1,
Nearest,
"1.0e5",
"0x2.0E+4#1",
Greater,
);
test_big(
Rational::power_of_2(100000i64) - Rational::power_of_2(-5i64),
5,
Nearest,
"9.8e4",
"0x1.8E+4#5",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-100000i64),
1,
Floor,
"too_small",
"0x1.0E-25000#1",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-100000i64),
5,
Floor,
"too_small",
"0x1.7E-25000#5",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-100000i64),
1,
Ceiling,
"too_small",
"0x2.0E-25000#1",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-100000i64),
5,
Ceiling,
"too_small",
"0x1.8E-25000#5",
Greater,
);
test_big(
Rational::ONE + Rational::power_of_2(-100000i64),
1,
Nearest,
"too_small",
"0x1.0E-25000#1",
Less,
);
test_big(
Rational::ONE + Rational::power_of_2(-100000i64),
5,
Nearest,
"too_small",
"0x1.7E-25000#5",
Less,
);
test_big(
Rational::ONE - Rational::power_of_2(-100000i64),
1,
Floor,
"-too_small",
"-0x2.0E-25000#1",
Less,
);
test_big(
Rational::ONE - Rational::power_of_2(-100000i64),
5,
Floor,
"-too_small",
"-0x1.8E-25000#5",
Less,
);
test_big(
Rational::ONE - Rational::power_of_2(-100000i64),
1,
Ceiling,
"-too_small",
"-0x1.0E-25000#1",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-100000i64),
5,
Ceiling,
"-too_small",
"-0x1.7E-25000#5",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-100000i64),
1,
Nearest,
"-too_small",
"-0x1.0E-25000#1",
Greater,
);
test_big(
Rational::ONE - Rational::power_of_2(-100000i64),
5,
Nearest,
"-too_small",
"-0x1.7E-25000#5",
Greater,
);
test_big(
Rational::from(4) + Rational::power_of_2(-200i64),
1,
Floor,
"2.0",
"0x2.0#1",
Less,
);
test_big(
Rational::from(4) + Rational::power_of_2(-200i64),
5,
Floor,
"2.0",
"0x2.0#5",
Less,
);
test_big(
Rational::from(4) + Rational::power_of_2(-200i64),
1,
Ceiling,
"4.0",
"0x4.0#1",
Greater,
);
test_big(
Rational::from(4) + Rational::power_of_2(-200i64),
5,
Ceiling,
"2.1",
"0x2.2#5",
Greater,
);
test_big(
Rational::from(4) + Rational::power_of_2(-200i64),
1,
Nearest,
"2.0",
"0x2.0#1",
Less,
);
test_big(
Rational::from(4) + Rational::power_of_2(-200i64),
5,
Nearest,
"2.0",
"0x2.0#5",
Less,
);
test_big(
Rational::from_signeds(1, 4) - Rational::power_of_2(-200i64),
1,
Floor,
"-4.0",
"-0x4.0#1",
Less,
);
test_big(
Rational::from_signeds(1, 4) - Rational::power_of_2(-200i64),
5,
Floor,
"-2.1",
"-0x2.2#5",
Less,
);
test_big(
Rational::from_signeds(1, 4) - Rational::power_of_2(-200i64),
1,
Ceiling,
"-2.0",
"-0x2.0#1",
Greater,
);
test_big(
Rational::from_signeds(1, 4) - Rational::power_of_2(-200i64),
5,
Ceiling,
"-2.0",
"-0x2.0#5",
Greater,
);
test_big(
Rational::from_signeds(1, 4) - Rational::power_of_2(-200i64),
1,
Nearest,
"-2.0",
"-0x2.0#1",
Greater,
);
test_big(
Rational::from_signeds(1, 4) - Rational::power_of_2(-200i64),
5,
Nearest,
"-2.0",
"-0x2.0#5",
Greater,
);
}
#[test]
#[allow(clippy::type_repetition_in_bounds)]
fn test_primitive_float_log_base_2() {
fn test<T: PrimitiveFloat>(x: T, out: T)
where
Float: From<T> + PartialOrd<T>,
for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
{
assert_eq!(NiceFloat(primitive_float_log_base_2(x)), NiceFloat(out));
}
test::<f32>(f32::NAN, f32::NAN);
test::<f32>(f32::INFINITY, f32::INFINITY);
test::<f32>(f32::NEGATIVE_INFINITY, f32::NAN);
test::<f32>(0.0, f32::NEGATIVE_INFINITY);
test::<f32>(-0.0, f32::NEGATIVE_INFINITY);
test::<f32>(1.0, 0.0);
test::<f32>(2.0, 1.0);
test::<f32>(0.5, -1.0);
test::<f32>(8.0, 3.0);
test::<f32>(10.0, std::f32::consts::LOG2_10); test::<f32>(-1.0, f32::NAN);
test::<f32>(-10.0, f32::NAN);
test::<f64>(f64::NAN, f64::NAN);
test::<f64>(f64::INFINITY, f64::INFINITY);
test::<f64>(f64::NEGATIVE_INFINITY, f64::NAN);
test::<f64>(0.0, f64::NEGATIVE_INFINITY);
test::<f64>(-0.0, f64::NEGATIVE_INFINITY);
test::<f64>(1.0, 0.0);
test::<f64>(2.0, 1.0);
test::<f64>(0.5, -1.0);
test::<f64>(8.0, 3.0);
test::<f64>(10.0, std::f64::consts::LOG2_10); test::<f64>(-1.0, f64::NAN);
test::<f64>(-10.0, f64::NAN);
test::<f64>(1.8391006370482736, 0.8790004273289614);
}
#[allow(clippy::type_repetition_in_bounds)]
fn primitive_float_log_base_2_properties_helper<T: PrimitiveFloat>()
where
Float: From<T> + PartialOrd<T>,
for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
{
primitive_float_gen::<T>().test_properties(|x| {
primitive_float_log_base_2(x);
});
}
#[test]
fn primitive_float_log_base_2_properties() {
apply_fn_to_primitive_floats!(primitive_float_log_base_2_properties_helper);
}
#[test]
#[allow(clippy::type_repetition_in_bounds)]
fn test_primitive_float_log_base_2_rational() {
fn test<T: PrimitiveFloat>(s: &str, out: T)
where
Float: From<T> + PartialOrd<T>,
for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
{
let u = Rational::from_str(s).unwrap();
assert_eq!(
NiceFloat(primitive_float_log_base_2_rational(&u)),
NiceFloat(out)
);
}
test::<f32>("0", f32::NEGATIVE_INFINITY);
test::<f32>("1", 0.0);
test::<f32>("1/2", -1.0);
test::<f32>("2", 1.0);
test::<f32>("8", 3.0);
test::<f32>("1/3", -1.5849625);
test::<f32>("22/7", 1.6520767);
test::<f32>("1000000", 19.931568);
test::<f32>("1/1000000", -19.931568);
test::<f32>("-1", f32::NAN);
test::<f32>("-1/2", f32::NAN);
test::<f32>("-22/7", f32::NAN);
test::<f64>("0", f64::NEGATIVE_INFINITY);
test::<f64>("1", 0.0);
test::<f64>("1/2", -1.0);
test::<f64>("2", 1.0);
test::<f64>("8", 3.0);
test::<f64>("1/3", -1.584962500721156);
test::<f64>("22/7", 1.6520766965796931);
test::<f64>("1000000", 19.931568569324174);
test::<f64>("1/1000000", -19.931568569324174);
test::<f64>("-1", f64::NAN);
test::<f64>("-1/2", f64::NAN);
test::<f64>("-22/7", f64::NAN);
}
#[allow(clippy::type_repetition_in_bounds)]
fn primitive_float_log_base_2_rational_properties_helper<T: PrimitiveFloat>()
where
Float: From<T> + PartialOrd<T>,
for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
{
rational_gen().test_properties(|x| {
let y = primitive_float_log_base_2_rational::<T>(&x);
if x != 0u32 {
assert_eq!(
NiceFloat(
primitive_float_log_base_2_rational::<T>(&x.reciprocal()).abs_negative_zero()
),
NiceFloat((-y).abs_negative_zero())
);
}
});
}
#[test]
fn primitive_float_log_base_2_rational_properties() {
apply_fn_to_primitive_floats!(primitive_float_log_base_2_rational_properties_helper);
}