// Copyright © 2024 Mikhail Hogrefe
//
// This file is part of Malachite.
//
// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
// 3 of the License, or (at your option) any later version. See .
use malachite_base::num::arithmetic::traits::NegAssign;
use malachite_base::num::basic::floats::PrimitiveFloat;
use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, NegativeZero, 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::exhaustive::exhaustive_rounding_modes;
use malachite_base::rounding_modes::RoundingMode::{self, *};
use malachite_base::test_util::generators::primitive_float_pair_gen;
use malachite_float::test_util::arithmetic::add::{
add_prec_round_naive, add_rational_prec_round_naive,
};
use malachite_float::test_util::arithmetic::sub::{
rug_sub, rug_sub_prec, rug_sub_prec_round, rug_sub_rational, rug_sub_rational_prec,
rug_sub_rational_prec_round, rug_sub_rational_round, rug_sub_round,
};
use malachite_float::test_util::common::{
emulate_primitive_float_fn_2, parse_hex_string, rug_round_try_from_rounding_mode, to_hex_string,
};
use malachite_float::test_util::generators::{
float_float_rounding_mode_triple_gen_var_10, float_float_rounding_mode_triple_gen_var_11,
float_float_rounding_mode_triple_gen_var_12, float_float_rounding_mode_triple_gen_var_13,
float_float_rounding_mode_triple_gen_var_14, float_float_rounding_mode_triple_gen_var_15,
float_float_rounding_mode_triple_gen_var_2,
float_float_unsigned_rounding_mode_quadruple_gen_var_2, float_float_unsigned_triple_gen_var_1,
float_gen, float_pair_gen, float_pair_gen_var_2, float_pair_gen_var_3, float_pair_gen_var_4,
float_pair_gen_var_5, float_pair_gen_var_6, float_pair_gen_var_7, float_rational_pair_gen,
float_rational_rounding_mode_triple_gen_var_2,
float_rational_unsigned_rounding_mode_quadruple_gen_var_2,
float_rational_unsigned_triple_gen_var_1, float_rounding_mode_pair_gen,
float_unsigned_pair_gen_var_1, float_unsigned_rounding_mode_triple_gen_var_1,
rational_rounding_mode_pair_gen_var_6, rational_unsigned_rounding_mode_triple_gen_var_1,
};
use malachite_float::{ComparableFloat, ComparableFloatRef, Float};
use malachite_q::test_util::generators::{rational_gen, rational_unsigned_pair_gen_var_3};
use malachite_q::Rational;
use std::cmp::{
max,
Ordering::{self, *},
};
use std::panic::catch_unwind;
use std::str::FromStr;
#[test]
fn test_sub() {
let test = |s, s_hex, t, t_hex, out: &str, out_hex: &str| {
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let y = parse_hex_string(t_hex);
assert_eq!(y.to_string(), t);
let diff = x.clone() - y.clone();
assert!(diff.is_valid());
assert_eq!(diff.to_string(), out);
assert_eq!(to_hex_string(&diff), out_hex);
let diff_alt = x.clone() - &y;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
let diff_alt = &x - y.clone();
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
let diff_alt = &x - &y;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
let mut diff_alt = x.clone();
diff_alt -= y.clone();
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
let mut diff_alt = x.clone();
diff_alt -= &y;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(
ComparableFloatRef(&Float::from(&rug_sub(
&rug::Float::exact_from(&x),
&rug::Float::exact_from(&y)
))),
ComparableFloatRef(&diff)
);
let diff_alt = add_prec_round_naive(
x.clone(),
-&y,
max(x.significant_bits(), y.significant_bits()),
Nearest,
)
.0;
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
};
test("NaN", "NaN", "NaN", "NaN", "NaN", "NaN");
test("NaN", "NaN", "Infinity", "Infinity", "NaN", "NaN");
test("NaN", "NaN", "-Infinity", "-Infinity", "NaN", "NaN");
test("NaN", "NaN", "0.0", "0x0.0", "NaN", "NaN");
test("NaN", "NaN", "-0.0", "-0x0.0", "NaN", "NaN");
test("Infinity", "Infinity", "NaN", "NaN", "NaN", "NaN");
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
);
test("Infinity", "Infinity", "Infinity", "Infinity", "NaN", "NaN");
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", "Infinity", "Infinity",
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", "Infinity", "Infinity",
);
test("-Infinity", "-Infinity", "NaN", "NaN", "NaN", "NaN");
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
"NaN",
"NaN",
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
);
test("0.0", "0x0.0", "NaN", "NaN", "NaN", "NaN");
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
);
test("0.0", "0x0.0", "-0.0", "-0x0.0", "0.0", "0x0.0");
test("0.0", "0x0.0", "0.0", "0x0.0", "0.0", "0x0.0");
test("-0.0", "-0x0.0", "NaN", "NaN", "NaN", "NaN");
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
);
test("-0.0", "-0x0.0", "-0.0", "-0x0.0", "0.0", "0x0.0");
test("-0.0", "-0x0.0", "0.0", "0x0.0", "-0.0", "-0x0.0");
test("123.0", "0x7b.0#7", "NaN", "NaN", "NaN", "NaN");
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
);
test("123.0", "0x7b.0#7", "-0.0", "-0x0.0", "123.0", "0x7b.0#7");
test("123.0", "0x7b.0#7", "0.0", "0x0.0", "123.0", "0x7b.0#7");
test("NaN", "NaN", "-123.0", "-0x7b.0#7", "NaN", "NaN");
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
"Infinity",
"Infinity",
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
"-Infinity",
"-Infinity",
);
test("0.0", "0x0.0", "-123.0", "-0x7b.0#7", "123.0", "0x7b.0#7");
test("-0.0", "-0x0.0", "-123.0", "-0x7b.0#7", "123.0", "0x7b.0#7");
test("1.0", "0x1.0#1", "-2.0", "-0x2.0#1", "4.0", "0x4.0#1");
test("1.0", "0x1.0#1", "-2.0", "-0x2.0#2", "3.0", "0x3.0#2");
test("1.0", "0x1.0#2", "-2.0", "-0x2.0#1", "3.0", "0x3.0#2");
test("1.0", "0x1.0#2", "-2.0", "-0x2.0#2", "3.0", "0x3.0#2");
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
"3.0",
"0x3.00#10",
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"4.555806215962888",
"0x4.8e4950f0795fc#53",
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1.727379091216698",
"-0x1.ba35842091e63#53",
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1.727379091216698",
"0x1.ba35842091e63#53",
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-4.555806215962888",
"-0x4.8e4950f0795fc#53",
);
test("1.0", "0x1.0#1", "-0.0002", "-0x0.001#1", "1.0", "0x1.0#1");
// - in sub_float_significands_same_prec_lt_w
// - x_exp == y_exp in sub_float_significands_same_prec_lt_w
// - x == y in sub_float_significands_same_prec_lt_w
test("1.0", "0x1.0#1", "1.0", "0x1.0#1", "0.0", "0x0.0");
// - x_exp < y_exp in sub_float_significands_same_prec_lt_w
// - exp_diff < Limb::WIDTH in sub_float_significands_same_prec_lt_w
// - leading_zeros != 0 in sub_float_significands_same_prec_lt_w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_lt_w
test("1.0", "0x1.0#1", "2.0", "0x2.0#1", "-1.0", "-0x1.0#1");
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_lt_w
// - neg in sub_float_significands_same_prec_lt_w
// - rm == Nearest in sub_float_significands_same_prec_lt_w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff & shift_bit) != 0) in
// sub_float_significands_same_prec_lt_w
// - rm == Nearest && round_bit != 0 && sticky_bit != 0 && diff == 0 in
// sub_float_significands_same_prec_lt_w
test("1.0", "0x1.0#1", "4.0", "0x4.0#1", "-4.0", "-0x4.0#1");
// - !neg in sub_float_significands_same_prec_lt_w
test("1.0", "0x1.0#1", "0.2", "0x0.4#1", "1.0", "0x1.0#1");
// - x < y in sub_float_significands_same_prec_lt_w
test("1.0", "0x1.0#2", "1.5", "0x1.8#2", "-0.5", "-0x0.8#2");
// - x > y in sub_float_significands_same_prec_lt_w
test("1.5", "0x1.8#2", "1.0", "0x1.0#2", "0.5", "0x0.8#2");
// - leading_zeros == 0 in sub_float_significands_same_prec_lt_w
test("1.5", "0x1.8#2", "0.5", "0x0.8#2", "1.0", "0x1.0#2");
// - rm == Nearest && (round_bit == 0 || (sticky_bit == 0 && (diff & shift_bit) == 0)) in
// sub_float_significands_same_prec_lt_w
test("2.0", "0x2.0#2", "0.8", "0x0.c#2", "1.0", "0x1.0#2");
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff & shift_bit) != 0) && diff !=
// 0 in sub_float_significands_same_prec_lt_w
test("1.5", "0x1.8#2", "0.1", "0x0.2#2", "1.5", "0x1.8#2");
// - exp_diff >= Limb::WIDTH in sub_float_significands_same_prec_lt_w
// - x <= HIGH_BIT in sub_float_significands_same_prec_lt_w
test(
"1.0e9",
"0x4.0E+7#1",
"6.0e-11",
"0x4.0E-9#1",
"1.0e9",
"0x4.0E+7#1",
);
// - x > HIGH_BIT in sub_float_significands_same_prec_lt_w
test(
"9.2047171e-27",
"0x2.d945d78E-22#27",
"1.43189635e33",
"0x4.69912aE+27#27",
"-1.43189635e33",
"-0x4.69912aE+27#27",
);
// - in sub_float_significands_same_prec_w
// - x_exp == y_exp in sub_float_significands_same_prec_w
// - x_exp == y_exp && a0 == 0 in sub_float_significands_same_prec_w
test(
"1.0",
"0x1.0000000000000000#64",
"1.0",
"0x1.0000000000000000#64",
"0.0",
"0x0.0",
);
// - x_exp != y_exp in sub_float_significands_same_prec_w
// - x_exp < y_exp in sub_float_significands_same_prec_w
// - exp_diff < Limb::WIDTH in sub_float_significands_same_prec_w
// - a0 != 0 in sub_float_significands_same_prec_w
// - leading_zeros != 0 in sub_float_significands_same_prec_w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_w
test(
"1.0",
"0x1.0000000000000000#64",
"2.0",
"0x2.0000000000000000#64",
"-1.0",
"-0x1.0000000000000000#64",
);
// - a0 > x in sub_float_significands_same_prec_w
test(
"1.0",
"0x1.0000000000000000#64",
"1.0000000000000000001",
"0x1.0000000000000002#64",
"-1.084202172485504434e-19",
"-0x2.0000000000000000E-16#64",
);
// - a0 <= x in sub_float_significands_same_prec_w
test(
"1.0000000000000000001",
"0x1.0000000000000002#64",
"1.0",
"0x1.0000000000000000#64",
"1.084202172485504434e-19",
"0x2.0000000000000000E-16#64",
);
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_w
// - neg in sub_float_significands_same_prec_w
// - rm == Nearest in sub_float_significands_same_prec_w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff & 1) != 0) in
// sub_float_significands_same_prec_w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff & 1) != 0) &&
// !diff.overflowing_add_assign(1) in sub_float_significands_same_prec_w
test(
"1.0000000000000000001",
"0x1.0000000000000002#64",
"4.0",
"0x4.0000000000000000#64",
"-3.0",
"-0x3.0000000000000000#64",
);
// - !neg in sub_float_significands_same_prec_w
test(
"4.0",
"0x4.0000000000000000#64",
"1.0000000000000000001",
"0x1.0000000000000002#64",
"3.0",
"0x3.0000000000000000#64",
);
// - rm == Nearest && (round_bit == 0 || (sticky_bit == 0 && (diff & 1) == 0)) in
// sub_float_significands_same_prec_w
test(
"1.0000000000000000003",
"0x1.0000000000000006#64",
"4.0",
"0x4.0000000000000000#64",
"-2.9999999999999999996",
"-0x2.fffffffffffffff8#64",
);
// - leading_zeros == 0 in sub_float_significands_same_prec_w
test(
"3.2729513077064011786e-37",
"0x6.f5f6d50e7b8f6eb0E-31#64",
"7.8519772600462495573e-34",
"0x4.13b4f0d218450fb0E-28#64",
"-7.848704308738543156e-34",
"-0x4.13459164c75d56b8E-28#64",
);
// - exp_diff >= Limb::WIDTH in sub_float_significands_same_prec_w
// - x > HIGH_BIT in sub_float_significands_same_prec_w
test(
"5.9376349676904431794e-6",
"0x0.0000639df2b03f3e49a70#64",
"2.9347251290514630352e-45",
"0x1.0c11b075f03d6daeE-37#64",
"5.9376349676904431794e-6",
"0x0.0000639df2b03f3e49a70#64",
);
// - x <= HIGH_BIT in sub_float_significands_same_prec_w
// - exp_diff != Limb::WIDTH || y <= HIGH_BIT in sub_float_significands_same_prec_w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff & 1) != 0) &&
// diff.overflowing_add_assign(1) in sub_float_significands_same_prec_w
test(
"8355840.0624923708378",
"0x7f8000.0fff8000ff8#64",
"2.3384026197294446691e49",
"0x1.0000000000000000E+41#64",
"-2.3384026197294446691e49",
"-0x1.0000000000000000E+41#64",
);
// - x_exp != y_exp && a0 == 0 in sub_float_significands_same_prec_w
test(
"63.999999999999999997",
"0x3f.ffffffffffffffc#64",
"64.0",
"0x40.000000000000000#64",
"-3.4694469519536141888e-18",
"-0x4.0000000000000000E-15#64",
);
// - exp_diff == Limb::WIDTH && y > HIGH_BIT in sub_float_significands_same_prec_w
test(
"4.656578456163629198e-10",
"0x1.ffff07fffffffffeE-8#64",
"4294967296.0",
"0x100000000.00000000#64",
"-4294967295.9999999995",
"-0xffffffff.fffffffe#64",
);
// - in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp == y_exp in sub_float_significands_same_prec_gt_w_lt_2w
// - a1 == 0 && a0 == 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.0",
"0x1.0000000000000000#65",
"1.0",
"0x1.0000000000000000#65",
"0.0",
"0x0.0",
);
// - x_exp != y_exp in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp < y_exp in sub_float_significands_same_prec_gt_w_lt_2w
// - exp_diff < Limb::WIDTH in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp != y_exp && a1 != 0 in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp != y_exp && leading_zeros != 0 in sub_float_significands_same_prec_gt_w_lt_2w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.0",
"0x1.0000000000000000#65",
"2.0",
"0x2.0000000000000000#65",
"-1.0",
"-0x1.0000000000000000#65",
);
// - (a1 != 0 || a0 != 0) && a1 >= x_1 in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp == y_exp && a1 == 0 in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp == y_exp && leading_zeros == 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.0",
"0x1.0000000000000000#65",
"1.00000000000000000005",
"0x1.0000000000000001#65",
"-5.42101086242752217e-20",
"-0x1.0000000000000000E-16#65",
);
// - (a1 != 0 || a0 != 0) && a1 < x_1 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.00000000000000000005",
"0x1.0000000000000001#65",
"1.0",
"0x1.0000000000000000#65",
"5.42101086242752217e-20",
"0x1.0000000000000000E-16#65",
);
// - x_exp == y_exp && leading_zeros != 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.0",
"0x1.00000000000000000#66",
"1.00000000000000000003",
"0x1.00000000000000008#66",
"-2.710505431213761085e-20",
"-0x8.0000000000000000E-17#66",
);
// - x_exp == y_exp && a1 != 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.0",
"0x1.0000000000000000#65",
"1.00000000000000000011",
"0x1.0000000000000002#65",
"-1.084202172485504434e-19",
"-0x2.0000000000000000E-16#65",
);
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_gt_w_lt_2w
// - neg in sub_float_significands_same_prec_gt_w_lt_2w
// - rm == Nearest in sub_float_significands_same_prec_gt_w_lt_2w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) &&
// !overflow in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.00000000000000000005",
"0x1.0000000000000001#65",
"4.0",
"0x4.0000000000000000#65",
"-3.0",
"-0x3.0000000000000000#65",
);
// - !neg in sub_float_significands_same_prec_gt_w_lt_2w
test(
"4.0",
"0x4.0000000000000000#65",
"1.00000000000000000005",
"0x1.0000000000000001#65",
"3.0",
"0x3.0000000000000000#65",
);
// - rm == Nearest && (round_bit == 0 || (sticky_bit == 0 && (diff_0 & shift_bit) == 0)) in
// sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.00000000000000000016",
"0x1.0000000000000003#65",
"4.0",
"0x4.0000000000000000#65",
"-2.9999999999999999998",
"-0x2.fffffffffffffffc#65",
);
// - Limb::WIDTH <= exp_diff < Limb::WIDTH * 2 in sub_float_significands_same_prec_gt_w_lt_2w
// - Limb::WIDTH < exp_diff < Limb::WIDTH * 2 in sub_float_significands_same_prec_gt_w_lt_2w
// - Limb::WIDTH <= exp_diff < Limb::WIDTH * 2 && a1 >= HIGH_BIT in
// sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.44020837962004126031156726e28",
"0x2.e891fdf020840728c0894E+23#85",
"18.63123034252626794758647",
"0x12.a1984fcd64a8ae228eef#85",
"1.44020837962004126031156726e28",
"0x2.e891fdf020840728c0894E+23#85",
);
// - x_exp != y_exp && leading_zeros == 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"0.0001507756106295330606262754053",
"0x0.0009e19851127b95dcf03f0cdc#91",
"3458.565842843038054059107814",
"0xd82.90db1399862ba513faf8#91",
"-3458.565692067427424526047188",
"-0xd82.90d132013519297e1e08#91",
);
// - exp_diff >= Limb::WIDTH * 2 in sub_float_significands_same_prec_gt_w_lt_2w
// - exp_diff >= Limb::WIDTH * 2 && a1 >= HIGH_BIT in
// sub_float_significands_same_prec_gt_w_lt_2w
test(
"4.8545822922649671226e27",
"0xf.af9dc963a0709f78E+22#65",
"1.14823551075108882469e-96",
"0x2.73dea72af3fe6314E-80#65",
"4.8545822922649671226e27",
"0xf.af9dc963a0709f78E+22#65",
);
// - exp_diff == Limb::WIDTH in sub_float_significands_same_prec_gt_w_lt_2w
test(
"19585.2851423168986928116147584507795",
"0x4c81.48ff163dc91a0d4bd90309b0f8#116",
"372369974082165972902790.766638151683",
"0x4eda377c7f0d747fa386.c44265dd58#116",
"-372369974082165972883205.481495834785",
"-0x4eda377c7f0d747f5705.7b434f9f90#116",
);
// - Limb::WIDTH <= exp_diff < Limb::WIDTH * 2 && a1 < HIGH_BIT in
// sub_float_significands_same_prec_gt_w_lt_2w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) &&
// overflow in sub_float_significands_same_prec_gt_w_lt_2w
test(
"9.9035203142830421991929938e27",
"0x2.000000000000000000000E+23#85",
"16.0",
"0x10.00000000000000000000#85",
"9.9035203142830421991929938e27",
"0x2.000000000000000000000E+23#85",
);
// - exp_diff >= Limb::WIDTH * 2 && a1 < HIGH_BIT in sub_float_significands_same_prec_gt_w_lt_2w
test(
"5.3455294200288159103345444e-51",
"0x1.ffffffffc000000000000E-42#83",
"8.0",
"0x8.00000000000000000000#83",
"-8.0",
"-0x8.00000000000000000000#83",
);
// - x_exp != y_exp && a1 == 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"4.00000000000000000000084702",
"0x4.000000000000000003fffc#89",
"3.999999999999999999999999994",
"0x3.fffffffffffffffffffffe#89",
"8.47026484905764768539612568e-22",
"0x3.fffe000000000000000000E-18#89",
);
// - in sub_float_significands_same_prec_2w
// - x_exp == y_exp in sub_float_significands_same_prec_2w
// - a1 == 0 && a0 == 0 in sub_float_significands_same_prec_2w
test(
"1.0",
"0x1.00000000000000000000000000000000#128",
"1.0",
"0x1.00000000000000000000000000000000#128",
"0.0",
"0x0.0",
);
// - x_exp != y_exp in sub_float_significands_same_prec_2w
// - x_exp < y_exp in sub_float_significands_same_prec_2w
// - exp_diff < Limb::WIDTH in sub_float_significands_same_prec_2w
// - a1 != 0 second time in sub_float_significands_same_prec_2w
// - a1 != 0 third time in sub_float_significands_same_prec_2w
// - x_exp != y_exp && leading_zeros != 0 in sub_float_significands_same_prec_2w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_2w
test(
"1.0",
"0x1.00000000000000000000000000000000#128",
"2.0",
"0x2.00000000000000000000000000000000#128",
"-1.0",
"-0x1.00000000000000000000000000000000#128",
);
// - (a1 != 0 || a0 != 0) && a1 >= x_1 in sub_float_significands_same_prec_2w
// - a1 == 0 first time in sub_float_significands_same_prec_2w
// - x_exp == y_exp && leading_zeros != 0 in sub_float_significands_same_prec_2w
test(
"1.0",
"0x1.00000000000000000000000000000000#128",
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#128",
"-5.87747175411143753984368268611122838909e-39",
"-0x2.00000000000000000000000000000000E-32#128",
);
// - (a1 != 0 || a0 != 0) && a1 < x_1 in sub_float_significands_same_prec_2w
test(
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#128",
"1.0",
"0x1.00000000000000000000000000000000#128",
"5.87747175411143753984368268611122838909e-39",
"0x2.00000000000000000000000000000000E-32#128",
);
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_2w
// - neg in sub_float_significands_same_prec_2w
// - rm == Nearest in sub_float_significands_same_prec_2w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & 1) != 0) && !overflow in
// sub_float_significands_same_prec_2w
test(
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#128",
"4.0",
"0x4.00000000000000000000000000000000#128",
"-3.0",
"-0x3.00000000000000000000000000000000#128",
);
// - !neg in sub_float_significands_same_prec_2w
test(
"4.0",
"0x4.00000000000000000000000000000000#128",
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#128",
"3.0",
"0x3.00000000000000000000000000000000#128",
);
// - rm == Nearest && (round_bit == 0 || (sticky_bit == 0 && (diff_0 & 1) == 0)) in
// sub_float_significands_same_prec_2w
test(
"1.000000000000000000000000000000000000018",
"0x1.00000000000000000000000000000006#128",
"4.0",
"0x4.00000000000000000000000000000000#128",
"-2.99999999999999999999999999999999999998",
"-0x2.fffffffffffffffffffffffffffffff8#128",
);
// - x_exp != y_exp && leading_zeros == 0 in sub_float_significands_same_prec_2w
test(
"1.91698663575347889601435178329077738407e-37",
"0x4.13b4f0d218450fb6f5f6d50e7b8f6eb0E-31#128",
"8.0669110092962644724944820639408319804e-34",
"0x4.3046c1d7c0f5b6be39df2b03f3e49a70E-28#128",
"-8.06499402266051099359846771215754120301e-34",
"-0x4.30058688b3d4326d3e6fcb96a2fce178E-28#128",
);
// - exp_diff >= Limb::WIDTH * 2 in sub_float_significands_same_prec_2w
// - x_1 > HIGH_BIT || x_0 > 0 in sub_float_significands_same_prec_2w
test(
"5.80991149045382428948889299639419733262e-6",
"0x0.00006179613d776a1c835894818a219f488e8#128",
"5.07801249136957145270807726205511855421e-45",
"0x1.cfd8608b7c32de2bbcfecf8bcf8a2d00E-37#128",
"5.80991149045382428948889299639419733262e-6",
"0x0.00006179613d776a1c835894818a219f488e8#128",
);
// - Limb::WIDTH <= exp_diff < Limb::WIDTH * 2 in sub_float_significands_same_prec_2w
// - Limb::WIDTH < exp_diff < Limb::WIDTH * 2 in sub_float_significands_same_prec_2w
// - a1 >= HIGH_BIT in sub_float_significands_same_prec_2w
test(
"4354249796990942.35435357526597783143164",
"0xf782ac869b7de.5ab6ea78fcf0cc5079f#128",
"8.03239453825726512240307053405256016022e-10",
"0x3.732bce7aa121827a284545a25f32dc68E-8#128",
"4354249796990942.35435357446273837760591",
"0xf782ac869b7de.5ab6ea7589c4fdd5d8d#128",
);
// - a1 != 0 first time in sub_float_significands_same_prec_2w
test(
"852777855057.113455599443829872557360137",
"0xc68d856851.1d0b6d1928c98779f28bdd#128",
"869223500084.503694559376384046083491558",
"0xca61c20934.80f2206bb1d7d5cad69caa#128",
"-16445645027.39023895993255417352613142066",
"-0x3d43ca0e3.63e6b352890e4e50e410cd00#128",
);
// - exp_diff == Limb::WIDTH in sub_float_significands_same_prec_2w
test(
"1.057437459917463716438672572710788562701e-17",
"0xc.310127aae1df1a1cb12f60c4d339d76E-15#128",
"148.0549133677002965445211858794413066474",
"0x94.0e0ecd6e62d0a8c7c7c2a633277e3e#128",
"-148.054913367700296533946811280266669483",
"-0x94.0e0ecd6e62d0a804b7b02b85098c9c#128",
);
// - x_1 <= HIGH_BIT && x_0 <= 0 in sub_float_significands_same_prec_2w
// - exp_diff != TWICE_WIDTH || tst in sub_float_significands_same_prec_2w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & 1) != 0) && overflow in
// sub_float_significands_same_prec_2w
test(
"3.83123885216472214589586756787577295905e53",
"0x4.00000000000000000000000000000000E+44#128",
"9.09494703466994132423639742106012939545e-13",
"0x1.00000008000000000000007fffffff80E-10#128",
"3.83123885216472214589586756787577295905e53",
"0x4.00000000000000000000000000000000E+44#128",
);
// - a1 < HIGH_BIT in sub_float_significands_same_prec_2w
test(
"0.000473141670219947088192358501321236008969",
"0x0.001f01fffffe001ffe000000000003ffff0#128",
"144115188075855872.000000000007275846592",
"0x200000000000000.0000000007fff80000#128",
"-144115188075855871.9995268583370558995037",
"-0x1ffffffffffffff.ffe0fe000801f7e002#128",
);
// - a1 == 0 second time in sub_float_significands_same_prec_2w
test(
"1.192092895507812500000000000000000918348e-7",
"0x2.0000000000000000000000000007fffcE-6#128",
"1.19209289550781249999999999999999632658e-7",
"0x1.ffffffffffffffffffffffffffe00000E-6#128",
"4.5917678014072389539175224798764807294e-40",
"0x2.7fffc000000000000000000000000000E-33#128",
);
// - exp_diff == TWICE_WIDTH && !tst in sub_float_significands_same_prec_2w
test(
"1024.0",
"0x400.000000000000000000000000000000#128",
"5.97151130219911582898625687582100437209e-36",
"0x7.f00000001fffffffffffffffe0000000E-30#128",
"1023.999999999999999999999999999999999994",
"0x3ff.fffffffffffffffffffffffffffff8#128",
);
// - x_exp == y_exp && leading_zeros == 0 in sub_float_significands_same_prec_2w
test(
"0.249999999999999999999999999974756451033",
"0x0.3ffffffffffffffffffffffe000000000#128",
"0.2499999999999999999864474728691747435412",
"0x0.3fffffffffffffffc0000001ffffffffc#128",
"1.35525271055817074916830884337875729072e-20",
"0x3.ffffffc0000000040000000000000000E-17#128",
);
// - a1 == 0 third time in sub_float_significands_same_prec_2w
test(
"8.0",
"0x8.0000000000000000000000000000000#128",
"7.99999999999999999999999999999999999998",
"0x7.fffffffffffffffffffffffffffffff8#128",
"2.35098870164457501593747307444449135564e-38",
"0x8.0000000000000000000000000000000E-32#128",
);
// - in sub_float_significands_same_prec_gt_2w_lt_3w
// - x_exp == y_exp in sub_float_significands_same_prec_gt_2w_lt_3w
// - a2 == 0 && a1 == 0 && a0 == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.0",
"0x1.00000000000000000000000000000000#129",
"1.0",
"0x1.00000000000000000000000000000000#129",
"0.0",
"0x0.0",
);
// - x_exp != y_exp in sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff < Limb::WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff < Limb::WIDTH && sticky_bit == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff < Limb::WIDTH && a2 != 0 first time in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff < Limb::WIDTH && leading_zeros != 0 in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.0",
"0x1.00000000000000000000000000000000#129",
"2.0",
"0x2.00000000000000000000000000000000#129",
"-1.0",
"-0x1.00000000000000000000000000000000#129",
);
// - x_exp >= y_exp in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"2.0",
"0x2.00000000000000000000000000000000#129",
"1.0",
"0x1.00000000000000000000000000000000#129",
"1.0",
"0x1.00000000000000000000000000000000#129",
);
// - (a2 != 0 || a1 != 0 || a0 != 0) && a2 >= x_2 in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - x_exp == y_exp && a2 == 0 first time in sub_float_significands_same_prec_gt_2w_lt_3w
// - x_exp == y_exp && a2 == 0 second time in sub_float_significands_same_prec_gt_2w_lt_3w
// - x_exp == y_exp && leading_zeros == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.0",
"0x1.00000000000000000000000000000000#129",
"1.000000000000000000000000000000000000003",
"0x1.00000000000000000000000000000001#129",
"-2.93873587705571876992184134305561419455e-39",
"-0x1.00000000000000000000000000000000E-32#129",
);
// - (a2 != 0 || a1 != 0 || a0 != 0) && a2 < x_2 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.000000000000000000000000000000000000003",
"0x1.00000000000000000000000000000001#129",
"1.0",
"0x1.00000000000000000000000000000000#129",
"2.93873587705571876992184134305561419455e-39",
"0x1.00000000000000000000000000000000E-32#129",
);
// - x_exp == y_exp && leading_zeros != 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.0",
"0x1.000000000000000000000000000000000#130",
"1.000000000000000000000000000000000000001",
"0x1.000000000000000000000000000000008#130",
"-1.469367938527859384960920671527807097273e-39",
"-0x8.00000000000000000000000000000000E-33#130",
);
// - x_exp == y_exp && a2 != 0 second time in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.0",
"0x1.00000000000000000000000000000000#129",
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#129",
"-5.87747175411143753984368268611122838909e-39",
"-0x2.00000000000000000000000000000000E-32#129",
);
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_gt_2w_lt_3w
// - neg in sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest in sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) &&
// overflow in sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) && diff_1
// == 0 && diff_0 == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest && diff_2 != 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.000000000000000000000000000000000000003",
"0x1.00000000000000000000000000000001#129",
"4.0",
"0x4.00000000000000000000000000000000#129",
"-3.0",
"-0x3.00000000000000000000000000000000#129",
);
// - !neg in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"4.0",
"0x4.00000000000000000000000000000000#129",
"1.000000000000000000000000000000000000003",
"0x1.00000000000000000000000000000001#129",
"3.0",
"0x3.00000000000000000000000000000000#129",
);
// - rm == Nearest && round_bit == 0 || (sticky_bit == 0 && (diff_0 & shift_bit) == 0) in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.000000000000000000000000000000000000009",
"0x1.00000000000000000000000000000003#129",
"4.0",
"0x4.00000000000000000000000000000000#129",
"-2.999999999999999999999999999999999999988",
"-0x2.fffffffffffffffffffffffffffffffc#129",
);
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) &&
// (diff_1 != 0 || diff_0 != 0) in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"2.000000000000000000000000000000000000006",
"0x2.00000000000000000000000000000002#129",
"0.500000000000000000000000000000000000001",
"0x0.800000000000000000000000000000008#129",
"1.500000000000000000000000000000000000006",
"0x1.80000000000000000000000000000002#129",
);
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) &&
// !overflow in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"2.000000000000000000000000000000000000003",
"0x2.00000000000000000000000000000001#130",
"0.5000000000000000000000000000000000000007",
"0x0.800000000000000000000000000000004#130",
"1.500000000000000000000000000000000000003",
"0x1.800000000000000000000000000000010#130",
);
// - TWICE_WIDTH <= exp_diff < THRICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - TWICE_WIDTH < exp_diff < THRICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - TWICE_WIDTH <= exp_diff < THRICE_WIDTH && a2 >= HIGH_BIT in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"2.024076700393272432111968987625898501371897741e-29",
"0x1.9a88122864b9c4b577e4b655958954f82345dE-24#149",
"245906107849378561117126906.9059035528266331265",
"0xcb68a4d1611415054400fa.e7e94b94b8791630#149",
"-245906107849378561117126906.9059035528266331265",
"-0xcb68a4d1611415054400fa.e7e94b94b8791630#149",
);
// - exp_diff >= THRICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff >= THRICE_WIDTH && a2 >= HIGH_BIT in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"4.397610888919711045634814958598336677777534377e47",
"0x4.d0791b9428a6b4fc52e44e537ab5a0f269ad60E+39#155",
"6.8892360159362421595728818935378487832685754059e-50",
"0x1.9c693c182df3035eef00d41638bbdd942f4d498E-41#155",
"4.397610888919711045634814958598336677777534377e47",
"0x4.d0791b9428a6b4fc52e44e537ab5a0f269ad60E+39#155",
);
// - exp_diff < Limb::WIDTH && leading_zeros == 0 in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"4.9709672065181108960570410290811793724062284431352e-48",
"0x7.43dc113e95ca123693650af31435eac45c0e7a680E-40#165",
"5.2183974782595301717751266872943662193587933931613e-47",
"0x4.c4457ca8b3429511981a96eb0c2de4fdb8c43bea4E-39#165",
"-4.7213007576077190821694225843862482821181705488478e-47",
"-0x4.5007bb94c9e5f3ee2ee4463bdaea865173035443cE-39#165",
);
// - exp_diff < Limb::WIDTH && sticky_bit != 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"8.264811372870109665580646414654919646529224699888394e-20",
"0x1.864b7049feb3dcfe49ea910db778157cbe9c2021b44E-16#171",
"0.0007337187065343299500100945131574173571435306249470578",
"0x0.003015c1d959ec54ab97dc58b77c22566586c06119b810#171",
"-0.0007337187065343298673619807844563207013370664783978612",
"-0x0.003015c1d959ec53254c6c0eb8c845581b9c2f53623ff8#171",
);
// - Limb::WIDTH <= exp_diff < TWICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - Limb::WIDTH < exp_diff < TWICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - Limb::WIDTH < exp_diff < TWICE_WIDTH && sticky_bit != 0 in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - Limb::WIDTH < exp_diff < TWICE_WIDTH && a2 >= HIGH_BIT in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"4.2850537238606374652351877988811796373898773e-22",
"0x2.0607fd4819748c532aad3528693c1e3c1966E-18#146",
"978.49328809934495391839880801989439981236569",
"0x3d2.7e4820fe314caadcb9a156bef2f1c8e53c#146",
"-978.49328809934495391839837951452201374861917",
"-0x3d2.7e4820fe314caadcb79b4ec1aad85458e9#146",
);
// - Limb::WIDTH < exp_diff < TWICE_WIDTH && sticky_bit == 0 in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"0.4575080253178526499352273198671695352442",
"0x0.751f3ef665d0ca4dfa2d089979c4e9600#130",
"184366716174337778394.1535133791267987587",
"0x9fe9a278b38ab22da.274ca71ed919c918#130",
"-184366716174337778393.6960053538089461089",
"-0x9fe9a278b38ab22d9.b22d68287348fecc#130",
);
// - x_exp == y_exp && a2 != 0 first time in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"229.1456159244630209666077998586332154002628588961962846344",
"0xe5.254715d158717849f7198986a38cb415eeea3464b1df38#189",
"175.1335582002789888688278442018847623084238889142385801004",
"0xaf.2230dec64f958583522e37252cf610378914f3127d0bb0#189",
"54.01205772418403209777995565674845309183896998195770453405",
"0x36.0316370b08dbf2c6a4eb52617696a3de65d5415234d388#189",
);
// - exp_diff == TWICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"563971925627753843356041629019151473018178607215.42",
"0x62c960337e963a378ba6626ea422d8a5e623986f.6c#165",
"1301375421.83361702516620516356439489325145225661938",
"0x4d9169bd.d567ece47a47ef60371d48c969ba8765d4#165",
"563971925627753843356041629019151473016877231793.59",
"0x62c960337e963a378ba6626ea422d8a598922eb1.98#165",
);
// - exp_diff == Limb::WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"226.9305090753243797994707628568605406194",
"0xe2.ee35d7bf263fda8c632644ad7c49d98#130",
"4262448175090788889452.984188256984861391",
"0xe71159efd3a67e736c.fbf3c2f8db72fb8#130",
"-4262448175090788889226.053679181660481592",
"-0xe71159efd3a67e728a.0dbdeb39b533210#130",
);
// - TWICE_WIDTH <= exp_diff < THRICE_WIDTH && a2 < HIGH_BIT in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest && diff_2 == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"0.0001220703125",
"0x0.0008000000000000000000000000000000000000#145",
"8.2855746158774225568154012162196749515653053e-50",
"0x1.f0000fc000000000000003fffffffffffffcE-41#145",
"0.0001220703125",
"0x0.0008000000000000000000000000000000000000#145",
);
// - Limb::WIDTH < exp_diff < TWICE_WIDTH && a2 < HIGH_BIT in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"0.0156250000000000000000000000252435487789932816416198",
"0x0.040000000000000000000001ffffffc00000000003f#167",
"2.11758236813575084767080625169910490512847748461541e-22",
"0xf.ffffffffffffffffffffffffffffffffff0000000E-19#167",
"0.0156249999999999999997882417884299736942262010164499",
"0x0.03ffffffffffffffff000001ffffffc00000000003f0#167",
);
// - exp_diff >= THRICE_WIDTH && a2 < HIGH_BIT in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.028440348325753776346855739098344065614209916020987e62",
"0x4.000000000000000000000000000000000000000000E+51#168",
"0.00781238079073842683897073489057921223679527623088422",
"0x0.01fffe000007e000000038000007fffffffffe000000#168",
"1.028440348325753776346855739098344065614209916020987e62",
"0x4.000000000000000000000000000000000000000000E+51#168",
);
// - exp_diff < Limb::WIDTH && a2 == 0 first time in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff < Limb::WIDTH && a2 != 0 second time in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"32767.9999999999999999999999999999999999999999996",
"0x7fff.fffffffffffffffffffffffffffffffffff8#156",
"32768.0000000000000000069388939039072268369037424",
"0x8000.000000000000007ffffffffffff80000000#156",
"-6.93889390390722683690374277451135137549581608853e-18",
"-0x7.ffffffffffff800000008000000000000000000E-15#156",
);
// - exp_diff < Limb::WIDTH && a2 == 0 second time in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"137438953471.99999999999999999999999999999",
"0x1fffffffff.ffffffffffffffffffffffff#133",
"137438953472.0",
"0x2000000000.000000000000000000000000#133",
"-1.2621774483536188886587657044524579674771e-29",
"-0x1.000000000000000000000000000000000E-24#133",
);
// - in sub_float_significands_same_prec_ge_3w
// - x_exp == y_exp in sub_float_significands_same_prec_ge_3w
// - k < 0 in sub_float_significands_same_prec_ge_3w
test(
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
"0.0",
"0x0.0",
);
// - x_exp > y_exp in sub_float_significands_same_prec_ge_3w
// - exp_diff == 1 in sub_float_significands_same_prec_ge_3w
// - !goto_sub_d1_no_lose && !goto_sub_d1_lose in sub_float_significands_same_prec_ge_3w
// - limb < HIGH_BIT in sub_float_significands_same_prec_ge_3w
// - exp_diff == 0 in sub_float_significands_same_prec_ge_3w
// - goto_exact_normalize in sub_float_significands_same_prec_ge_3w
// - limb != 0 in sub_float_significands_same_prec_ge_3w
// - exp_diff == 0 && limb != 0 && leading_zeros == 0 in sub_float_significands_same_prec_ge_3w
test(
"2.0",
"0x2.000000000000000000000000000000000000000000000000#192",
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
);
// - k >= 0 && xs[k] < ys[k] in sub_float_significands_same_prec_ge_3w
// - !goto_exact_normalize in sub_float_significands_same_prec_ge_3w
// - limb == 0 in sub_float_significands_same_prec_ge_3w
// - out[usize::exact_from(k)] != 0 in sub_float_significands_same_prec_ge_3w
// - limb == 0 && leading_zeros != 0 in sub_float_significands_same_prec_ge_3w
test(
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#192",
"-3.186183822264904554057760795535423611182209110385237572148e-58",
"-0x2.000000000000000000000000000000000000000000000000E-48#192",
);
// - k >= 0 && xs[k] >= ys[k] in sub_float_significands_same_prec_ge_3w
test(
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#192",
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
"3.186183822264904554057760795535423611182209110385237572148e-58",
"0x2.000000000000000000000000000000000000000000000000E-48#192",
);
// - exp_diff == 0 && limb != 0 && leading_zeros != 0 in sub_float_significands_same_prec_ge_3w
test(
"2.0",
"0x2.000000000000000000000000000000000000000000000000#192",
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#192",
"0.9999999999999999999999999999999999999999999999999999999997",
"0x0.fffffffffffffffffffffffffffffffffffffffffffffffe#192",
);
// - 2 <= exp_diff < prec in sub_float_significands_same_prec_ge_3w
// - dm != 0 && m == 0 in sub_float_significands_same_prec_ge_3w
// - sx != 0 in sub_float_significands_same_prec_ge_3w
// - !out[n - 1].get_highest_bit() in sub_float_significands_same_prec_ge_3w
// - round_bit == 0 in sub_float_significands_same_prec_ge_3w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_ge_3w
test(
"2.0",
"0x2.000000000000000000000000000000000000000000000000#192",
"0.5",
"0x0.800000000000000000000000000000000000000000000000#192",
"1.5",
"0x1.800000000000000000000000000000000000000000000000#192",
);
// - limb == 0 && leading_zeros == 0 in sub_float_significands_same_prec_ge_3w
test(
"1.0",
"0x1.000000000000000000000000000000000000000000000000#193",
"1.0000000000000000000000000000000000000000000000000000000002",
"0x1.000000000000000000000000000000000000000000000001#193",
"-1.5930919111324522770288803977677118055911045551926187860739e-58",
"-0x1.000000000000000000000000000000000000000000000000E-48#193",
);
// - sx == 0 in sub_float_significands_same_prec_ge_3w
test(
"2.0",
"0x2.000000000000000000000000000000000000000000000000#193",
"0.5",
"0x0.8000000000000000000000000000000000000000000000000#193",
"1.5",
"0x1.800000000000000000000000000000000000000000000000#193",
);
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_ge_3w
// - out_power_of_2 || round_bit == 0 in sub_float_significands_same_prec_ge_3w
// - rm == Nearest in sub_float_significands_same_prec_ge_3w
// - rm == Nearest && !out_power_of_2 first time in sub_float_significands_same_prec_ge_3w
// - rm == Nearest && (round_bit == 0 || (round_bit != 0 && sticky_bit == 0 && (out[0] &
// shift_bit == 0 || prec == 1))) in sub_float_significands_same_prec_ge_3w
test(
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#192",
"4.0",
"0x4.000000000000000000000000000000000000000000000000#192",
"-3.0",
"-0x3.000000000000000000000000000000000000000000000000#192",
);
// - out[usize::exact_from(k)] == 0 in sub_float_significands_same_prec_ge_3w
test(
"1.0000000000000000000000000000000000000000000000000000000002",
"0x1.000000000000000000000000000000000000000000000001#193",
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#193",
"-1.5930919111324522770288803977677118055911045551926187860739e-58",
"-0x1.000000000000000000000000000000000000000000000000E-48#193",
);
// - round_bit != 0 in sub_float_significands_same_prec_ge_3w
test(
"1.0000000000000000000000000000000000000000000000000000000006",
"0x1.000000000000000000000000000000000000000000000004#192",
"4.0",
"0x4.000000000000000000000000000000000000000000000000#192",
"-2.9999999999999999999999999999999999999999999999999999999994",
"-0x2.fffffffffffffffffffffffffffffffffffffffffffffffc#192",
);
// - rm == Nearest && round_bit != 0 && (round_bit == 0 || sticky_bit != 0 || (out[0] &
// shift_bit != 0 && prec == 1)) in sub_float_significands_same_prec_ge_3w
// - rm == Nearest && !out_power_of_2 second time in sub_float_significands_same_prec_ge_3w
test(
"1.000000000000000000000000000000000000000000000000000000001",
"0x1.000000000000000000000000000000000000000000000006#192",
"4.0",
"0x4.000000000000000000000000000000000000000000000000#192",
"-2.9999999999999999999999999999999999999999999999999999999987",
"-0x2.fffffffffffffffffffffffffffffffffffffffffffffff8#192",
);
// - sticky_bit_2 == 0 && k > 0 third time in sub_float_significands_same_prec_ge_3w
test(
"0.5",
"0x0.8000000000000000000000000000000000000000000000000#193",
"4.0",
"0x4.000000000000000000000000000000000000000000000000#193",
"-3.5",
"-0x3.800000000000000000000000000000000000000000000000#193",
);
// - sticky_bit_2 != 0 || k <= 0 third time in sub_float_significands_same_prec_ge_3w
test(
"4.0",
"0x4.000000000000000000000000000000000000000000000000#192",
"0.5000000000000000000000000000000000000000000000000000000002",
"0x0.800000000000000000000000000000000000000000000001#192",
"3.5",
"0x3.800000000000000000000000000000000000000000000000#192",
);
// - dm != 0 && m != 0 in sub_float_significands_same_prec_ge_3w
// - out[n - 1].get_highest_bit() in sub_float_significands_same_prec_ge_3w
test(
"7.28057116938384227432903448367767196428679514765398378973101e-48",
"0xa.a3fc2da1f20fb2d9771f86d3c16a444cd62d5d139e3935f24E-40#198",
"3.5123473778825578958968695187657587760357139395948269588971e-27",
"0x1.1646de419a6dbd3466f3081403a87d719b7a765a1ec69e4658E-22#198",
"-3.51234737788255789588958894759637493376138490511114928693281e-27",
"-0x1.1646de419a6dbd345c4f0be661b66dbec20356d34b05340208E-22#198",
);
// - exp_diff >= prec in sub_float_significands_same_prec_ge_3w
// - exp_diff > prec in sub_float_significands_same_prec_ge_3w
// - exp_diff != prec + 1 in sub_float_significands_same_prec_ge_3w
test(
"4.1322282880219162156901559575161649173615955518072607291207e86",
"0xd.4b575f05941ee41ef3ef9a37068d9d453f22eb3bf80bd1b0E+71#193",
"0.023991386767031193042066748710708351501952890752924613005724",
"0x0.06244cad8cd272134e34b325815ad281733f2c06231a0ee744#193",
"4.1322282880219162156901559575161649173615955518072607291207e86",
"0xd.4b575f05941ee41ef3ef9a37068d9d453f22eb3bf80bd1b0E+71#193",
);
// - dm == 0 in sub_float_significands_same_prec_ge_3w
test(
"6.442552350746554109885349691592991892989624685631192235549e-6",
"0x0.00006c168d38e231899f0fc85d1888549d5177bdceaee72e15060#192",
"1476808010161862576835936576709144.7975622615653024045505082",
"0x48cff00a780a50d34bb694ada218.cc2d0a55f25f9f9126258#192",
"-1476808010161862576835936576709144.7975558190129516579963983",
"-0x48cff00a780a50d34bb694ada218.cc2c9e3f6526bd5f9c868#192",
);
// - exp_diff == prec + 1 in sub_float_significands_same_prec_ge_3w
// - sticky_bit_2 != 0 || k <= 0 second time in sub_float_significands_same_prec_ge_3w
test(
"29249291732025621624535078208.59212499364958152526111994335",
"0x5e827271f9e9d261e7cb5540.979580eade814aae28ae9d3c8#192",
"1.7056859397843570965021420438616279890690624515282312011749e-30",
"0x2.2986d80d04731f28b49380410e3f4711dc2cc5f113c594a0E-25#192",
"29249291732025621624535078208.59212499364958152526111994335",
"0x5e827271f9e9d261e7cb5540.979580eade814aae28ae9d3c8#192",
);
// - limb > HIGH_BIT in sub_float_significands_same_prec_ge_3w
// - y0 != 0 in sub_float_significands_same_prec_ge_3w
test(
"1958139908729.1847354007541959640287427302874567071533816044",
"0x1c7ea3bd279.2f4ad1b8a7190307771c7e5767590237208b90#192",
"688604646855.2266320591592881661509057171162297144871538944",
"0xa054090dc7.3a048f025074a63da83a500a235d2b8fd9766d#192",
"1269535261873.9581033415949077978778370131712269926662277102",
"0x1279632c4b1.f54642b656a45cc9cee22e4d43fbd6a7471524#192",
);
// - y0 == 0 in sub_float_significands_same_prec_ge_3w
test(
"2473299914875391681216.10395653853096422269749051583697615",
"0x8613ee70797f97a2c0.1a9ce54d32239153edab6ff15dad1c0#193",
"7716446651886500012256.87778108230244207876352217543002925",
"0x1a24f3592677b2760e0.e0b642d189564d3b4c797ad9c9cde8#193",
"-5243146737011108331040.7738245437714778560660316595930531",
"-0x11c3b4721edfb8fbe20.c6195d845732bbe75ece0ae86c20cc#193",
);
// - exp_diff == prec in sub_float_significands_same_prec_ge_3w
// - sticky_bit_2 != 0 || k <= 0 first time in sub_float_significands_same_prec_ge_3w
test(
"4.0635838402455207229400698207668893925379768151364313942222e-23",
"0x3.1202ecf10ff40b477337957dede18bd7b746884ec977474eE-19#194",
"1174582238252884689829665592721065057.76655867827770290150723",
"0xe237601fa3ed6d89b0ae33e924c461.c43d3085aaefab6b5d4#194",
"-1174582238252884689829665592721065057.76655867827770290150718",
"-0xe237601fa3ed6d89b0ae33e924c461.c43d3085aaefab6b5d0#194",
);
// - rm == Nearest && out_power_of_2 first time in sub_float_significands_same_prec_ge_3w
test(
"22300745198530623141535718272648361505980416.0",
"0x1000000000000000000000000000000000000.000000000000#192",
"8.470329472543003387009805160583577341645369940072346001613e-22",
"0x3.ffffffffffffffe000000003ff0000003ffffffc00000000E-18#192",
"22300745198530623141535718272648361505980416.0",
"0x1000000000000000000000000000000000000.000000000000#192",
);
// - sticky_bit_2 == 0 && k > 0 second time in sub_float_significands_same_prec_ge_3w
test(
"1.6849966666969146159452711670928107852024276704905067469395e66",
"0xf.ffffffffffff01fffff00000000000000000000000000000E+54#193",
"33554432.00000000000000044408920985006261616945266723632812",
"0x2000000.0000000000001ffffffffffffffffffffffffffffe#193",
"1.6849966666969146159452711670928107852024276704905067469395e66",
"0xf.ffffffffffff01fffff00000000000000000000000000000E+54#193",
);
// - limb == HIGH_BIT in sub_float_significands_same_prec_ge_3w
// - l >= 0 first time in sub_float_significands_same_prec_ge_3w
// - xs[l] != yl_shifted in sub_float_significands_same_prec_ge_3w
// - l >= 0 && xs[l] <= yl_shifted in sub_float_significands_same_prec_ge_3w
// - goto_sub_d1_no_lose || goto_sub_d1_lose in sub_float_significands_same_prec_ge_3w
test(
"2047.9999999999999999999999999999747564510329303127198868805",
"0x7ff.fffffffffffffffffffffffe00000000003c000003fffc#193",
"4095.99999999999999988897769753748434595763683319091796875",
"0xfff.fffffffffffff800000000000000000000000000000000#193",
"-2047.9999999999999998889776975375095895066039028781980818695",
"-0x7ff.fffffffffffff80000000001ffffffffffc3fffffc0004#193",
);
// - sticky_bit_2 == 0 && k > 0 first time in sub_float_significands_same_prec_ge_3w
test(
"0.0002442598197376355528831482438462803411504065058668775410457",
"0x0.001001fff000000000000003ffff00000001fffffff07fffffe#192",
"5.834076822994820350447560050418866475553361427251759468222e-62",
"0x1.8000000000000000000000000000000000001c00007ffffeE-51#192",
"0.00024425981973763555288314824384628034115040650586687754104564",
"0x0.001001fff000000000000003ffff00000001fffffff07fffffc#192",
);
// - l >= 0 && xs[l] > yl_shifted in sub_float_significands_same_prec_ge_3w
test(
"127.99999999999999999999998841947063540272586186468301133273",
"0x7f.fffffffffffffffffff1fffff00007ffffffffffffffff8#192",
"255.99999999999999999999999979320484686174308128214782699291",
"0xff.ffffffffffffffffffffc00000000000000000000000ff#192",
"-128.0000000000000000000000113737342114590172194174648156602",
"-0x80.0000000000000000000dc0000ffff80000000000000100#192",
);
// - out_power_of_2 && round_bit != 0 in sub_float_significands_same_prec_ge_3w
test(
"81129638414606681695789005144064.0",
"0x400000000000000000000000000.0000000000000000000000#193",
"6.46392625738094777466974989455420015132331189664152496326e-27",
"0x2.001ffffffffe0000001fffff000000ffffff80000000000eE-22#193",
"81129638414606681695789005144063.999999999999999999999999994",
"0x3ffffffffffffffffffffffffff.fffffffffffffffffffffe#193",
);
// - rm == Nearest && out_power_of_2 second time in sub_float_significands_same_prec_ge_3w
test(
"9.5367431640625e-7",
"0x0.00001000000000000000000000000000000000000000000000000#192",
"7.596455102175746880546879414772134233793171691679642324806e-65",
"0x8.00000ffffffffffe000000000000000000000000001ffffE-54#192",
"9.536743164062499999999999999999999999999999999999999999998e-7",
"0xf.fffffffffffffffffffffffffffffffffffffffffffffffE-6#192",
);
// - xs[l] == yl_shifted in sub_float_significands_same_prec_ge_3w
test(
"1180591620717411303423.9999999999999999999999999999999999998",
"0x3fffffffffffffffff.ffffffffffffffffffffffffffffffc#192",
"2361183241434822606847.9999999999999999930619531290400259223",
"0x7fffffffffffffffff.ffffffffffffff8003ffffffffffff8#192",
"-1180591620717411303423.9999999999999999930619531290400259225",
"-0x3fffffffffffffffff.ffffffffffffff8003ffffffffffffc#192",
);
// - l < 0 first time in sub_float_significands_same_prec_ge_3w
// - l < 0 second time in sub_float_significands_same_prec_ge_3w
// - yl_shifted != 0 in sub_float_significands_same_prec_ge_3w
test(
"32767.999999999999999999999999999999999999999999999999999995",
"0x7fff.ffffffffffffffffffffffffffffffffffffffffffff8#192",
"65535.99999999999999999999999999999999999999999999999999999",
"0xffff.ffffffffffffffffffffffffffffffffffffffffffff#192",
"-32767.999999999999999999999999999999999999999999999999999995",
"-0x7fff.ffffffffffffffffffffffffffffffffffffffffffff8#192",
);
// - yl_shifted == 0 in sub_float_significands_same_prec_ge_3w
test(
"34359738367.999999999999999999999999999999999999999999999989",
"0x7ffffffff.fffffffffffffffffffffffffffffffffffffff0#192",
"68719476735.99999999999999999999999999999999999999999999999",
"0xfffffffff.fffffffffffffffffffffffffffffffffffffff#192",
"-34359738368.0",
"-0x800000000.000000000000000000000000000000000000000#192",
);
test("1.0", "0x1.0#1", "1.5", "0x1.8#2", "-0.5", "-0x0.8#2");
test("0.5", "0x0.8#1", "3.0", "0x3.0#2", "-2.0", "-0x2.0#2");
test("0.2", "0x0.4#1", "4.0", "0x4.0#2", "-4.0", "-0x4.0#2");
test(
"0.00374222828352849",
"0x0.00f5402c178824#46",
"1.07183972513958531257713938927815e-11",
"0xb.c8f5eafa12eb9821601f1dd6aeE-10#107",
"0.00374222827281009532032311766811006",
"0x0.00f5402c0bbf2e1505ed1467de9fe#107",
);
test(
"2589062031404.0",
"0x25ad01f682c.0#43",
"4351572166934988.581719655389852344796925751245753159273257621838622031922945531041952618\
810238932316",
"0xf75bb593981cc.94eb944f56fd85d744c7e812bf078ed9a4f5d3086fdab71e98a907840097016cb76fdc\
#330",
"-4348983104903584.58171965538985234479692575124575315927325762183862203192294553104195261\
8810238932316",
"-0xf7360891a19a0.94eb944f56fd85d744c7e812bf078ed9a4f5d3086fdab71e98a907840097016cb76fdc\
#330",
);
// - in sub_float_significands_general
// - in exponent_shift_compare
// - sdiff_exp >= 0 in exponent_shift_compare
// - diff_exp == 0 first time in exponent_shift_compare
// - xi >= 0 && yi >= 0 && xs[xi] == ys[yi] in exponent_shift_compare
// - xi < 0 in exponent_shift_compare
// - xi < 0 && yi < 0 in exponent_shift_compare
// - sign == Equal in sub_float_significands_general
test("1.0", "0x1.0#1", "1.0", "0x1.0#2", "0.0", "0x0.0");
// - diff_exp != 0 first time in exponent_shift_compare
// - diff_exp < Limb::WIDTH in exponent_shift_compare
// - diff_exp != 0 second time in exponent_shift_compare
// - (yi < 0 && lasty == 0) || high_dif != 0 || dif != 1 in exponent_shift_compare
// - high_dif == 0 in exponent_shift_compare
// - dif.is_power_of_2() in exponent_shift_compare
// - yi < 0 && lasty == 0 in exponent_shift_compare
// - sign != Equal in sub_float_significands_general
// - sign != Less in sub_float_significands_general
// - !neg in sub_float_significands_general
// - max(out_prec, x_prec) + 2 > exp_diff in sub_float_significands_general
// - shift_x != 0 in sub_float_significands_general
// - shift_y == 0 in sub_float_significands_general
// - cancel >= exp_diff in sub_float_significands_general
// - out_len + cancel1 <= xs_len in sub_float_significands_general
// - out_len + cancel2 > 0 in sub_float_significands_general
// - cancel2 >= 0 in sub_float_significands_general
// - out_len + cancel2 <= ys_len in sub_float_significands_general
// - rm == Nearest in sub_float_significands_general
// - rm == Nearest && carry <= Limb::power_of_2(sh - 1) && (0 >= carry || carry >=
// Limb::power_of_2(sh - 1)) in sub_float_significands_general
// - !goto_truncate in sub_float_significands_general
// - ixs_len <= 0 && iys_len <= 0 in sub_float_significands_general
// - !goto_truncate && !goto_end_of_sub second time in sub_float_significands_general
// - rm != Nearest || cmp_low == 0 in sub_float_significands_general
// - !goto_end_of_sub in sub_float_significands_general
// - out[out_len - 1] >> (Limb::WIDTH - 1) != 0 in sub_float_significands_general
// - cancel != 0 in sub_float_significands_general
test("2.0", "0x2.0#1", "1.0", "0x1.0#2", "1.0", "0x1.0#2");
// - sdiff_exp < 0 in exponent_shift_compare
// - sign == Less in sub_float_significands_general
// - neg in sub_float_significands_general
test("1.0", "0x1.0#2", "2.0", "0x2.0#1", "-1.0", "-0x1.0#2");
// - xi < 0 || yi < 0 || xs[xi] != ys[yi] in exponent_shift_compare
// - xi >= 0 in exponent_shift_compare
// - yi >= 0 second time in exponent_shift_compare
// - xs[xi] < ys[yi] in exponent_shift_compare
// - diff_exp == 0 second time in exponent_shift_compare
// - shift_y != 0 in sub_float_significands_general
test("1.0", "0x1.0#1", "1.5", "0x1.8#2", "-0.5", "-0x0.8#2");
// - xs[xi] >= ys[yi] in exponent_shift_compare
test("1.5", "0x1.8#2", "1.0", "0x1.0#1", "0.5", "0x0.8#2");
// - shift_x == 0 in sub_float_significands_general
// - cancel < exp_diff in sub_float_significands_general
// - ixs_len > 0 || iys_len > 0 in sub_float_significands_general
// - ixs_len <= 0 in sub_float_significands_general
// - iys_len condition in sub_float_significands_general
// - cmp_low == 0 first time in sub_float_significands_general
// - rm == Nearest && (sh != 0 || k != 0) in sub_float_significands_general
// - cmp_low == 0 second time in sub_float_significands_general
// - !goto_truncate && !goto_end_of_sub first time in sub_float_significands_general
// - cancel == 0 in sub_float_significands_general
test("0.5", "0x0.8#1", "1.5", "0x1.8#2", "-1.0", "-0x1.0#2");
// - !dif.is_power_of_2() in exponent_shift_compare
test("0.5", "0x0.8#1", "2.0", "0x2.0#2", "-1.5", "-0x1.8#2");
// - cmp_low != 0 first time in sub_float_significands_general
// - cmp_low > 0 in sub_float_significands_general
// - cmp_low > 0 && rm == Nearest in sub_float_significands_general
// - cmp_low > 0 && rm == Nearest && xx == yy in sub_float_significands_general
// - rm == Nearest && cmp_low != 0 in sub_float_significands_general
// - (out[0] >> sh) & 1 == 0 in sub_float_significands_general
test("0.5", "0x0.8#1", "3.0", "0x3.0#2", "-2.0", "-0x2.0#2");
// - (out[0] >> sh) & 1 != 0 in sub_float_significands_general
// - cmp_low >= 0 in sub_float_significands_general
// - cmp_low >= 0 && !carry in sub_float_significands_general
test("4.0", "0x4.0#1", "1.2", "0x1.4#3", "3.0", "0x3.0#3");
// - cmp_low >= 0 && carry in sub_float_significands_general
test("4.0", "0x4.0#1", "0.5", "0x0.8#2", "4.0", "0x4.0#2");
// - rm == Nearest && carry > Limb::power_of_2(sh - 1) in sub_float_significands_general
// - goto_truncate in sub_float_significands_general
test("3.0", "0x3.0#2", "0.2", "0x0.4#1", "3.0", "0x3.0#2");
// - rm == Nearest && carry <= Limb::power_of_2(sh - 1) && 0 < carry && carry <
// Limb::power_of_2(sh - 1) in sub_float_significands_general
test("4.0", "0x4.0#1", "0.8", "0x0.c#2", "3.0", "0x3.0#2");
// - max(out_prec, x_prec) + 2 <= exp_diff in sub_float_significands_general
// - in round_helper
// - dest_prec >= x_prec in round_helper
// - !increment_exp in sub_float_significands_general
// - inexact == 0 && rm != Down && rm != Floor in sub_float_significands_general
test("0.2", "0x0.4#1", "4.0", "0x4.0#2", "-4.0", "-0x4.0#2");
// - diff_exp >= Limb::WIDTH in exponent_shift_compare first time
test(
"8.82188e11",
"0xc.d668E+9#18",
"9.75459983374e122",
"0x1.79c17f063aE+102#40",
"-9.75459983374e122",
"-0x1.79c17f063aE+102#40",
);
// - cancel2 < 0 in sub_float_significands_general
// - out_len - neg_cancel2 <= ys_len in sub_float_significands_general
test(
"3.29008365861415556134836580980448399733562188e-9",
"0xe.217c389f8c9fd22042f5ed70da20cfb9f1ecE-8#146",
"3719044561792922503530448846362960.3599330496921301151502834994",
"0xb75cf116bc625ef1eab58f3c9950.5c2492852d5fb6817443c180#205",
"-3719044561792922503530448846362960.359933046402046456536127938",
"-0xb75cf116bc625ef1eab58f3c9950.5c2492770be37de1e7a3ef60#205",
);
// - out_len + cancel1 > xs_len in sub_float_significands_general
// - cancel1 < xs_len in sub_float_significands_general
test(
"1.07183972513958531257713938927815e-11",
"0xb.c8f5eafa12eb9821601f1dd6aeE-10#107",
"0.00374222828352849",
"0x0.00f5402c178824#46",
"-0.00374222827281009532032311766811006",
"-0x0.00f5402c0bbf2e1505ed1467de9fe#107",
);
// - out_len + cancel2 > ys_len in sub_float_significands_general
test(
"2589062031404.0",
"0x25ad01f682c.0#43",
"4351572166934988.581719655389852344796925751245753159273257621838622031922945531041952618\
810238932316",
"0xf75bb593981cc.94eb944f56fd85d744c7e812bf078ed9a4f5d3086fdab71e98a907840097016cb76fdc\
#330",
"-4348983104903584.58171965538985234479692575124575315927325762183862203192294553104195261\
8810238932316",
"-0xf7360891a19a0.94eb944f56fd85d744c7e812bf078ed9a4f5d3086fdab71e98a907840097016cb76fdc\
#330",
);
// - yi >= 0 && lasty != 0 in exponent_shift_compare
// - xi < 0 fourth time in exponent_shift_compare
// - lasty == 0 in exponent_shift_compare
// - yi < 0 || ys[yi] != 0 in exponent_shift_compare
// - yi >= 0 fourth time in exponent_shift_compare
test(
"0.002",
"0x0.008#2",
"1.107886492190627864290739752375593855464628579e-38",
"0x3.c51af197224960473945f6944424f855697e2E-32#149",
"0.001953124999999999999999999999999999988921135078",
"0x0.007ffffffffffffffffffffffffffffc3ae50e68#149",
);
// - cmp_low > 0 && rm == Nearest && xx < yy in sub_float_significands_general
// - goto_truncate || goto_end_of_sub first time in sub_float_significands_general
// - goto_truncate || goto_end_of_sub second time in sub_float_significands_general
test(
"1.521287e-9",
"0x6.88ac4E-8#21",
"6.842391932190563625e-20",
"0x1.431f7157e61b20d0E-16#62",
"1.5212870962270854807e-9",
"0x6.88ac3ffebce08eaE-8#62",
);
// - out_len - neg_cancel2 > ys_len in sub_float_significands_general
test(
"0.00678514868524062",
"0x0.01bcabe7b39c71#49",
"492541199943575879969.43922949854802247248767794847124160758",
"0x1ab361dbc0e97d4121.7071582bb3c5bd22b8f59cfc93c72a98#194",
"-492541199943575879969.43244434986278185350564935536210679008",
"-0x1ab361dbc0e97d4121.6eb4ac4400294c22b8f59cfc93c72a98#194",
);
// - rm == Nearest && sh == 0 && k == 0 in sub_float_significands_general
// - rm == Nearest && cmp_low >= 0 in sub_float_significands_general
// - rm == Nearest && cmp_low >= 0 && yy < half in sub_float_significands_general
// - rm == Nearest && cmp_low >= 0 && cmp_low <= 0 in sub_float_significands_general
test(
"5.7505515877842013577e-7",
"0x9.a5d7d56cabed47dE-6#64",
"1.1758894e-14",
"0x3.4f515E-12#22",
"5.7505514701952590309e-7",
"0x9.a5d7d21d5a9d47dE-6#64",
);
// - rm == Nearest && cmp_low < 0 in sub_float_significands_general
// - rm == Nearest && cmp_low < 0 && yy < half in sub_float_significands_general
// - cmp_low < 0 in sub_float_significands_general first time
// - cmp_low < 0 && rm == Nearest in sub_float_significands_general
// - rm == Nearest && (xx > yy || sh > 0 || cmp_low == -1) in sub_float_significands_general
test(
"8319983682.218895978935307677994592087137128849954503237724",
"0x1efe8e042.3809911ec0c7f99b114d2930720001b00aa46846#192",
"1.88392800575e35",
"0x2.4487b7174E+29#37",
"-188392800574747474298435817696599997.78110402106469232200542",
"-0x24487b7173fffffffffffe10171fbd.c7f66ee13f380664eec#192",
);
// - rm == Nearest && cmp_low < 0 && yy >= half in sub_float_significands_general
// - rm == Nearest && xx < yy && sh <= 0 && cmp_low != -1 in sub_float_significands_general
// - goto_end_of_sub in sub_float_significands_general
test(
"2.36288970224581301467472547462526069521e-27",
"0xb.b3518c72d51185c09977eb6e009c2c0E-23#128",
"3.413020751e-12",
"0x3.c0ae105E-10#30",
"-3.413020751029435178256669624768773569e-12",
"-0x3.c0ae104fffff44cae738d2aee7a3f668E-10#128",
);
// - xi >= 0 fourth time in exponent_shift_compare
// - diff_exp >= Limb::WIDTH in exponent_shift_compare second time
// - xs[xi] == yy in exponent_shift_compare
test(
"1125899906842624.0",
"0x4000000000000.000000000000#98",
"1.166815364554e-61",
"0x2.ffffffff80E-51#39",
"1125899906842624.0",
"0x4000000000000.000000000000#98",
);
// - 0 < diff_exp < Limb::WIDTH && yi >= 0 in exponent_shift_compare
// - xs[xi] != yy in exponent_shift_compare
test(
"9671406556917033397649408.0",
"0x800000000000000000000.0000#99",
"65536.015624999999999999946",
"0x10000.03ffffffffffffff00#87",
"9671406556917033397583871.98438",
"0x7fffffffffffffffeffff.fc00#99",
);
// - diff_exp == 0 && yi >= 0 in exponent_shift_compare
test(
"1.3877787807814456370485565165946e-17",
"0xf.ffffffffffffe007ffffffff8E-15#101",
"128.0000000000000000000000000008077935669463159990585083341",
"0x80.00000000000000000000003ffffffffffffe0000000000#190",
"-127.9999999999999999861222121929933371964607508331127668586",
"-0x7f.ffffffffffffff00000000400001ff7ffffe0008000000#190",
);
// - rm == Nearest && xx == yy && sh <= 0 && cmp_low != -1 in sub_float_significands_general
// - cmp_low < 0 in sub_float_significands_general second time
test(
"2.220581574517834801066783605693002897371795957735742517101e-16",
"0x1.0003fffffe00000000007ffffffffffffffffffffff000feE-13#192",
"8.881784e-16",
"0x4.00000E-13#21",
"-6.661202622483417522322269739033559602628204042264257482898e-16",
"-0x2.fffc000001ffffffffff80000000000000000000000fff00E-13#192",
);
// - diff_exp < Limb::WIDTH && yi < 0 in exponent_shift_compare
test(
"-1.8e-12",
"-0x1.fcE-10#7",
"-524288.0000000000017621525",
"-0x80000.0000000001f00078#81",
"524287.9999999999999573739",
"0x7ffff.fffffffffff40078#81",
);
// - (yi >= 0 || lasty != 0) && high_dif == 0 && dif == 1 in exponent_shift_compare
// - xi >= 0 third time in exponent_shift_compare
// - yi >= 0 && diff_exp != 0 in exponent_shift_compare
// - high_dif != 0 in exponent_shift_compare
// - dif == 0 in exponent_shift_compare
test(
"3.99999999999999999957",
"0x3.fffffffffffffff80#67",
"4.0",
"0x4.00000000000000000#68",
"-4.33680868994201773603e-19",
"-0x8.0000000000000000E-16#68",
);
// - xi < 0 third time in exponent_shift_compare
// - cancel1 >= xs_len in sub_float_significands_general
test(
"6.77626357803440271254657930615627554e-21",
"0x1.ffffffffffffffffffffc01fff800E-17#117",
"7.0e-21",
"0x2.0E-17#4",
"-6.99280860154738521672154778865541105e-46",
"-0x3.fe000800000000000000000000000E-38#117",
);
// - yi >= 0 && diff_exp == 0 in exponent_shift_compare
// - dif != 0 in exponent_shift_compare
test(
"1.45519152351431153846750277125465800054371356958e-11",
"0x1.00000001ffffffffffffffffffffffffffffffcE-9#155",
"1.455191523514311538467502771254658000526607875496523229114700566610230516799191954282190\
364e-11",
"0x1.00000001fffffffffffffffffffffffc0000000000000000000000000000fffffffffff87f8E-9#301",
"1.710569408086637569000134230861426729009957349416545362986887684243433631257558931055548\
3967e-49",
"0x3.ffffffbfffffffffffffffffffff00000000000780800000000000000000000000000000000E-41#301",
);
// - xs[xi] == 0 in exponent_shift_compare
// - xi < 0 second time in exponent_shift_compare
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000E-7#69",
"0.0",
"0x0.0",
);
// - xi >= 0 second time in exponent_shift_compare
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000000000000000000000000000000000000E-7#200",
"0.0",
"0x0.0",
);
}
#[test]
fn test_sub_prec() {
let test = |s, s_hex, t, t_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 y = parse_hex_string(t_hex);
assert_eq!(y.to_string(), t);
let (diff, o) = x.clone().sub_prec(y.clone(), prec);
assert!(diff.is_valid());
assert_eq!(diff.to_string(), out);
assert_eq!(to_hex_string(&diff), out_hex);
assert_eq!(o, o_out);
let (diff_alt, o_alt) = x.clone().sub_prec_val_ref(&y, prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let (diff_alt, o_alt) = x.sub_prec_ref_val(y.clone(), prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let (diff_alt, o_alt) = x.sub_prec_ref_ref(&y, prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_prec_assign(y.clone(), prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_prec_assign_ref(&y, prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let (diff_alt, o_alt) = add_prec_round_naive(x.clone(), -&y, prec, Nearest);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (rug_diff, rug_o) = rug_sub_prec(
&rug::Float::exact_from(&x),
&rug::Float::exact_from(&y),
prec,
);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff),
);
assert_eq!(rug_o, o);
};
test("NaN", "NaN", "NaN", "NaN", 1, "NaN", "NaN", Equal);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
1,
"NaN",
"NaN",
Equal,
);
test("NaN", "NaN", "Infinity", "Infinity", 1, "NaN", "NaN", Equal);
test("NaN", "NaN", "-0.0", "-0x0.0", 1, "NaN", "NaN", Equal);
test("NaN", "NaN", "0.0", "0x0.0", 1, "NaN", "NaN", Equal);
test("Infinity", "Infinity", "NaN", "NaN", 1, "NaN", "NaN", Equal);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
1,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", 1, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", 1, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", 1, "Infinity", "Infinity", Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
1,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
1,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
1,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
1,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
1,
"-Infinity",
"-Infinity",
Equal,
);
test("0.0", "0x0.0", "NaN", "NaN", 1, "NaN", "NaN", Equal);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
1,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
1,
"-Infinity",
"-Infinity",
Equal,
);
test("0.0", "0x0.0", "-0.0", "-0x0.0", 1, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0.0", "0x0.0", 1, "0.0", "0x0.0", Equal);
test("-0.0", "-0x0.0", "NaN", "NaN", 1, "NaN", "NaN", Equal);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
1,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
1,
"-Infinity",
"-Infinity",
Equal,
);
test("-0.0", "-0x0.0", "-0.0", "-0x0.0", 1, "0.0", "0x0.0", Equal);
test("-0.0", "-0x0.0", "0.0", "0x0.0", 1, "-0.0", "-0x0.0", Equal);
test("123.0", "0x7b.0#7", "NaN", "NaN", 1, "NaN", "NaN", Equal);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
1,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
1,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-0.0",
"-0x0.0",
1,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"123.0",
"0x7b.0#7",
"0.0",
"0x0.0",
1,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test("NaN", "NaN", "-123.0", "-0x7b.0#7", 1, "NaN", "NaN", Equal);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
1,
"Infinity",
"Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
1,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
1,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
1,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", 1, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", 2, "3.0", "0x3.0#2", Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#1",
10,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", 1, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", 2, "3.0", "0x3.0#2", Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#2",
10,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", 1, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", 2, "3.0", "0x3.0#2", Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#1",
10,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", 1, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", 2, "3.0", "0x3.0#2", Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#2",
10,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
1,
"4.0",
"0x4.0#1",
Greater,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
2,
"3.0",
"0x3.0#2",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
10,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
1,
"4.0",
"0x4.0#1",
Less,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
"4.555",
"0x4.8e#10",
Less,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
1,
"-2.0",
"-0x2.0#1",
Less,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
"-1.727",
"-0x1.ba0#10",
Greater,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
1,
"2.0",
"0x2.0#1",
Greater,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
"1.727",
"0x1.ba0#10",
Less,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
1,
"-4.0",
"-0x4.0#1",
Greater,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
"-4.555",
"-0x4.8e#10",
Greater,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
1,
"1.0",
"0x1.0#1",
Less,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
20,
"1.000244",
"0x1.00100#20",
Equal,
);
test("1.0", "0x1.0#1", "1.0", "0x1.0#1", 1, "0.0", "0x0.0", Equal);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", 10, "0.0", "0x0.0", Equal,
);
test(
"0.5", "0x0.8#1", "4.0", "0x4.0#1", 2, "-4.0", "-0x4.0#2", Less,
);
test(
"8.829e30",
"0x6.f70E+25#13",
"0.05475",
"0x0.0e04#10",
36,
"8.8289883602e30",
"0x6.f70000000E+25#36",
Greater,
);
test(
"1.6390041924e12",
"0x1.7d9c433e8E+10#34",
"1.8272611248130303984e40",
"0x3.5b2c8ea9f3a386bE+33#62",
40,
"-1.827261124813e40",
"-0x3.5b2c8ea9f4E+33#40",
Less,
);
test(
"5.96031697199505378e-9",
"0x1.9997014b4948928E-7#60",
"0.000014",
"0x0.0000f#4",
3,
"-0.000013",
"-0x0.0000e#3",
Greater,
);
test(
"8.7741695e-21",
"0x2.96f51f0E-17#27",
"1.86647e10",
"0x4.5880E+8#16",
11,
"-1.866e10",
"-0x4.58E+8#11",
Greater,
);
// - dest_prec < x_prec in round_helper
// - sh != 0 in round_helper
// - sh != 0 && (rm == Nearest || rb == 0) in round_helper
// - sh != 0 && (rm == Nearest || rb == 0) && (n == 0 || sb != 0) in round_helper
// - rm == Nearest in round_helper
// - rm == Nearest && rb != 0 && sb != 0 in round_helper
// - !increment second time in round_helper
// - inexact != 0 && inexact != MPFR_EVEN_INEX in sub_float_significands_general
test(
"1.6390041924e12",
"0x1.7d9c433e8E+10#34",
"1.8272611248130303984e40",
"0x3.5b2c8ea9f3a386bE+33#62",
40,
"-1.827261124813e40",
"-0x3.5b2c8ea9f4E+33#40",
Less,
);
// - rm == Nearest && rb == 0 in round_helper
test(
"13104.5238818416080254535",
"0x3330.861d1ed0acba8a3a#77",
"2.854e-35",
"0x2.5fE-29#10",
17,
"13104.5",
"0x3330.8#17",
Less,
);
// - out_len + cancel2 <= 0 in sub_float_significands_general
test(
"1.73414747294406e-17",
"0x1.3fe4cc8cf520E-14#48",
"5095194424.1679374580403939884785489",
"0x12fb27f38.2afdf3020e8eaac84a7ec#116",
62,
"-5095194424.167937458",
"-0x12fb27f38.2afdf300#62",
Greater,
);
// - rm == Nearest && rb != 0 && sb == 0 in round_helper
// - xs[o] & ulp != 0 in round_helper
// - increment first time in round_helper
// - increment_exp in sub_float_significands_general
// - inexact != 0 || rm == Down || rm == Floor && (inexact == 0 || inexact == MPFR_EVEN_INEX) in
// sub_float_significands_general
// - !out[out_len - 1].get_highest_bit() in sub_float_significands_general
test(
"5.96031697199505378e-9",
"0x1.9997014b4948928E-7#60",
"0.000014",
"0x0.0000f#4",
3,
"-0.000013",
"-0x0.0000e#3",
Greater,
);
// - xs[o] & ulp == 0 in round_helper
test(
"8.7741695e-21",
"0x2.96f51f0E-17#27",
"1.86647e10",
"0x4.5880E+8#16",
11,
"-1.866e10",
"-0x4.58E+8#11",
Greater,
);
// - !increment first time in round_helper
// - out[out_len - 1].get_highest_bit() in sub_float_significands_general
test(
"1.3482e25",
"0xb.27E+20#12",
"1.12202588817e-11",
"0xc.5638dc08E-10#36",
11,
"1.348e25",
"0xb.26E+20#11",
Less,
);
// - increment second time in round_helper
test(
"4.53892e18",
"0x3.efd8E+15#16",
"3412.3125291",
"0xd54.5001e8#33",
1,
"5.0e18",
"0x4.0E+15#1",
Greater,
);
// - ixs_len > 0 in sub_float_significands_general
test(
"6058.05208272591415306446968882359605946955168456454",
"0x17aa.0d554b247ce1b6ab28ba39c8d5992a74c7ac91a#169",
"0.000144566892208323",
"0x0.0009796e12f9784#47",
64,
"6058.0519381590219448",
"0x17aa.0d4bd1b669e84#64",
Greater,
);
// - sh == 0 in round_helper
// - sh == 0 && (rm == Nearest || rb == 0) in round_helper
// - sh == 0 && (rm == Nearest || rb == 0) && (n == 0 || sb != 0) in round_helper
test(
"3.6596517369110659089355442395654891585e48",
"0x2.810875a0ca3206afd8c6cf841941830E+40#123",
"1545.699550397407201099813420288295",
"0x609.b315bc1ec48a143a74bd53048#109",
64,
"3.6596517369110659089e48",
"0x2.810875a0ca3206b0E+40#64",
Greater,
);
// - rm == Nearest && cmp_low >= 0 && cmp_low > 0 in sub_float_significands_general
// - cmp_low > 0 && rm == Nearest && xx > yy in sub_float_significands_general
// - cmp_low == 2 && rm == Nearest && xx > yy in sub_float_significands_general
// - cmp_low == 2 && rm == Nearest && xx > yy && !carry in sub_float_significands_general
test(
"2.80915429604669102593383052436808885401854724410738829e-11",
"0x1.ee310ffa09a06a6361f52c2cd8a9569a780b775dc213E-9#177",
"519241072363118296470.333928838103121952666621563036",
"0x1c25eadc41d4907d96.557c5c3ed81cab65dab0cf920#166",
64,
"-5.1924107236311829648e20",
"-0x1.c25eadc41d4907daE+17#64",
Less,
);
// - cmp_low > 0 && cmp_low != 2 && rm == Nearest && xx > yy in sub_float_significands_general
test(
"559935046210054011882951826578284118061013900.5853448",
"0x191bbd3588c78488c2f4d122814d5fb34edb8c.95d928#170",
"3.027932e11",
"0x4.67fe2E+9#22",
63,
"5.599350462100540119e44",
"0x1.91bbd3588c78488cE+37#63",
Less,
);
// - sh != 0 && (rm == Nearest || rb == 0) && n != 0 && sb == 0 in round_helper
test(
"7184368264698708563285024670194469326968686224.86386349506591",
"0x1422880c600dc4fd90a02f1814859aafd658690.dd2628738430#198",
"1.0296060328202e-24",
"0x1.3ea5cb49bdaE-20#44",
61,
"7.184368264698708565e45",
"0x1.422880c600dc4feE+38#61",
Greater,
);
// - not iys_len condition in sub_float_significands_general
test(
"0.005406335446698931371156460215539762984788400068",
"0x0.01624f41ef4d9361bd396d1b5ff5c84cbeacdc10#153",
"268934084586659427574577798723115132232.14094768348",
"0xca52d21696ccb42e28dd0ff5c50ba548.241525bafe#167",
62,
"-2.689340845866594276e38",
"-0xc.a52d21696ccb430E+31#62",
Less,
);
// - out[out_len - 1] >> (Limb::WIDTH - 1) == 0 in sub_float_significands_general
test(
"64.0",
"0x40.000000000000000000000000#101",
"3.388131587461699328349286349380665493965593642335603946234186645761911188725141218987660\
374e-21",
"0xf.fffff007f8000000007ffc00ffff00007fffffffffffffff80003ffff800001fffffffff80E-18#298",
32,
"64.0",
"0x40.0000000#32",
Greater,
);
// - xi < 0 && yi >= 0 in exponent_shift_compare
// - yi < 0 second time in exponent_shift_compare
// - xs[xi] != 0 in exponent_shift_compare
test(
"8.0",
"0x8.00#10",
"8.000000000000000000001799531422609112",
"0x8.0000000000000000087f8000000000#121",
146,
"-1.79953142260911170668274960959820418793242425e-21",
"-0x8.7f8000000000000000000000000000000000E-18#146",
Equal,
);
// - yi >= 0 && ys[yi] == 0 in exponent_shift_compare
// - yi < 0 fourth time in exponent_shift_compare
test(
"65536.0",
"0x10000.0000000000000000000#90",
"1.0e5",
"0x2.0E+4#2",
146,
"-65536.0",
"-0x10000.000000000000000000000000000000000#146",
Equal,
);
// - rm == Nearest && cmp_low >= 0 && yy >= half in sub_float_significands_general
test(
"3004622760.998488672936478517",
"0xb316e7a8.ff9cf423b0491b4#90",
"1355498858579258.8596",
"0x4d0d1abf5853a.dc0ec#70",
64,
"-1355495853956497.8611",
"-0x4d0d0f8de9d91.dc70#64",
Greater,
);
// - cmp_low == 2 && rm == Nearest && xx > yy && carry in sub_float_significands_general
test(
"2596143477507256672744148570210303.750244140624999888977803416602752745179193772357882662\
973853959140044204",
"0x7ffff000000000000000001fffff.c00ffffffffff800007ffffffffffffffe000001ffffffff80000001ff\
fc#349",
"4.2351647e-22",
"0x1.ffffffcE-18#27",
18,
"2.59615e33",
"0x8.0000E+27#18",
Greater,
);
// - lasty != 0 in exponent_shift_compare
test(
"6.2230152778611417071440640537801242403342227837862e-61",
"0xf.ffffffffffffffffffffffffffffff1ffff3fffeE-51#163",
"6.0e-61",
"0x1.0E-50#4",
11,
"-2.56e-98",
"-0xe.00E-82#11",
Greater,
);
// - sh == 0 && (rm == Nearest || rb == 0) && n != 0 && sb == 0 in round_helper
test(
"1.56676e-64",
"0x1.07ff8E-53#18",
"127.906249999999999993061106096092771622352302164",
"0x7f.e7ffffffffffff8000000000000000000001ff8#160",
64,
"-127.906249999999999993",
"-0x7f.e7ffffffffffff8#64",
Greater,
);
// - yi < 0 third time in exponent_shift_compare
test(
"6.9e-18",
"0x8.0E-15#6",
"6.9388939039072283773e-18",
"0x7.fffffffffffffff8E-15#64",
86,
"3.7615819226313200254999569e-37",
"0x8.000000000000000000000E-31#86",
Equal,
);
}
#[test]
fn sub_prec_fail() {
assert_panic!(Float::NAN.sub_prec(Float::NAN, 0));
assert_panic!(Float::NAN.sub_prec_val_ref(&Float::NAN, 0));
assert_panic!(Float::NAN.sub_prec_ref_val(Float::NAN, 0));
assert_panic!(Float::NAN.sub_prec_ref_ref(&Float::NAN, 0));
assert_panic!({
let mut x = Float::NAN;
x.sub_prec_assign(Float::NAN, 0)
});
assert_panic!({
let mut x = Float::NAN;
x.sub_prec_assign_ref(&Float::NAN, 0)
});
}
#[test]
fn test_sub_round() {
let test = |s, s_hex, t, t_hex, rm, out: &str, out_hex: &str, o_out| {
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let y = parse_hex_string(t_hex);
assert_eq!(y.to_string(), t);
let (diff, o) = x.clone().sub_round(y.clone(), rm);
assert!(diff.is_valid());
assert_eq!(diff.to_string(), out);
assert_eq!(to_hex_string(&diff), out_hex);
assert_eq!(o, o_out);
let (diff_alt, o_alt) = x.clone().sub_round_val_ref(&y, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let (diff_alt, o_alt) = x.sub_round_ref_val(y.clone(), rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let (diff_alt, o_alt) = x.sub_round_ref_ref(&y, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_round_assign(y.clone(), rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_round_assign_ref(&y, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_diff, rug_o) =
rug_sub_round(&rug::Float::exact_from(&x), &rug::Float::exact_from(&y), rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff),
);
assert_eq!(rug_o, o);
}
let (diff_alt, o_alt) = add_prec_round_naive(
x.clone(),
-&y,
max(x.significant_bits(), y.significant_bits()),
rm,
);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
};
test("NaN", "NaN", "NaN", "NaN", Floor, "NaN", "NaN", Equal);
test("NaN", "NaN", "NaN", "NaN", Ceiling, "NaN", "NaN", Equal);
test("NaN", "NaN", "NaN", "NaN", Down, "NaN", "NaN", Equal);
test("NaN", "NaN", "NaN", "NaN", Up, "NaN", "NaN", Equal);
test("NaN", "NaN", "NaN", "NaN", Nearest, "NaN", "NaN", Equal);
test("NaN", "NaN", "NaN", "NaN", Exact, "NaN", "NaN", Equal);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
Floor,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
Down,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
Up,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
Exact,
"NaN",
"NaN",
Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", Floor, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", Ceiling, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", Down, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", Up, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", Nearest, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", Exact, "NaN", "NaN", Equal,
);
test("NaN", "NaN", "-0.0", "-0x0.0", Floor, "NaN", "NaN", Equal);
test("NaN", "NaN", "-0.0", "-0x0.0", Ceiling, "NaN", "NaN", Equal);
test("NaN", "NaN", "-0.0", "-0x0.0", Down, "NaN", "NaN", Equal);
test("NaN", "NaN", "-0.0", "-0x0.0", Up, "NaN", "NaN", Equal);
test("NaN", "NaN", "-0.0", "-0x0.0", Nearest, "NaN", "NaN", Equal);
test("NaN", "NaN", "-0.0", "-0x0.0", Exact, "NaN", "NaN", Equal);
test("NaN", "NaN", "0.0", "0x0.0", Floor, "NaN", "NaN", Equal);
test("NaN", "NaN", "0.0", "0x0.0", Ceiling, "NaN", "NaN", Equal);
test("NaN", "NaN", "0.0", "0x0.0", Down, "NaN", "NaN", Equal);
test("NaN", "NaN", "0.0", "0x0.0", Up, "NaN", "NaN", Equal);
test("NaN", "NaN", "0.0", "0x0.0", Nearest, "NaN", "NaN", Equal);
test("NaN", "NaN", "0.0", "0x0.0", Exact, "NaN", "NaN", Equal);
test(
"Infinity", "Infinity", "NaN", "NaN", Floor, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "NaN", "NaN", Ceiling, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "NaN", "NaN", Down, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "NaN", "NaN", Up, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "NaN", "NaN", Nearest, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "NaN", "NaN", Exact, "NaN", "NaN", Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
Floor,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
Ceiling,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
Down,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
Up,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
Nearest,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
Exact,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", Floor, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", Ceiling, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", Down, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", Up, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", Nearest, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", Exact, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", Floor, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", Ceiling, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", Down, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", Up, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", Nearest, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", Exact, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", Floor, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", Ceiling, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", Down, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", Up, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", Nearest, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", Exact, "Infinity", "Infinity", Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
Floor,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
Down,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
Up,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
Exact,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
Floor,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
Down,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
Up,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
Exact,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test("0.0", "0x0.0", "NaN", "NaN", Floor, "NaN", "NaN", Equal);
test("0.0", "0x0.0", "NaN", "NaN", Ceiling, "NaN", "NaN", Equal);
test("0.0", "0x0.0", "NaN", "NaN", Down, "NaN", "NaN", Equal);
test("0.0", "0x0.0", "NaN", "NaN", Up, "NaN", "NaN", Equal);
test("0.0", "0x0.0", "NaN", "NaN", Nearest, "NaN", "NaN", Equal);
test("0.0", "0x0.0", "NaN", "NaN", Exact, "NaN", "NaN", Equal);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
Floor,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
Ceiling,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
Down,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
Up,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
Nearest,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
Exact,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0", "0x0.0", "-0.0", "-0x0.0", Floor, "0.0", "0x0.0", Equal,
);
test(
"0.0", "0x0.0", "-0.0", "-0x0.0", Ceiling, "0.0", "0x0.0", Equal,
);
test(
"0.0", "0x0.0", "-0.0", "-0x0.0", Down, "0.0", "0x0.0", Equal,
);
test("0.0", "0x0.0", "-0.0", "-0x0.0", Up, "0.0", "0x0.0", Equal);
test(
"0.0", "0x0.0", "-0.0", "-0x0.0", Nearest, "0.0", "0x0.0", Equal,
);
test(
"0.0", "0x0.0", "-0.0", "-0x0.0", Exact, "0.0", "0x0.0", Equal,
);
// Note different behavior for Floor
test(
"0.0", "0x0.0", "0.0", "0x0.0", Floor, "-0.0", "-0x0.0", Equal,
);
test(
"0.0", "0x0.0", "0.0", "0x0.0", Ceiling, "0.0", "0x0.0", Equal,
);
test("0.0", "0x0.0", "0.0", "0x0.0", Down, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0.0", "0x0.0", Up, "0.0", "0x0.0", Equal);
test(
"0.0", "0x0.0", "0.0", "0x0.0", Nearest, "0.0", "0x0.0", Equal,
);
test("0.0", "0x0.0", "0.0", "0x0.0", Exact, "0.0", "0x0.0", Equal);
test("-0.0", "-0x0.0", "NaN", "NaN", Floor, "NaN", "NaN", Equal);
test("-0.0", "-0x0.0", "NaN", "NaN", Ceiling, "NaN", "NaN", Equal);
test("-0.0", "-0x0.0", "NaN", "NaN", Down, "NaN", "NaN", Equal);
test("-0.0", "-0x0.0", "NaN", "NaN", Up, "NaN", "NaN", Equal);
test("-0.0", "-0x0.0", "NaN", "NaN", Nearest, "NaN", "NaN", Equal);
test("-0.0", "-0x0.0", "NaN", "NaN", Exact, "NaN", "NaN", Equal);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
Floor,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
Ceiling,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
Down,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
Up,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
Nearest,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
Exact,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
Exact,
"-Infinity",
"-Infinity",
Equal,
);
// Note different behavior for Floor
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", Floor, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", Ceiling, "0.0", "0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", Down, "0.0", "0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", Up, "0.0", "0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", Nearest, "0.0", "0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", Exact, "0.0", "0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", Floor, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", Ceiling, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", Down, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", Up, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", Nearest, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", Exact, "-0.0", "-0x0.0", Equal,
);
test(
"123.0", "0x7b.0#7", "NaN", "NaN", Floor, "NaN", "NaN", Equal,
);
test(
"123.0", "0x7b.0#7", "NaN", "NaN", Ceiling, "NaN", "NaN", Equal,
);
test("123.0", "0x7b.0#7", "NaN", "NaN", Down, "NaN", "NaN", Equal);
test("123.0", "0x7b.0#7", "NaN", "NaN", Up, "NaN", "NaN", Equal);
test(
"123.0", "0x7b.0#7", "NaN", "NaN", Nearest, "NaN", "NaN", Equal,
);
test(
"123.0", "0x7b.0#7", "NaN", "NaN", Exact, "NaN", "NaN", Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
Floor,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
Ceiling,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
Down,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
Up,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
Nearest,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
Exact,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0", "0x7b.0#7", "-0.0", "-0x0.0", Floor, "123.0", "0x7b.0#7", Equal,
);
test(
"123.0", "0x7b.0#7", "-0.0", "-0x0.0", Ceiling, "123.0", "0x7b.0#7", Equal,
);
test(
"123.0", "0x7b.0#7", "-0.0", "-0x0.0", Down, "123.0", "0x7b.0#7", Equal,
);
test(
"123.0", "0x7b.0#7", "-0.0", "-0x0.0", Up, "123.0", "0x7b.0#7", Equal,
);
test(
"123.0", "0x7b.0#7", "-0.0", "-0x0.0", Nearest, "123.0", "0x7b.0#7", Equal,
);
test(
"123.0", "0x7b.0#7", "-0.0", "-0x0.0", Exact, "123.0", "0x7b.0#7", Equal,
);
test(
"123.0", "0x7b.0#7", "0.0", "0x0.0", Floor, "123.0", "0x7b.0#7", Equal,
);
test(
"123.0", "0x7b.0#7", "0.0", "0x0.0", Ceiling, "123.0", "0x7b.0#7", Equal,
);
test(
"123.0", "0x7b.0#7", "0.0", "0x0.0", Down, "123.0", "0x7b.0#7", Equal,
);
test(
"123.0", "0x7b.0#7", "0.0", "0x0.0", Up, "123.0", "0x7b.0#7", Equal,
);
test(
"123.0", "0x7b.0#7", "0.0", "0x0.0", Nearest, "123.0", "0x7b.0#7", Equal,
);
test(
"123.0", "0x7b.0#7", "0.0", "0x0.0", Exact, "123.0", "0x7b.0#7", Equal,
);
test(
"NaN",
"NaN",
"-123.0",
"-0x7b.0#7",
Floor,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-123.0",
"-0x7b.0#7",
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-123.0",
"-0x7b.0#7",
Down,
"NaN",
"NaN",
Equal,
);
test("NaN", "NaN", "-123.0", "-0x7b.0#7", Up, "NaN", "NaN", Equal);
test(
"NaN",
"NaN",
"-123.0",
"-0x7b.0#7",
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-123.0",
"-0x7b.0#7",
Exact,
"NaN",
"NaN",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
Floor,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
Ceiling,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
Down,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
Up,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
Nearest,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
Exact,
"Infinity",
"Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
Floor,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
Ceiling,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
Down,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
Up,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
Nearest,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
Exact,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
Floor,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
Ceiling,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
Down,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
Up,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
Nearest,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
Exact,
"123.0",
"0x7b.0#7",
Equal,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", Floor, "2.0", "0x2.0#1", Less,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", Ceiling, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", Down, "2.0", "0x2.0#1", Less,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", Up, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", Nearest, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", Floor, "3.0", "0x3.0#2", Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
Floor,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
Ceiling,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
Down,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
Up,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
Nearest,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
Exact,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Floor,
"4.555806215962888",
"0x4.8e4950f0795fc#53",
Less,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Ceiling,
"4.555806215962889",
"0x4.8e4950f079600#53",
Greater,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Down,
"4.555806215962888",
"0x4.8e4950f0795fc#53",
Less,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Up,
"4.555806215962889",
"0x4.8e4950f079600#53",
Greater,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Nearest,
"4.555806215962888",
"0x4.8e4950f0795fc#53",
Less,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Floor,
"-1.727379091216698",
"-0x1.ba35842091e63#53",
Equal,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Ceiling,
"-1.727379091216698",
"-0x1.ba35842091e63#53",
Equal,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Down,
"-1.727379091216698",
"-0x1.ba35842091e63#53",
Equal,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Up,
"-1.727379091216698",
"-0x1.ba35842091e63#53",
Equal,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Nearest,
"-1.727379091216698",
"-0x1.ba35842091e63#53",
Equal,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Exact,
"-1.727379091216698",
"-0x1.ba35842091e63#53",
Equal,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Floor,
"1.727379091216698",
"0x1.ba35842091e63#53",
Equal,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Ceiling,
"1.727379091216698",
"0x1.ba35842091e63#53",
Equal,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Down,
"1.727379091216698",
"0x1.ba35842091e63#53",
Equal,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Up,
"1.727379091216698",
"0x1.ba35842091e63#53",
Equal,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Nearest,
"1.727379091216698",
"0x1.ba35842091e63#53",
Equal,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
Exact,
"1.727379091216698",
"0x1.ba35842091e63#53",
Equal,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Floor,
"-4.555806215962889",
"-0x4.8e4950f079600#53",
Less,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Ceiling,
"-4.555806215962888",
"-0x4.8e4950f0795fc#53",
Greater,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Down,
"-4.555806215962888",
"-0x4.8e4950f0795fc#53",
Greater,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Up,
"-4.555806215962889",
"-0x4.8e4950f079600#53",
Less,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
Floor,
"-4.555806215962889",
"-0x4.8e4950f079600#53",
Less,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
Floor,
"1.0",
"0x1.0#1",
Less,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
Ceiling,
"2.0",
"0x2.0#1",
Greater,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
Down,
"1.0",
"0x1.0#1",
Less,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
Up,
"2.0",
"0x2.0#1",
Greater,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
Nearest,
"1.0",
"0x1.0#1",
Less,
);
// Note different behavior for Floor
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", Floor, "-0.0", "-0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", Ceiling, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", Down, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", Up, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", Nearest, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", Exact, "0.0", "0x0.0", Equal,
);
test(
"0.5", "0x0.8#1", "2.0", "0x2.0#1", Down, "-1.0", "-0x1.0#1", Greater,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
Nearest,
"1.0",
"0x1.0#1",
Less,
);
// - in sub_float_significands_same_prec_lt_w
// - x_exp == y_exp in sub_float_significands_same_prec_lt_w
// - x == y in sub_float_significands_same_prec_lt_w
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", Nearest, "0.0", "0x0.0", Equal,
);
// - x_exp < y_exp in sub_float_significands_same_prec_lt_w
// - exp_diff < Limb::WIDTH in sub_float_significands_same_prec_lt_w
// - leading_zeros != 0 in sub_float_significands_same_prec_lt_w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_lt_w
test(
"1.0", "0x1.0#1", "2.0", "0x2.0#1", Nearest, "-1.0", "-0x1.0#1", Equal,
);
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_lt_w
// - neg in sub_float_significands_same_prec_lt_w
// - rm == Nearest in sub_float_significands_same_prec_lt_w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff & shift_bit) != 0) in
// sub_float_significands_same_prec_lt_w
// - rm == Nearest && round_bit != 0 && sticky_bit != 0 && diff == 0 in
// sub_float_significands_same_prec_lt_w
test(
"1.0", "0x1.0#1", "4.0", "0x4.0#1", Nearest, "-4.0", "-0x4.0#1", Less,
);
// - !neg in sub_float_significands_same_prec_lt_w
test(
"1.0", "0x1.0#1", "0.2", "0x0.4#1", Nearest, "1.0", "0x1.0#1", Greater,
);
// - x < y in sub_float_significands_same_prec_lt_w
test(
"1.0", "0x1.0#2", "1.5", "0x1.8#2", Nearest, "-0.5", "-0x0.8#2", Equal,
);
// - x > y in sub_float_significands_same_prec_lt_w
test(
"1.5", "0x1.8#2", "1.0", "0x1.0#2", Nearest, "0.5", "0x0.8#2", Equal,
);
// - leading_zeros == 0 in sub_float_significands_same_prec_lt_w
test(
"1.5", "0x1.8#2", "0.5", "0x0.8#2", Nearest, "1.0", "0x1.0#2", Equal,
);
// - rm == Nearest && (round_bit == 0 || (sticky_bit == 0 && (diff & shift_bit) == 0)) in
// sub_float_significands_same_prec_lt_w
test(
"2.0", "0x2.0#2", "0.8", "0x0.c#2", Nearest, "1.0", "0x1.0#2", Less,
);
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff & shift_bit) != 0) && diff !=
// 0 in sub_float_significands_same_prec_lt_w
test(
"1.5", "0x1.8#2", "0.1", "0x0.2#2", Nearest, "1.5", "0x1.8#2", Greater,
);
// - exp_diff >= Limb::WIDTH in sub_float_significands_same_prec_lt_w
// - x <= HIGH_BIT in sub_float_significands_same_prec_lt_w
test(
"1.0e9",
"0x4.0E+7#1",
"6.0e-11",
"0x4.0E-9#1",
Nearest,
"1.0e9",
"0x4.0E+7#1",
Greater,
);
// - x > HIGH_BIT in sub_float_significands_same_prec_lt_w
test(
"9.2047171e-27",
"0x2.d945d78E-22#27",
"1.43189635e33",
"0x4.69912aE+27#27",
Nearest,
"-1.43189635e33",
"-0x4.69912aE+27#27",
Less,
);
// - rm == Floor || rm == Down in sub_float_significands_same_prec_lt_w
test(
"1.0", "0x1.0#1", "0.2", "0x0.4#1", Down, "0.5", "0x0.8#1", Less,
);
// - rm == Ceiling || rm == Up in sub_float_significands_same_prec_lt_w
// - (rm == Ceiling || rm == Up) && diff == 0 in sub_float_significands_same_prec_lt_w
test(
"1.0", "0x1.0#1", "0.2", "0x0.4#1", Up, "1.0", "0x1.0#1", Greater,
);
// - (rm == Ceiling || rm == Up) && diff != 0 in sub_float_significands_same_prec_lt_w
test(
"2.0", "0x2.0#2", "0.8", "0x0.c#2", Up, "1.5", "0x1.8#2", Greater,
);
// - in sub_float_significands_same_prec_w
// - x_exp == y_exp in sub_float_significands_same_prec_w
// - x_exp == y_exp && a0 == 0 in sub_float_significands_same_prec_w
test(
"1.0",
"0x1.0000000000000000#64",
"1.0",
"0x1.0000000000000000#64",
Nearest,
"0.0",
"0x0.0",
Equal,
);
// - x_exp != y_exp in sub_float_significands_same_prec_w
// - x_exp < y_exp in sub_float_significands_same_prec_w
// - exp_diff < Limb::WIDTH in sub_float_significands_same_prec_w
// - a0 != 0 in sub_float_significands_same_prec_w
// - leading_zeros != 0 in sub_float_significands_same_prec_w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_w
test(
"1.0",
"0x1.0000000000000000#64",
"2.0",
"0x2.0000000000000000#64",
Nearest,
"-1.0",
"-0x1.0000000000000000#64",
Equal,
);
// - a0 > x in sub_float_significands_same_prec_w
test(
"1.0",
"0x1.0000000000000000#64",
"1.0000000000000000001",
"0x1.0000000000000002#64",
Nearest,
"-1.084202172485504434e-19",
"-0x2.0000000000000000E-16#64",
Equal,
);
// - a0 <= x in sub_float_significands_same_prec_w
test(
"1.0000000000000000001",
"0x1.0000000000000002#64",
"1.0",
"0x1.0000000000000000#64",
Nearest,
"1.084202172485504434e-19",
"0x2.0000000000000000E-16#64",
Equal,
);
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_w
// - neg in sub_float_significands_same_prec_w
// - rm == Nearest in sub_float_significands_same_prec_w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff & 1) != 0) in
// sub_float_significands_same_prec_w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff & 1) != 0) &&
// !diff.overflowing_add_assign(1) in sub_float_significands_same_prec_w
test(
"1.0000000000000000001",
"0x1.0000000000000002#64",
"4.0",
"0x4.0000000000000000#64",
Nearest,
"-3.0",
"-0x3.0000000000000000#64",
Less,
);
// - !neg in sub_float_significands_same_prec_w
test(
"4.0",
"0x4.0000000000000000#64",
"1.0000000000000000001",
"0x1.0000000000000002#64",
Nearest,
"3.0",
"0x3.0000000000000000#64",
Greater,
);
// - rm == Nearest && (round_bit == 0 || (sticky_bit == 0 && (diff & 1) == 0)) in
// sub_float_significands_same_prec_w
test(
"1.0000000000000000003",
"0x1.0000000000000006#64",
"4.0",
"0x4.0000000000000000#64",
Nearest,
"-2.9999999999999999996",
"-0x2.fffffffffffffff8#64",
Greater,
);
// - leading_zeros == 0 in sub_float_significands_same_prec_w
test(
"3.2729513077064011786e-37",
"0x6.f5f6d50e7b8f6eb0E-31#64",
"7.8519772600462495573e-34",
"0x4.13b4f0d218450fb0E-28#64",
Nearest,
"-7.848704308738543156e-34",
"-0x4.13459164c75d56b8E-28#64",
Greater,
);
// - exp_diff >= Limb::WIDTH in sub_float_significands_same_prec_w
// - x > HIGH_BIT in sub_float_significands_same_prec_w
test(
"5.9376349676904431794e-6",
"0x0.0000639df2b03f3e49a70#64",
"2.9347251290514630352e-45",
"0x1.0c11b075f03d6daeE-37#64",
Nearest,
"5.9376349676904431794e-6",
"0x0.0000639df2b03f3e49a70#64",
Greater,
);
// - x <= HIGH_BIT in sub_float_significands_same_prec_w
// - exp_diff != Limb::WIDTH || y <= HIGH_BIT in sub_float_significands_same_prec_w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff & 1) != 0) &&
// diff.overflowing_add_assign(1) in sub_float_significands_same_prec_w
test(
"8355840.0624923708378",
"0x7f8000.0fff8000ff8#64",
"2.3384026197294446691e49",
"0x1.0000000000000000E+41#64",
Nearest,
"-2.3384026197294446691e49",
"-0x1.0000000000000000E+41#64",
Less,
);
// - x_exp != y_exp && a0 == 0 in sub_float_significands_same_prec_w
test(
"63.999999999999999997",
"0x3f.ffffffffffffffc#64",
"64.0",
"0x40.000000000000000#64",
Nearest,
"-3.4694469519536141888e-18",
"-0x4.0000000000000000E-15#64",
Equal,
);
// - exp_diff == Limb::WIDTH && y > HIGH_BIT in sub_float_significands_same_prec_w
test(
"4.656578456163629198e-10",
"0x1.ffff07fffffffffeE-8#64",
"4294967296.0",
"0x100000000.00000000#64",
Nearest,
"-4294967295.9999999995",
"-0xffffffff.fffffffe#64",
Greater,
);
// - rm == Floor || rm == Down in sub_float_significands_same_prec_w
test(
"1.0000000000000000001",
"0x1.0000000000000002#64",
"4.0",
"0x4.0000000000000000#64",
Down,
"-2.9999999999999999998",
"-0x2.fffffffffffffffc#64",
Greater,
);
// - rm == Ceiling || rm == Up in sub_float_significands_same_prec_w
// - (rm == Ceiling || rm == Up) && !diff.overflowing_add_assign(1) in
// sub_float_significands_same_prec_w
test(
"1.0000000000000000001",
"0x1.0000000000000002#64",
"4.0",
"0x4.0000000000000000#64",
Up,
"-3.0",
"-0x3.0000000000000000#64",
Less,
);
// - (rm == Ceiling || rm == Up) && diff.overflowing_add_assign(1) in
// sub_float_significands_same_prec_w
test(
"7.737125245533626718e25",
"0x4.0000000000000000E+21#64",
"3.4410713482205469792e-21",
"0x1.03fffffffffc0000E-17#64",
Up,
"7.737125245533626718e25",
"0x4.0000000000000000E+21#64",
Greater,
);
// - in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp == y_exp in sub_float_significands_same_prec_gt_w_lt_2w
// - a1 == 0 && a0 == 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.0",
"0x1.0000000000000000#65",
"1.0",
"0x1.0000000000000000#65",
Nearest,
"0.0",
"0x0.0",
Equal,
);
// - x_exp != y_exp in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp < y_exp in sub_float_significands_same_prec_gt_w_lt_2w
// - exp_diff < Limb::WIDTH in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp != y_exp && a1 != 0 in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp != y_exp && leading_zeros != 0 in sub_float_significands_same_prec_gt_w_lt_2w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.0",
"0x1.0000000000000000#65",
"2.0",
"0x2.0000000000000000#65",
Nearest,
"-1.0",
"-0x1.0000000000000000#65",
Equal,
);
// - (a1 != 0 || a0 != 0) && a1 >= x_1 in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp == y_exp && a1 == 0 in sub_float_significands_same_prec_gt_w_lt_2w
// - x_exp == y_exp && leading_zeros == 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.0",
"0x1.0000000000000000#65",
"1.00000000000000000005",
"0x1.0000000000000001#65",
Nearest,
"-5.42101086242752217e-20",
"-0x1.0000000000000000E-16#65",
Equal,
);
// - (a1 != 0 || a0 != 0) && a1 < x_1 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.00000000000000000005",
"0x1.0000000000000001#65",
"1.0",
"0x1.0000000000000000#65",
Nearest,
"5.42101086242752217e-20",
"0x1.0000000000000000E-16#65",
Equal,
);
// - x_exp == y_exp && leading_zeros != 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.0",
"0x1.00000000000000000#66",
"1.00000000000000000003",
"0x1.00000000000000008#66",
Nearest,
"-2.710505431213761085e-20",
"-0x8.0000000000000000E-17#66",
Equal,
);
// - x_exp == y_exp && a1 != 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.0",
"0x1.0000000000000000#65",
"1.00000000000000000011",
"0x1.0000000000000002#65",
Nearest,
"-1.084202172485504434e-19",
"-0x2.0000000000000000E-16#65",
Equal,
);
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_gt_w_lt_2w
// - neg in sub_float_significands_same_prec_gt_w_lt_2w
// - rm == Nearest in sub_float_significands_same_prec_gt_w_lt_2w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) &&
// !overflow in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.00000000000000000005",
"0x1.0000000000000001#65",
"4.0",
"0x4.0000000000000000#65",
Nearest,
"-3.0",
"-0x3.0000000000000000#65",
Less,
);
// - !neg in sub_float_significands_same_prec_gt_w_lt_2w
test(
"4.0",
"0x4.0000000000000000#65",
"1.00000000000000000005",
"0x1.0000000000000001#65",
Nearest,
"3.0",
"0x3.0000000000000000#65",
Greater,
);
// - rm == Nearest && (round_bit == 0 || (sticky_bit == 0 && (diff_0 & shift_bit) == 0)) in
// sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.00000000000000000016",
"0x1.0000000000000003#65",
"4.0",
"0x4.0000000000000000#65",
Nearest,
"-2.9999999999999999998",
"-0x2.fffffffffffffffc#65",
Greater,
);
// - Limb::WIDTH <= exp_diff < Limb::WIDTH * 2 in sub_float_significands_same_prec_gt_w_lt_2w
// - Limb::WIDTH < exp_diff < Limb::WIDTH * 2 in sub_float_significands_same_prec_gt_w_lt_2w
// - Limb::WIDTH <= exp_diff < Limb::WIDTH * 2 && a1 >= HIGH_BIT in
// sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.44020837962004126031156726e28",
"0x2.e891fdf020840728c0894E+23#85",
"18.63123034252626794758647",
"0x12.a1984fcd64a8ae228eef#85",
Nearest,
"1.44020837962004126031156726e28",
"0x2.e891fdf020840728c0894E+23#85",
Greater,
);
// - x_exp != y_exp && leading_zeros == 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"0.0001507756106295330606262754053",
"0x0.0009e19851127b95dcf03f0cdc#91",
"3458.565842843038054059107814",
"0xd82.90db1399862ba513faf8#91",
Nearest,
"-3458.565692067427424526047188",
"-0xd82.90d132013519297e1e08#91",
Less,
);
// - exp_diff >= Limb::WIDTH * 2 in sub_float_significands_same_prec_gt_w_lt_2w
// - exp_diff >= Limb::WIDTH * 2 && a1 >= HIGH_BIT in
// sub_float_significands_same_prec_gt_w_lt_2w
test(
"4.8545822922649671226e27",
"0xf.af9dc963a0709f78E+22#65",
"1.14823551075108882469e-96",
"0x2.73dea72af3fe6314E-80#65",
Nearest,
"4.8545822922649671226e27",
"0xf.af9dc963a0709f78E+22#65",
Greater,
);
// - exp_diff == Limb::WIDTH in sub_float_significands_same_prec_gt_w_lt_2w
test(
"19585.2851423168986928116147584507795",
"0x4c81.48ff163dc91a0d4bd90309b0f8#116",
"372369974082165972902790.766638151683",
"0x4eda377c7f0d747fa386.c44265dd58#116",
Nearest,
"-372369974082165972883205.481495834785",
"-0x4eda377c7f0d747f5705.7b434f9f90#116",
Less,
);
// - Limb::WIDTH <= exp_diff < Limb::WIDTH * 2 && a1 < HIGH_BIT in
// sub_float_significands_same_prec_gt_w_lt_2w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) &&
// overflow in sub_float_significands_same_prec_gt_w_lt_2w
test(
"9.9035203142830421991929938e27",
"0x2.000000000000000000000E+23#85",
"16.0",
"0x10.00000000000000000000#85",
Nearest,
"9.9035203142830421991929938e27",
"0x2.000000000000000000000E+23#85",
Greater,
);
// - exp_diff >= Limb::WIDTH * 2 && a1 < HIGH_BIT in sub_float_significands_same_prec_gt_w_lt_2w
test(
"5.3455294200288159103345444e-51",
"0x1.ffffffffc000000000000E-42#83",
"8.0",
"0x8.00000000000000000000#83",
Nearest,
"-8.0",
"-0x8.00000000000000000000#83",
Less,
);
// - x_exp != y_exp && a1 == 0 in sub_float_significands_same_prec_gt_w_lt_2w
test(
"4.00000000000000000000084702",
"0x4.000000000000000003fffc#89",
"3.999999999999999999999999994",
"0x3.fffffffffffffffffffffe#89",
Nearest,
"8.47026484905764768539612568e-22",
"0x3.fffe000000000000000000E-18#89",
Equal,
);
// - rm == Floor || rm == Down in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.00000000000000000005",
"0x1.0000000000000001#65",
"4.0",
"0x4.0000000000000000#65",
Down,
"-2.9999999999999999999",
"-0x2.fffffffffffffffe#65",
Greater,
);
// - rm == Ceiling || rm == Up in sub_float_significands_same_prec_gt_w_lt_2w
// - (rm == Ceiling || rm == Up) && !overflow in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.00000000000000000005",
"0x1.0000000000000001#65",
"4.0",
"0x4.0000000000000000#65",
Up,
"-3.0",
"-0x3.0000000000000000#65",
Less,
);
// - (rm == Ceiling || rm == Up) && overflow in sub_float_significands_same_prec_gt_w_lt_2w
test(
"1.5986723171183083380727715984266450731e-36",
"0x2.1fffffffffff00000000000000ffff8E-30#123",
"2475880078570760549798248448.0",
"0x80000000000000000000000.00000000#123",
Up,
"-2475880078570760549798248448.0",
"-0x80000000000000000000000.00000000#123",
Less,
);
// - in sub_float_significands_same_prec_2w
// - x_exp == y_exp in sub_float_significands_same_prec_2w
// - a1 == 0 && a0 == 0 in sub_float_significands_same_prec_2w
test(
"1.0",
"0x1.00000000000000000000000000000000#128",
"1.0",
"0x1.00000000000000000000000000000000#128",
Nearest,
"0.0",
"0x0.0",
Equal,
);
// - x_exp != y_exp in sub_float_significands_same_prec_2w
// - x_exp < y_exp in sub_float_significands_same_prec_2w
// - exp_diff < Limb::WIDTH in sub_float_significands_same_prec_2w
// - a1 != 0 second time in sub_float_significands_same_prec_2w
// - a1 != 0 third time in sub_float_significands_same_prec_2w
// - x_exp != y_exp && leading_zeros != 0 in sub_float_significands_same_prec_2w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_2w
test(
"1.0",
"0x1.00000000000000000000000000000000#128",
"2.0",
"0x2.00000000000000000000000000000000#128",
Nearest,
"-1.0",
"-0x1.00000000000000000000000000000000#128",
Equal,
);
// - (a1 != 0 || a0 != 0) && a1 >= x_1 in sub_float_significands_same_prec_2w
// - a1 == 0 first time in sub_float_significands_same_prec_2w
// - x_exp == y_exp && leading_zeros != 0 in sub_float_significands_same_prec_2w
test(
"1.0",
"0x1.00000000000000000000000000000000#128",
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#128",
Nearest,
"-5.87747175411143753984368268611122838909e-39",
"-0x2.00000000000000000000000000000000E-32#128",
Equal,
);
// - (a1 != 0 || a0 != 0) && a1 < x_1 in sub_float_significands_same_prec_2w
test(
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#128",
"1.0",
"0x1.00000000000000000000000000000000#128",
Nearest,
"5.87747175411143753984368268611122838909e-39",
"0x2.00000000000000000000000000000000E-32#128",
Equal,
);
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_2w
// - neg in sub_float_significands_same_prec_2w
// - rm == Nearest in sub_float_significands_same_prec_2w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & 1) != 0) && !overflow in
// sub_float_significands_same_prec_2w
test(
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#128",
"4.0",
"0x4.00000000000000000000000000000000#128",
Nearest,
"-3.0",
"-0x3.00000000000000000000000000000000#128",
Less,
);
// - !neg in sub_float_significands_same_prec_2w
test(
"4.0",
"0x4.00000000000000000000000000000000#128",
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#128",
Nearest,
"3.0",
"0x3.00000000000000000000000000000000#128",
Greater,
);
// - rm == Nearest && (round_bit == 0 || (sticky_bit == 0 && (diff_0 & 1) == 0)) in
// sub_float_significands_same_prec_2w
test(
"1.000000000000000000000000000000000000018",
"0x1.00000000000000000000000000000006#128",
"4.0",
"0x4.00000000000000000000000000000000#128",
Nearest,
"-2.99999999999999999999999999999999999998",
"-0x2.fffffffffffffffffffffffffffffff8#128",
Greater,
);
// - x_exp != y_exp && leading_zeros == 0 in sub_float_significands_same_prec_2w
test(
"1.91698663575347889601435178329077738407e-37",
"0x4.13b4f0d218450fb6f5f6d50e7b8f6eb0E-31#128",
"8.0669110092962644724944820639408319804e-34",
"0x4.3046c1d7c0f5b6be39df2b03f3e49a70E-28#128",
Nearest,
"-8.06499402266051099359846771215754120301e-34",
"-0x4.30058688b3d4326d3e6fcb96a2fce178E-28#128",
Greater,
);
// - exp_diff >= Limb::WIDTH * 2 in sub_float_significands_same_prec_2w
// - x_1 > HIGH_BIT || x_0 > 0 in sub_float_significands_same_prec_2w
test(
"5.80991149045382428948889299639419733262e-6",
"0x0.00006179613d776a1c835894818a219f488e8#128",
"5.07801249136957145270807726205511855421e-45",
"0x1.cfd8608b7c32de2bbcfecf8bcf8a2d00E-37#128",
Nearest,
"5.80991149045382428948889299639419733262e-6",
"0x0.00006179613d776a1c835894818a219f488e8#128",
Greater,
);
// - Limb::WIDTH <= exp_diff < Limb::WIDTH * 2 in sub_float_significands_same_prec_2w
// - Limb::WIDTH < exp_diff < Limb::WIDTH * 2 in sub_float_significands_same_prec_2w
// - a1 >= HIGH_BIT in sub_float_significands_same_prec_2w
test(
"4354249796990942.35435357526597783143164",
"0xf782ac869b7de.5ab6ea78fcf0cc5079f#128",
"8.03239453825726512240307053405256016022e-10",
"0x3.732bce7aa121827a284545a25f32dc68E-8#128",
Nearest,
"4354249796990942.35435357446273837760591",
"0xf782ac869b7de.5ab6ea7589c4fdd5d8d#128",
Greater,
);
// - a1 != 0 first time in sub_float_significands_same_prec_2w
test(
"852777855057.113455599443829872557360137",
"0xc68d856851.1d0b6d1928c98779f28bdd#128",
"869223500084.503694559376384046083491558",
"0xca61c20934.80f2206bb1d7d5cad69caa#128",
Nearest,
"-16445645027.39023895993255417352613142066",
"-0x3d43ca0e3.63e6b352890e4e50e410cd00#128",
Equal,
);
// - exp_diff == Limb::WIDTH in sub_float_significands_same_prec_2w
test(
"1.057437459917463716438672572710788562701e-17",
"0xc.310127aae1df1a1cb12f60c4d339d76E-15#128",
"148.0549133677002965445211858794413066474",
"0x94.0e0ecd6e62d0a8c7c7c2a633277e3e#128",
Nearest,
"-148.054913367700296533946811280266669483",
"-0x94.0e0ecd6e62d0a804b7b02b85098c9c#128",
Greater,
);
// - x_1 <= HIGH_BIT && x_0 <= 0 in sub_float_significands_same_prec_2w
// - exp_diff != TWICE_WIDTH || tst in sub_float_significands_same_prec_2w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & 1) != 0) && overflow in
// sub_float_significands_same_prec_2w
test(
"3.83123885216472214589586756787577295905e53",
"0x4.00000000000000000000000000000000E+44#128",
"9.09494703466994132423639742106012939545e-13",
"0x1.00000008000000000000007fffffff80E-10#128",
Nearest,
"3.83123885216472214589586756787577295905e53",
"0x4.00000000000000000000000000000000E+44#128",
Greater,
);
// - a1 < HIGH_BIT in sub_float_significands_same_prec_2w
test(
"0.000473141670219947088192358501321236008969",
"0x0.001f01fffffe001ffe000000000003ffff0#128",
"144115188075855872.000000000007275846592",
"0x200000000000000.0000000007fff80000#128",
Nearest,
"-144115188075855871.9995268583370558995037",
"-0x1ffffffffffffff.ffe0fe000801f7e002#128",
Less,
);
// - a1 == 0 second time in sub_float_significands_same_prec_2w
test(
"1.192092895507812500000000000000000918348e-7",
"0x2.0000000000000000000000000007fffcE-6#128",
"1.19209289550781249999999999999999632658e-7",
"0x1.ffffffffffffffffffffffffffe00000E-6#128",
Nearest,
"4.5917678014072389539175224798764807294e-40",
"0x2.7fffc000000000000000000000000000E-33#128",
Equal,
);
// - exp_diff == TWICE_WIDTH && !tst in sub_float_significands_same_prec_2w
test(
"1024.0",
"0x400.000000000000000000000000000000#128",
"5.97151130219911582898625687582100437209e-36",
"0x7.f00000001fffffffffffffffe0000000E-30#128",
Nearest,
"1023.999999999999999999999999999999999994",
"0x3ff.fffffffffffffffffffffffffffff8#128",
Less,
);
// - x_exp == y_exp && leading_zeros == 0 in sub_float_significands_same_prec_2w
test(
"0.249999999999999999999999999974756451033",
"0x0.3ffffffffffffffffffffffe000000000#128",
"0.2499999999999999999864474728691747435412",
"0x0.3fffffffffffffffc0000001ffffffffc#128",
Nearest,
"1.35525271055817074916830884337875729072e-20",
"0x3.ffffffc0000000040000000000000000E-17#128",
Equal,
);
// - a1 == 0 third time in sub_float_significands_same_prec_2w
test(
"8.0",
"0x8.0000000000000000000000000000000#128",
"7.99999999999999999999999999999999999998",
"0x7.fffffffffffffffffffffffffffffff8#128",
Nearest,
"2.35098870164457501593747307444449135564e-38",
"0x8.0000000000000000000000000000000E-32#128",
Equal,
);
// - rm == Floor || rm == Down in sub_float_significands_same_prec_2w
test(
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#128",
"4.0",
"0x4.00000000000000000000000000000000#128",
Down,
"-2.99999999999999999999999999999999999999",
"-0x2.fffffffffffffffffffffffffffffffc#128",
Greater,
);
// - rm == Ceiling || rm == Up in sub_float_significands_same_prec_2w
// - (rm == Ceiling || rm == Up) && !overflow in sub_float_significands_same_prec_2w
test(
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#128",
"4.0",
"0x4.00000000000000000000000000000000#128",
Up,
"-3.0",
"-0x3.00000000000000000000000000000000#128",
Less,
);
// - (rm == Ceiling || rm == Up) && overflow in sub_float_significands_same_prec_2w
test(
"77371252455336267181195264.0",
"0x4000000000000000000000.00000000000#128",
"4.93038066207960562897601098365736701192e-32",
"0x1.00000003e00000000001ff000000001eE-26#128",
Up,
"77371252455336267181195264.0",
"0x4000000000000000000000.00000000000#128",
Greater,
);
// - rm == Floor || rm == Down in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.000000000000000000000000000000000000003",
"0x1.00000000000000000000000000000001#129",
"4.0",
"0x4.00000000000000000000000000000000#129",
Down,
"-2.999999999999999999999999999999999999994",
"-0x2.fffffffffffffffffffffffffffffffe#129",
Greater,
);
// - rm == Ceiling || rm == Up in sub_float_significands_same_prec_gt_2w_lt_3w
// - (rm == Ceiling || rm == Up) && overflow in sub_float_significands_same_prec_gt_2w_lt_3w
// - (rm == Ceiling || rm == Up) && diff_1 == 0 && diff_0 == 0 in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - (rm == Ceiling || rm == Up) && diff_2 != 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.000000000000000000000000000000000000003",
"0x1.00000000000000000000000000000001#129",
"4.0",
"0x4.00000000000000000000000000000000#129",
Up,
"-3.0",
"-0x3.00000000000000000000000000000000#129",
Less,
);
// - (rm == Ceiling || rm == Up) && !overflow in sub_float_significands_same_prec_gt_2w_lt_3w
// - (rm == Ceiling || rm == Up) && (diff_1 != 0 || diff_0 != 0) in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.000000000000000000000000000000000000009",
"0x1.00000000000000000000000000000003#129",
"4.0",
"0x4.00000000000000000000000000000000#129",
Up,
"-2.999999999999999999999999999999999999994",
"-0x2.fffffffffffffffffffffffffffffffe#129",
Less,
);
// - (rm == Ceiling || rm == Up) && diff_2 == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"3.982729777831130692572200994412995874342180298e-59",
"0x3.ffffffffffffffffffffffff800000000000000E-49#155",
"9.31322574615478515625e-10",
"0x4.00000000000000000000000000000000000000E-8#155",
Floor,
"-9.31322574615478515625e-10",
"-0x4.00000000000000000000000000000000000000E-8#155",
Less,
);
// - in sub_float_significands_same_prec_gt_2w_lt_3w
// - x_exp == y_exp in sub_float_significands_same_prec_gt_2w_lt_3w
// - a2 == 0 && a1 == 0 && a0 == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.0",
"0x1.00000000000000000000000000000000#129",
"1.0",
"0x1.00000000000000000000000000000000#129",
Nearest,
"0.0",
"0x0.0",
Equal,
);
// - x_exp != y_exp in sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff < Limb::WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff < Limb::WIDTH && sticky_bit == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff < Limb::WIDTH && a2 != 0 first time in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff < Limb::WIDTH && leading_zeros != 0 in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.0",
"0x1.00000000000000000000000000000000#129",
"2.0",
"0x2.00000000000000000000000000000000#129",
Nearest,
"-1.0",
"-0x1.00000000000000000000000000000000#129",
Equal,
);
// - x_exp >= y_exp in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"2.0",
"0x2.00000000000000000000000000000000#129",
"1.0",
"0x1.00000000000000000000000000000000#129",
Nearest,
"1.0",
"0x1.00000000000000000000000000000000#129",
Equal,
);
// - (a2 != 0 || a1 != 0 || a0 != 0) && a2 >= x_2 in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - x_exp == y_exp && a2 == 0 first time in sub_float_significands_same_prec_gt_2w_lt_3w
// - x_exp == y_exp && a2 == 0 second time in sub_float_significands_same_prec_gt_2w_lt_3w
// - x_exp == y_exp && leading_zeros == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.0",
"0x1.00000000000000000000000000000000#129",
"1.000000000000000000000000000000000000003",
"0x1.00000000000000000000000000000001#129",
Nearest,
"-2.93873587705571876992184134305561419455e-39",
"-0x1.00000000000000000000000000000000E-32#129",
Equal,
);
// - (a2 != 0 || a1 != 0 || a0 != 0) && a2 < x_2 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.000000000000000000000000000000000000003",
"0x1.00000000000000000000000000000001#129",
"1.0",
"0x1.00000000000000000000000000000000#129",
Nearest,
"2.93873587705571876992184134305561419455e-39",
"0x1.00000000000000000000000000000000E-32#129",
Equal,
);
// - x_exp == y_exp && leading_zeros != 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.0",
"0x1.000000000000000000000000000000000#130",
"1.000000000000000000000000000000000000001",
"0x1.000000000000000000000000000000008#130",
Nearest,
"-1.469367938527859384960920671527807097273e-39",
"-0x8.00000000000000000000000000000000E-33#130",
Equal,
);
// - x_exp == y_exp && a2 != 0 second time in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.0",
"0x1.00000000000000000000000000000000#129",
"1.000000000000000000000000000000000000006",
"0x1.00000000000000000000000000000002#129",
Nearest,
"-5.87747175411143753984368268611122838909e-39",
"-0x2.00000000000000000000000000000000E-32#129",
Equal,
);
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_gt_2w_lt_3w
// - neg in sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest in sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) &&
// overflow in sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) && diff_1
// == 0 && diff_0 == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest && diff_2 != 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.000000000000000000000000000000000000003",
"0x1.00000000000000000000000000000001#129",
"4.0",
"0x4.00000000000000000000000000000000#129",
Nearest,
"-3.0",
"-0x3.00000000000000000000000000000000#129",
Less,
);
// - !neg in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"4.0",
"0x4.00000000000000000000000000000000#129",
"1.000000000000000000000000000000000000003",
"0x1.00000000000000000000000000000001#129",
Nearest,
"3.0",
"0x3.00000000000000000000000000000000#129",
Greater,
);
// - rm == Nearest && round_bit == 0 || (sticky_bit == 0 && (diff_0 & shift_bit) == 0) in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.000000000000000000000000000000000000009",
"0x1.00000000000000000000000000000003#129",
"4.0",
"0x4.00000000000000000000000000000000#129",
Nearest,
"-2.999999999999999999999999999999999999988",
"-0x2.fffffffffffffffffffffffffffffffc#129",
Greater,
);
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) &&
// (diff_1 != 0 || diff_0 != 0) in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"2.000000000000000000000000000000000000006",
"0x2.00000000000000000000000000000002#129",
"0.500000000000000000000000000000000000001",
"0x0.800000000000000000000000000000008#129",
Nearest,
"1.500000000000000000000000000000000000006",
"0x1.80000000000000000000000000000002#129",
Greater,
);
// - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || (diff_0 & shift_bit) != 0) &&
// !overflow in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"2.000000000000000000000000000000000000003",
"0x2.00000000000000000000000000000001#130",
"0.5000000000000000000000000000000000000007",
"0x0.800000000000000000000000000000004#130",
Nearest,
"1.500000000000000000000000000000000000003",
"0x1.800000000000000000000000000000010#130",
Greater,
);
// - TWICE_WIDTH <= exp_diff < THRICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - TWICE_WIDTH < exp_diff < THRICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - TWICE_WIDTH <= exp_diff < THRICE_WIDTH && a2 >= HIGH_BIT in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"2.024076700393272432111968987625898501371897741e-29",
"0x1.9a88122864b9c4b577e4b655958954f82345dE-24#149",
"245906107849378561117126906.9059035528266331265",
"0xcb68a4d1611415054400fa.e7e94b94b8791630#149",
Nearest,
"-245906107849378561117126906.9059035528266331265",
"-0xcb68a4d1611415054400fa.e7e94b94b8791630#149",
Less,
);
// - exp_diff >= THRICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff >= THRICE_WIDTH && a2 >= HIGH_BIT in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"4.397610888919711045634814958598336677777534377e47",
"0x4.d0791b9428a6b4fc52e44e537ab5a0f269ad60E+39#155",
"6.8892360159362421595728818935378487832685754059e-50",
"0x1.9c693c182df3035eef00d41638bbdd942f4d498E-41#155",
Nearest,
"4.397610888919711045634814958598336677777534377e47",
"0x4.d0791b9428a6b4fc52e44e537ab5a0f269ad60E+39#155",
Greater,
);
// - exp_diff < Limb::WIDTH && leading_zeros == 0 in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"4.9709672065181108960570410290811793724062284431352e-48",
"0x7.43dc113e95ca123693650af31435eac45c0e7a680E-40#165",
"5.2183974782595301717751266872943662193587933931613e-47",
"0x4.c4457ca8b3429511981a96eb0c2de4fdb8c43bea4E-39#165",
Nearest,
"-4.7213007576077190821694225843862482821181705488478e-47",
"-0x4.5007bb94c9e5f3ee2ee4463bdaea865173035443cE-39#165",
Equal,
);
// - exp_diff < Limb::WIDTH && sticky_bit != 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"8.264811372870109665580646414654919646529224699888394e-20",
"0x1.864b7049feb3dcfe49ea910db778157cbe9c2021b44E-16#171",
"0.0007337187065343299500100945131574173571435306249470578",
"0x0.003015c1d959ec54ab97dc58b77c22566586c06119b810#171",
Nearest,
"-0.0007337187065343298673619807844563207013370664783978612",
"-0x0.003015c1d959ec53254c6c0eb8c845581b9c2f53623ff8#171",
Greater,
);
// - Limb::WIDTH <= exp_diff < TWICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - Limb::WIDTH < exp_diff < TWICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
// - Limb::WIDTH < exp_diff < TWICE_WIDTH && sticky_bit != 0 in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - Limb::WIDTH < exp_diff < TWICE_WIDTH && a2 >= HIGH_BIT in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"4.2850537238606374652351877988811796373898773e-22",
"0x2.0607fd4819748c532aad3528693c1e3c1966E-18#146",
"978.49328809934495391839880801989439981236569",
"0x3d2.7e4820fe314caadcb9a156bef2f1c8e53c#146",
Nearest,
"-978.49328809934495391839837951452201374861917",
"-0x3d2.7e4820fe314caadcb79b4ec1aad85458e9#146",
Less,
);
// - Limb::WIDTH < exp_diff < TWICE_WIDTH && sticky_bit == 0 in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"0.4575080253178526499352273198671695352442",
"0x0.751f3ef665d0ca4dfa2d089979c4e9600#130",
"184366716174337778394.1535133791267987587",
"0x9fe9a278b38ab22da.274ca71ed919c918#130",
Nearest,
"-184366716174337778393.6960053538089461089",
"-0x9fe9a278b38ab22d9.b22d68287348fecc#130",
Less,
);
// - x_exp == y_exp && a2 != 0 first time in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"229.1456159244630209666077998586332154002628588961962846344",
"0xe5.254715d158717849f7198986a38cb415eeea3464b1df38#189",
"175.1335582002789888688278442018847623084238889142385801004",
"0xaf.2230dec64f958583522e37252cf610378914f3127d0bb0#189",
Nearest,
"54.01205772418403209777995565674845309183896998195770453405",
"0x36.0316370b08dbf2c6a4eb52617696a3de65d5415234d388#189",
Equal,
);
// - exp_diff == TWICE_WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"563971925627753843356041629019151473018178607215.42",
"0x62c960337e963a378ba6626ea422d8a5e623986f.6c#165",
"1301375421.83361702516620516356439489325145225661938",
"0x4d9169bd.d567ece47a47ef60371d48c969ba8765d4#165",
Nearest,
"563971925627753843356041629019151473016877231793.59",
"0x62c960337e963a378ba6626ea422d8a598922eb1.98#165",
Greater,
);
// - exp_diff == Limb::WIDTH in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"226.9305090753243797994707628568605406194",
"0xe2.ee35d7bf263fda8c632644ad7c49d98#130",
"4262448175090788889452.984188256984861391",
"0xe71159efd3a67e736c.fbf3c2f8db72fb8#130",
Nearest,
"-4262448175090788889226.053679181660481592",
"-0xe71159efd3a67e728a.0dbdeb39b533210#130",
Less,
);
// - TWICE_WIDTH <= exp_diff < THRICE_WIDTH && a2 < HIGH_BIT in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - rm == Nearest && diff_2 == 0 in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"0.0001220703125",
"0x0.0008000000000000000000000000000000000000#145",
"8.2855746158774225568154012162196749515653053e-50",
"0x1.f0000fc000000000000003fffffffffffffcE-41#145",
Nearest,
"0.0001220703125",
"0x0.0008000000000000000000000000000000000000#145",
Greater,
);
// - Limb::WIDTH < exp_diff < TWICE_WIDTH && a2 < HIGH_BIT in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"0.0156250000000000000000000000252435487789932816416198",
"0x0.040000000000000000000001ffffffc00000000003f#167",
"2.11758236813575084767080625169910490512847748461541e-22",
"0xf.ffffffffffffffffffffffffffffffffff0000000E-19#167",
Nearest,
"0.0156249999999999999997882417884299736942262010164499",
"0x0.03ffffffffffffffff000001ffffffc00000000003f0#167",
Less,
);
// - exp_diff >= THRICE_WIDTH && a2 < HIGH_BIT in sub_float_significands_same_prec_gt_2w_lt_3w
test(
"1.028440348325753776346855739098344065614209916020987e62",
"0x4.000000000000000000000000000000000000000000E+51#168",
"0.00781238079073842683897073489057921223679527623088422",
"0x0.01fffe000007e000000038000007fffffffffe000000#168",
Nearest,
"1.028440348325753776346855739098344065614209916020987e62",
"0x4.000000000000000000000000000000000000000000E+51#168",
Greater,
);
// - exp_diff < Limb::WIDTH && a2 == 0 first time in
// sub_float_significands_same_prec_gt_2w_lt_3w
// - exp_diff < Limb::WIDTH && a2 != 0 second time in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"32767.9999999999999999999999999999999999999999996",
"0x7fff.fffffffffffffffffffffffffffffffffff8#156",
"32768.0000000000000000069388939039072268369037424",
"0x8000.000000000000007ffffffffffff80000000#156",
Nearest,
"-6.93889390390722683690374277451135137549581608853e-18",
"-0x7.ffffffffffff800000008000000000000000000E-15#156",
Equal,
);
// - exp_diff < Limb::WIDTH && a2 == 0 second time in
// sub_float_significands_same_prec_gt_2w_lt_3w
test(
"137438953471.99999999999999999999999999999",
"0x1fffffffff.ffffffffffffffffffffffff#133",
"137438953472.0",
"0x2000000000.000000000000000000000000#133",
Nearest,
"-1.2621774483536188886587657044524579674771e-29",
"-0x1.000000000000000000000000000000000E-24#133",
Equal,
);
// - in sub_float_significands_same_prec_ge_3w
// - x_exp == y_exp in sub_float_significands_same_prec_ge_3w
// - k < 0 in sub_float_significands_same_prec_ge_3w
test(
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
Nearest,
"0.0",
"0x0.0",
Equal,
);
// - x_exp > y_exp in sub_float_significands_same_prec_ge_3w
// - exp_diff == 1 in sub_float_significands_same_prec_ge_3w
// - !goto_sub_d1_no_lose && !goto_sub_d1_lose in sub_float_significands_same_prec_ge_3w
// - limb < HIGH_BIT in sub_float_significands_same_prec_ge_3w
// - exp_diff == 0 in sub_float_significands_same_prec_ge_3w
// - goto_exact_normalize in sub_float_significands_same_prec_ge_3w
// - limb != 0 in sub_float_significands_same_prec_ge_3w
// - exp_diff == 0 && limb != 0 && leading_zeros == 0 in sub_float_significands_same_prec_ge_3w
test(
"2.0",
"0x2.000000000000000000000000000000000000000000000000#192",
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
Nearest,
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
Equal,
);
// - k >= 0 && xs[k] < ys[k] in sub_float_significands_same_prec_ge_3w
// - !goto_exact_normalize in sub_float_significands_same_prec_ge_3w
// - limb == 0 in sub_float_significands_same_prec_ge_3w
// - out[usize::exact_from(k)] != 0 in sub_float_significands_same_prec_ge_3w
// - limb == 0 && leading_zeros != 0 in sub_float_significands_same_prec_ge_3w
test(
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#192",
Nearest,
"-3.186183822264904554057760795535423611182209110385237572148e-58",
"-0x2.000000000000000000000000000000000000000000000000E-48#192",
Equal,
);
// - k >= 0 && xs[k] >= ys[k] in sub_float_significands_same_prec_ge_3w
test(
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#192",
"1.0",
"0x1.000000000000000000000000000000000000000000000000#192",
Nearest,
"3.186183822264904554057760795535423611182209110385237572148e-58",
"0x2.000000000000000000000000000000000000000000000000E-48#192",
Equal,
);
// - exp_diff == 0 && limb != 0 && leading_zeros != 0 in sub_float_significands_same_prec_ge_3w
test(
"2.0",
"0x2.000000000000000000000000000000000000000000000000#192",
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#192",
Nearest,
"0.9999999999999999999999999999999999999999999999999999999997",
"0x0.fffffffffffffffffffffffffffffffffffffffffffffffe#192",
Equal,
);
// - 2 <= exp_diff < prec in sub_float_significands_same_prec_ge_3w
// - dm != 0 && m == 0 in sub_float_significands_same_prec_ge_3w
// - sx != 0 in sub_float_significands_same_prec_ge_3w
// - !out[n - 1].get_highest_bit() in sub_float_significands_same_prec_ge_3w
// - round_bit == 0 in sub_float_significands_same_prec_ge_3w
// - round_bit == 0 && sticky_bit == 0 in sub_float_significands_same_prec_ge_3w
test(
"2.0",
"0x2.000000000000000000000000000000000000000000000000#192",
"0.5",
"0x0.800000000000000000000000000000000000000000000000#192",
Nearest,
"1.5",
"0x1.800000000000000000000000000000000000000000000000#192",
Equal,
);
// - limb == 0 && leading_zeros == 0 in sub_float_significands_same_prec_ge_3w
test(
"1.0",
"0x1.000000000000000000000000000000000000000000000000#193",
"1.0000000000000000000000000000000000000000000000000000000002",
"0x1.000000000000000000000000000000000000000000000001#193",
Nearest,
"-1.5930919111324522770288803977677118055911045551926187860739e-58",
"-0x1.000000000000000000000000000000000000000000000000E-48#193",
Equal,
);
// - sx == 0 in sub_float_significands_same_prec_ge_3w
test(
"2.0",
"0x2.000000000000000000000000000000000000000000000000#193",
"0.5",
"0x0.8000000000000000000000000000000000000000000000000#193",
Nearest,
"1.5",
"0x1.800000000000000000000000000000000000000000000000#193",
Equal,
);
// - round_bit != 0 || sticky_bit != 0 in sub_float_significands_same_prec_ge_3w
// - out_power_of_2 || round_bit == 0 in sub_float_significands_same_prec_ge_3w
// - rm == Nearest in sub_float_significands_same_prec_ge_3w
// - rm == Nearest && !out_power_of_2 first time in sub_float_significands_same_prec_ge_3w
// - rm == Nearest && (round_bit == 0 || (round_bit != 0 && sticky_bit == 0 && (out[0] &
// shift_bit == 0 || prec == 1))) in sub_float_significands_same_prec_ge_3w
test(
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#192",
"4.0",
"0x4.000000000000000000000000000000000000000000000000#192",
Nearest,
"-3.0",
"-0x3.000000000000000000000000000000000000000000000000#192",
Less,
);
// - out[usize::exact_from(k)] == 0 in sub_float_significands_same_prec_ge_3w
test(
"1.0000000000000000000000000000000000000000000000000000000002",
"0x1.000000000000000000000000000000000000000000000001#193",
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#193",
Nearest,
"-1.5930919111324522770288803977677118055911045551926187860739e-58",
"-0x1.000000000000000000000000000000000000000000000000E-48#193",
Equal,
);
// - round_bit != 0 in sub_float_significands_same_prec_ge_3w
test(
"1.0000000000000000000000000000000000000000000000000000000006",
"0x1.000000000000000000000000000000000000000000000004#192",
"4.0",
"0x4.000000000000000000000000000000000000000000000000#192",
Nearest,
"-2.9999999999999999999999999999999999999999999999999999999994",
"-0x2.fffffffffffffffffffffffffffffffffffffffffffffffc#192",
Equal,
);
// - rm == Nearest && round_bit != 0 && (round_bit == 0 || sticky_bit != 0 || (out[0] &
// shift_bit != 0 && prec == 1)) in sub_float_significands_same_prec_ge_3w
// - rm == Nearest && !out_power_of_2 second time in sub_float_significands_same_prec_ge_3w
test(
"1.000000000000000000000000000000000000000000000000000000001",
"0x1.000000000000000000000000000000000000000000000006#192",
"4.0",
"0x4.000000000000000000000000000000000000000000000000#192",
Nearest,
"-2.9999999999999999999999999999999999999999999999999999999987",
"-0x2.fffffffffffffffffffffffffffffffffffffffffffffff8#192",
Greater,
);
// - sticky_bit_2 == 0 && k > 0 third time in sub_float_significands_same_prec_ge_3w
test(
"0.5",
"0x0.8000000000000000000000000000000000000000000000000#193",
"4.0",
"0x4.000000000000000000000000000000000000000000000000#193",
Nearest,
"-3.5",
"-0x3.800000000000000000000000000000000000000000000000#193",
Equal,
);
// - sticky_bit_2 != 0 || k <= 0 third time in sub_float_significands_same_prec_ge_3w
test(
"4.0",
"0x4.000000000000000000000000000000000000000000000000#192",
"0.5000000000000000000000000000000000000000000000000000000002",
"0x0.800000000000000000000000000000000000000000000001#192",
Nearest,
"3.5",
"0x3.800000000000000000000000000000000000000000000000#192",
Greater,
);
// - dm != 0 && m != 0 in sub_float_significands_same_prec_ge_3w
// - out[n - 1].get_highest_bit() in sub_float_significands_same_prec_ge_3w
test(
"7.28057116938384227432903448367767196428679514765398378973101e-48",
"0xa.a3fc2da1f20fb2d9771f86d3c16a444cd62d5d139e3935f24E-40#198",
"3.5123473778825578958968695187657587760357139395948269588971e-27",
"0x1.1646de419a6dbd3466f3081403a87d719b7a765a1ec69e4658E-22#198",
Nearest,
"-3.51234737788255789588958894759637493376138490511114928693281e-27",
"-0x1.1646de419a6dbd345c4f0be661b66dbec20356d34b05340208E-22#198",
Greater,
);
// - exp_diff >= prec in sub_float_significands_same_prec_ge_3w
// - exp_diff > prec in sub_float_significands_same_prec_ge_3w
// - exp_diff != prec + 1 in sub_float_significands_same_prec_ge_3w
test(
"4.1322282880219162156901559575161649173615955518072607291207e86",
"0xd.4b575f05941ee41ef3ef9a37068d9d453f22eb3bf80bd1b0E+71#193",
"0.023991386767031193042066748710708351501952890752924613005724",
"0x0.06244cad8cd272134e34b325815ad281733f2c06231a0ee744#193",
Nearest,
"4.1322282880219162156901559575161649173615955518072607291207e86",
"0xd.4b575f05941ee41ef3ef9a37068d9d453f22eb3bf80bd1b0E+71#193",
Greater,
);
// - dm == 0 in sub_float_significands_same_prec_ge_3w
test(
"6.442552350746554109885349691592991892989624685631192235549e-6",
"0x0.00006c168d38e231899f0fc85d1888549d5177bdceaee72e15060#192",
"1476808010161862576835936576709144.7975622615653024045505082",
"0x48cff00a780a50d34bb694ada218.cc2d0a55f25f9f9126258#192",
Nearest,
"-1476808010161862576835936576709144.7975558190129516579963983",
"-0x48cff00a780a50d34bb694ada218.cc2c9e3f6526bd5f9c868#192",
Less,
);
// - exp_diff == prec + 1 in sub_float_significands_same_prec_ge_3w
// - sticky_bit_2 != 0 || k <= 0 second time in sub_float_significands_same_prec_ge_3w
test(
"29249291732025621624535078208.59212499364958152526111994335",
"0x5e827271f9e9d261e7cb5540.979580eade814aae28ae9d3c8#192",
"1.7056859397843570965021420438616279890690624515282312011749e-30",
"0x2.2986d80d04731f28b49380410e3f4711dc2cc5f113c594a0E-25#192",
Nearest,
"29249291732025621624535078208.59212499364958152526111994335",
"0x5e827271f9e9d261e7cb5540.979580eade814aae28ae9d3c8#192",
Greater,
);
// - limb > HIGH_BIT in sub_float_significands_same_prec_ge_3w
// - y0 != 0 in sub_float_significands_same_prec_ge_3w
test(
"1958139908729.1847354007541959640287427302874567071533816044",
"0x1c7ea3bd279.2f4ad1b8a7190307771c7e5767590237208b90#192",
"688604646855.2266320591592881661509057171162297144871538944",
"0xa054090dc7.3a048f025074a63da83a500a235d2b8fd9766d#192",
Nearest,
"1269535261873.9581033415949077978778370131712269926662277102",
"0x1279632c4b1.f54642b656a45cc9cee22e4d43fbd6a7471524#192",
Greater,
);
// - y0 == 0 in sub_float_significands_same_prec_ge_3w
test(
"2473299914875391681216.10395653853096422269749051583697615",
"0x8613ee70797f97a2c0.1a9ce54d32239153edab6ff15dad1c0#193",
"7716446651886500012256.87778108230244207876352217543002925",
"0x1a24f3592677b2760e0.e0b642d189564d3b4c797ad9c9cde8#193",
Nearest,
"-5243146737011108331040.7738245437714778560660316595930531",
"-0x11c3b4721edfb8fbe20.c6195d845732bbe75ece0ae86c20cc#193",
Equal,
);
// - exp_diff == prec in sub_float_significands_same_prec_ge_3w
// - sticky_bit_2 != 0 || k <= 0 first time in sub_float_significands_same_prec_ge_3w
test(
"4.0635838402455207229400698207668893925379768151364313942222e-23",
"0x3.1202ecf10ff40b477337957dede18bd7b746884ec977474eE-19#194",
"1174582238252884689829665592721065057.76655867827770290150723",
"0xe237601fa3ed6d89b0ae33e924c461.c43d3085aaefab6b5d4#194",
Nearest,
"-1174582238252884689829665592721065057.76655867827770290150718",
"-0xe237601fa3ed6d89b0ae33e924c461.c43d3085aaefab6b5d0#194",
Greater,
);
// - rm == Nearest && out_power_of_2 first time in sub_float_significands_same_prec_ge_3w
test(
"22300745198530623141535718272648361505980416.0",
"0x1000000000000000000000000000000000000.000000000000#192",
"8.470329472543003387009805160583577341645369940072346001613e-22",
"0x3.ffffffffffffffe000000003ff0000003ffffffc00000000E-18#192",
Nearest,
"22300745198530623141535718272648361505980416.0",
"0x1000000000000000000000000000000000000.000000000000#192",
Greater,
);
// - sticky_bit_2 == 0 && k > 0 second time in sub_float_significands_same_prec_ge_3w
test(
"1.6849966666969146159452711670928107852024276704905067469395e66",
"0xf.ffffffffffff01fffff00000000000000000000000000000E+54#193",
"33554432.00000000000000044408920985006261616945266723632812",
"0x2000000.0000000000001ffffffffffffffffffffffffffffe#193",
Nearest,
"1.6849966666969146159452711670928107852024276704905067469395e66",
"0xf.ffffffffffff01fffff00000000000000000000000000000E+54#193",
Greater,
);
// - limb == HIGH_BIT in sub_float_significands_same_prec_ge_3w
// - l >= 0 first time in sub_float_significands_same_prec_ge_3w
// - xs[l] != yl_shifted in sub_float_significands_same_prec_ge_3w
// - l >= 0 && xs[l] <= yl_shifted in sub_float_significands_same_prec_ge_3w
// - goto_sub_d1_no_lose || goto_sub_d1_lose in sub_float_significands_same_prec_ge_3w
test(
"2047.9999999999999999999999999999747564510329303127198868805",
"0x7ff.fffffffffffffffffffffffe00000000003c000003fffc#193",
"4095.99999999999999988897769753748434595763683319091796875",
"0xfff.fffffffffffff800000000000000000000000000000000#193",
Nearest,
"-2047.9999999999999998889776975375095895066039028781980818695",
"-0x7ff.fffffffffffff80000000001ffffffffffc3fffffc0004#193",
Equal,
);
// - sticky_bit_2 == 0 && k > 0 first time in sub_float_significands_same_prec_ge_3w
test(
"0.0002442598197376355528831482438462803411504065058668775410457",
"0x0.001001fff000000000000003ffff00000001fffffff07fffffe#192",
"5.834076822994820350447560050418866475553361427251759468222e-62",
"0x1.8000000000000000000000000000000000001c00007ffffeE-51#192",
Nearest,
"0.00024425981973763555288314824384628034115040650586687754104564",
"0x0.001001fff000000000000003ffff00000001fffffff07fffffc#192",
Less,
);
// - l >= 0 && xs[l] > yl_shifted in sub_float_significands_same_prec_ge_3w
test(
"127.99999999999999999999998841947063540272586186468301133273",
"0x7f.fffffffffffffffffff1fffff00007ffffffffffffffff8#192",
"255.99999999999999999999999979320484686174308128214782699291",
"0xff.ffffffffffffffffffffc00000000000000000000000ff#192",
Nearest,
"-128.0000000000000000000000113737342114590172194174648156602",
"-0x80.0000000000000000000dc0000ffff80000000000000100#192",
Less,
);
// - out_power_of_2 && round_bit != 0 in sub_float_significands_same_prec_ge_3w
test(
"81129638414606681695789005144064.0",
"0x400000000000000000000000000.0000000000000000000000#193",
"6.46392625738094777466974989455420015132331189664152496326e-27",
"0x2.001ffffffffe0000001fffff000000ffffff80000000000eE-22#193",
Nearest,
"81129638414606681695789005144063.999999999999999999999999994",
"0x3ffffffffffffffffffffffffff.fffffffffffffffffffffe#193",
Greater,
);
// - rm == Nearest && out_power_of_2 second time in sub_float_significands_same_prec_ge_3w
test(
"9.5367431640625e-7",
"0x0.00001000000000000000000000000000000000000000000000000#192",
"7.596455102175746880546879414772134233793171691679642324806e-65",
"0x8.00000ffffffffffe000000000000000000000000001ffffE-54#192",
Nearest,
"9.536743164062499999999999999999999999999999999999999999998e-7",
"0xf.fffffffffffffffffffffffffffffffffffffffffffffffE-6#192",
Less,
);
// - xs[l] == yl_shifted in sub_float_significands_same_prec_ge_3w
test(
"1180591620717411303423.9999999999999999999999999999999999998",
"0x3fffffffffffffffff.ffffffffffffffffffffffffffffffc#192",
"2361183241434822606847.9999999999999999930619531290400259223",
"0x7fffffffffffffffff.ffffffffffffff8003ffffffffffff8#192",
Nearest,
"-1180591620717411303423.9999999999999999930619531290400259225",
"-0x3fffffffffffffffff.ffffffffffffff8003ffffffffffffc#192",
Equal,
);
// - l < 0 first time in sub_float_significands_same_prec_ge_3w
// - l < 0 second time in sub_float_significands_same_prec_ge_3w
// - yl_shifted != 0 in sub_float_significands_same_prec_ge_3w
test(
"32767.999999999999999999999999999999999999999999999999999995",
"0x7fff.ffffffffffffffffffffffffffffffffffffffffffff8#192",
"65535.99999999999999999999999999999999999999999999999999999",
"0xffff.ffffffffffffffffffffffffffffffffffffffffffff#192",
Nearest,
"-32767.999999999999999999999999999999999999999999999999999995",
"-0x7fff.ffffffffffffffffffffffffffffffffffffffffffff8#192",
Equal,
);
// - yl_shifted == 0 in sub_float_significands_same_prec_ge_3w
test(
"34359738367.999999999999999999999999999999999999999999999989",
"0x7ffffffff.fffffffffffffffffffffffffffffffffffffff0#192",
"68719476735.99999999999999999999999999999999999999999999999",
"0xfffffffff.fffffffffffffffffffffffffffffffffffffff#192",
Nearest,
"-34359738368.0",
"-0x800000000.000000000000000000000000000000000000000#192",
Equal,
);
// - neg in sub_float_significands_same_prec_ge_3w
// - rm == Down || rm == Floor in sub_float_significands_same_prec_ge_3w
// - (rm == Down || rm == Floor) && !out_power_of_2 in sub_float_significands_same_prec_ge_3w
test(
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#192",
"4.0",
"0x4.000000000000000000000000000000000000000000000000#192",
Down,
"-2.9999999999999999999999999999999999999999999999999999999994",
"-0x2.fffffffffffffffffffffffffffffffffffffffffffffffc#192",
Greater,
);
// - !neg in sub_float_significands_same_prec_ge_3w
test(
"4.0",
"0x4.000000000000000000000000000000000000000000000000#192",
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#192",
Down,
"2.9999999999999999999999999999999999999999999999999999999994",
"0x2.fffffffffffffffffffffffffffffffffffffffffffffffc#192",
Less,
);
// - rm == Up || rm == Ceiling in sub_float_significands_same_prec_ge_3w
test(
"1.0000000000000000000000000000000000000000000000000000000003",
"0x1.000000000000000000000000000000000000000000000002#192",
"4.0",
"0x4.000000000000000000000000000000000000000000000000#192",
Up,
"-3.0",
"-0x3.000000000000000000000000000000000000000000000000#192",
Less,
);
// - (rm == Down || rm == Floor) && out_power_of_2 in sub_float_significands_same_prec_ge_3w
test(
"5.392603845001725202291044579550746038551121674218581060912e-33",
"0x1.c0000000fffffffffffffffffffffffffffffffffffffffeE-27#192",
"1329227995784915872903807060280344576.0",
"0x1000000000000000000000000000000.000000000000000000#192",
Ceiling,
"-1329227995784915872903807060280344575.9999999999999999999998",
"-0xffffffffffffffffffffffffffffff.ffffffffffffffffff#192",
Greater,
);
test(
"1.0", "0x1.0#1", "1.5", "0x1.8#2", Nearest, "-0.5", "-0x0.8#2", Equal,
);
test(
"0.5", "0x0.8#1", "3.0", "0x3.0#2", Nearest, "-2.0", "-0x2.0#2", Greater,
);
test(
"0.2", "0x0.4#1", "4.0", "0x4.0#2", Nearest, "-4.0", "-0x4.0#2", Less,
);
test(
"0.00374222828352849",
"0x0.00f5402c178824#46",
"1.07183972513958531257713938927815e-11",
"0xb.c8f5eafa12eb9821601f1dd6aeE-10#107",
Nearest,
"0.00374222827281009532032311766811006",
"0x0.00f5402c0bbf2e1505ed1467de9fe#107",
Less,
);
test(
"2589062031404.0",
"0x25ad01f682c.0#43",
"4351572166934988.581719655389852344796925751245753159273257621838622031922945531041952618\
810238932316",
"0xf75bb593981cc.94eb944f56fd85d744c7e812bf078ed9a4f5d3086fdab71e98a907840097016cb76fdc\
#330",
Nearest,
"-4348983104903584.58171965538985234479692575124575315927325762183862203192294553104195261\
8810238932316",
"-0xf7360891a19a0.94eb944f56fd85d744c7e812bf078ed9a4f5d3086fdab71e98a907840097016cb76fdc\
#330",
Equal,
);
// - in sub_float_significands_general
// - in exponent_shift_compare
// - sdiff_exp >= 0 in exponent_shift_compare
// - diff_exp == 0 first time in exponent_shift_compare
// - xi >= 0 && yi >= 0 && xs[xi] == ys[yi] in exponent_shift_compare
// - xi < 0 in exponent_shift_compare
// - xi < 0 && yi < 0 in exponent_shift_compare
// - sign == Equal in sub_float_significands_general
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#2", Nearest, "0.0", "0x0.0", Equal,
);
// - diff_exp != 0 first time in exponent_shift_compare
// - diff_exp < Limb::WIDTH in exponent_shift_compare
// - diff_exp != 0 second time in exponent_shift_compare
// - (yi < 0 && lasty == 0) || high_dif != 0 || dif != 1 in exponent_shift_compare
// - high_dif == 0 in exponent_shift_compare
// - dif.is_power_of_2() in exponent_shift_compare
// - yi < 0 && lasty == 0 in exponent_shift_compare
// - sign != Equal in sub_float_significands_general
// - sign != Less in sub_float_significands_general
// - !neg in sub_float_significands_general
// - max(out_prec, x_prec) + 2 > exp_diff in sub_float_significands_general
// - shift_x != 0 in sub_float_significands_general
// - shift_y == 0 in sub_float_significands_general
// - cancel >= exp_diff in sub_float_significands_general
// - out_len + cancel1 <= xs_len in sub_float_significands_general
// - out_len + cancel2 > 0 in sub_float_significands_general
// - cancel2 >= 0 in sub_float_significands_general
// - out_len + cancel2 <= ys_len in sub_float_significands_general
// - rm == Nearest in sub_float_significands_general
// - rm == Nearest && carry <= Limb::power_of_2(sh - 1) && (0 >= carry || carry >=
// Limb::power_of_2(sh - 1)) in sub_float_significands_general
// - !goto_truncate in sub_float_significands_general
// - ixs_len <= 0 && iys_len <= 0 in sub_float_significands_general
// - !goto_truncate && !goto_end_of_sub second time in sub_float_significands_general
// - rm != Nearest || cmp_low == 0 in sub_float_significands_general
// - !goto_end_of_sub in sub_float_significands_general
// - out[out_len - 1] >> (Limb::WIDTH - 1) != 0 in sub_float_significands_general
// - cancel != 0 in sub_float_significands_general
test(
"2.0", "0x2.0#1", "1.0", "0x1.0#2", Nearest, "1.0", "0x1.0#2", Equal,
);
// - sdiff_exp < 0 in exponent_shift_compare
// - sign == Less in sub_float_significands_general
// - neg in sub_float_significands_general
test(
"1.0", "0x1.0#2", "2.0", "0x2.0#1", Nearest, "-1.0", "-0x1.0#2", Equal,
);
// - xi < 0 || yi < 0 || xs[xi] != ys[yi] in exponent_shift_compare
// - xi >= 0 in exponent_shift_compare
// - yi >= 0 second time in exponent_shift_compare
// - xs[xi] < ys[yi] in exponent_shift_compare
// - diff_exp == 0 second time in exponent_shift_compare
// - shift_y != 0 in sub_float_significands_general
test(
"1.0", "0x1.0#1", "1.5", "0x1.8#2", Nearest, "-0.5", "-0x0.8#2", Equal,
);
// - xs[xi] >= ys[yi] in exponent_shift_compare
test(
"1.5", "0x1.8#2", "1.0", "0x1.0#1", Nearest, "0.5", "0x0.8#2", Equal,
);
// - shift_x == 0 in sub_float_significands_general
// - cancel < exp_diff in sub_float_significands_general
// - ixs_len > 0 || iys_len > 0 in sub_float_significands_general
// - ixs_len <= 0 in sub_float_significands_general
// - iys_len condition in sub_float_significands_general
// - cmp_low == 0 first time in sub_float_significands_general
// - rm == Nearest && (sh != 0 || k != 0) in sub_float_significands_general
// - cmp_low == 0 second time in sub_float_significands_general
// - !goto_truncate && !goto_end_of_sub first time in sub_float_significands_general
// - cancel == 0 in sub_float_significands_general
test(
"0.5", "0x0.8#1", "1.5", "0x1.8#2", Nearest, "-1.0", "-0x1.0#2", Equal,
);
// - !dif.is_power_of_2() in exponent_shift_compare
test(
"0.5", "0x0.8#1", "2.0", "0x2.0#2", Nearest, "-1.5", "-0x1.8#2", Equal,
);
// - cmp_low != 0 first time in sub_float_significands_general
// - cmp_low > 0 in sub_float_significands_general
// - cmp_low > 0 && rm == Nearest in sub_float_significands_general
// - cmp_low > 0 && rm == Nearest && xx == yy in sub_float_significands_general
// - rm == Nearest && cmp_low != 0 in sub_float_significands_general
// - (out[0] >> sh) & 1 == 0 in sub_float_significands_general
test(
"0.5", "0x0.8#1", "3.0", "0x3.0#2", Nearest, "-2.0", "-0x2.0#2", Greater,
);
// - (out[0] >> sh) & 1 != 0 in sub_float_significands_general
// - cmp_low >= 0 in sub_float_significands_general
// - cmp_low >= 0 && !carry in sub_float_significands_general
test(
"4.0", "0x4.0#1", "1.2", "0x1.4#3", Nearest, "3.0", "0x3.0#3", Greater,
);
// - cmp_low >= 0 && carry in sub_float_significands_general
test(
"4.0", "0x4.0#1", "0.5", "0x0.8#2", Nearest, "4.0", "0x4.0#2", Greater,
);
// - rm == Nearest && carry > Limb::power_of_2(sh - 1) in sub_float_significands_general
// - goto_truncate in sub_float_significands_general
test(
"3.0", "0x3.0#2", "0.2", "0x0.4#1", Nearest, "3.0", "0x3.0#2", Greater,
);
// - rm == Nearest && carry <= Limb::power_of_2(sh - 1) && 0 < carry && carry <
// Limb::power_of_2(sh - 1) in sub_float_significands_general
test(
"4.0", "0x4.0#1", "0.8", "0x0.c#2", Nearest, "3.0", "0x3.0#2", Less,
);
// - max(out_prec, x_prec) + 2 <= exp_diff in sub_float_significands_general
// - in round_helper
// - dest_prec >= x_prec in round_helper
// - !increment_exp in sub_float_significands_general
// - inexact == 0 && rm != Down && rm != Floor in sub_float_significands_general
test(
"0.2", "0x0.4#1", "4.0", "0x4.0#2", Nearest, "-4.0", "-0x4.0#2", Less,
);
// - diff_exp >= Limb::WIDTH in exponent_shift_compare first time
test(
"8.82188e11",
"0xc.d668E+9#18",
"9.75459983374e122",
"0x1.79c17f063aE+102#40",
Nearest,
"-9.75459983374e122",
"-0x1.79c17f063aE+102#40",
Less,
);
// - cancel2 < 0 in sub_float_significands_general
// - out_len - neg_cancel2 <= ys_len in sub_float_significands_general
test(
"3.29008365861415556134836580980448399733562188e-9",
"0xe.217c389f8c9fd22042f5ed70da20cfb9f1ecE-8#146",
"3719044561792922503530448846362960.3599330496921301151502834994",
"0xb75cf116bc625ef1eab58f3c9950.5c2492852d5fb6817443c180#205",
Nearest,
"-3719044561792922503530448846362960.359933046402046456536127938",
"-0xb75cf116bc625ef1eab58f3c9950.5c2492770be37de1e7a3ef60#205",
Less,
);
// - out_len + cancel1 > xs_len in sub_float_significands_general
// - cancel1 < xs_len in sub_float_significands_general
test(
"1.07183972513958531257713938927815e-11",
"0xb.c8f5eafa12eb9821601f1dd6aeE-10#107",
"0.00374222828352849",
"0x0.00f5402c178824#46",
Nearest,
"-0.00374222827281009532032311766811006",
"-0x0.00f5402c0bbf2e1505ed1467de9fe#107",
Greater,
);
// - out_len + cancel2 > ys_len in sub_float_significands_general
test(
"2589062031404.0",
"0x25ad01f682c.0#43",
"4351572166934988.581719655389852344796925751245753159273257621838622031922945531041952618\
810238932316",
"0xf75bb593981cc.94eb944f56fd85d744c7e812bf078ed9a4f5d3086fdab71e98a907840097016cb76fdc\
#330",
Nearest,
"-4348983104903584.58171965538985234479692575124575315927325762183862203192294553104195261\
8810238932316",
"-0xf7360891a19a0.94eb944f56fd85d744c7e812bf078ed9a4f5d3086fdab71e98a907840097016cb76fdc\
#330",
Equal,
);
// - yi >= 0 && lasty != 0 in exponent_shift_compare
// - xi < 0 fourth time in exponent_shift_compare
// - lasty == 0 in exponent_shift_compare
// - yi < 0 || ys[yi] != 0 in exponent_shift_compare
// - yi >= 0 fourth time in exponent_shift_compare
test(
"0.002",
"0x0.008#2",
"1.107886492190627864290739752375593855464628579e-38",
"0x3.c51af197224960473945f6944424f855697e2E-32#149",
Nearest,
"0.001953124999999999999999999999999999988921135078",
"0x0.007ffffffffffffffffffffffffffffc3ae50e68#149",
Less,
);
// - cmp_low > 0 && rm == Nearest && xx < yy in sub_float_significands_general
// - goto_truncate || goto_end_of_sub first time in sub_float_significands_general
// - goto_truncate || goto_end_of_sub second time in sub_float_significands_general
test(
"1.521287e-9",
"0x6.88ac4E-8#21",
"6.842391932190563625e-20",
"0x1.431f7157e61b20d0E-16#62",
Nearest,
"1.5212870962270854807e-9",
"0x6.88ac3ffebce08eaE-8#62",
Less,
);
// - out_len - neg_cancel2 > ys_len in sub_float_significands_general
test(
"0.00678514868524062",
"0x0.01bcabe7b39c71#49",
"492541199943575879969.43922949854802247248767794847124160758",
"0x1ab361dbc0e97d4121.7071582bb3c5bd22b8f59cfc93c72a98#194",
Nearest,
"-492541199943575879969.43244434986278185350564935536210679008",
"-0x1ab361dbc0e97d4121.6eb4ac4400294c22b8f59cfc93c72a98#194",
Equal,
);
// - rm == Nearest && sh == 0 && k == 0 in sub_float_significands_general
// - rm == Nearest && cmp_low >= 0 in sub_float_significands_general
// - rm == Nearest && cmp_low >= 0 && yy < half in sub_float_significands_general
// - rm == Nearest && cmp_low >= 0 && cmp_low <= 0 in sub_float_significands_general
test(
"5.7505515877842013577e-7",
"0x9.a5d7d56cabed47dE-6#64",
"1.1758894e-14",
"0x3.4f515E-12#22",
Nearest,
"5.7505514701952590309e-7",
"0x9.a5d7d21d5a9d47dE-6#64",
Equal,
);
// - rm == Nearest && cmp_low < 0 in sub_float_significands_general
// - rm == Nearest && cmp_low < 0 && yy < half in sub_float_significands_general
// - cmp_low < 0 in sub_float_significands_general first time
// - cmp_low < 0 && rm == Nearest in sub_float_significands_general
// - rm == Nearest && (xx > yy || sh > 0 || cmp_low == -1) in sub_float_significands_general
test(
"8319983682.218895978935307677994592087137128849954503237724",
"0x1efe8e042.3809911ec0c7f99b114d2930720001b00aa46846#192",
"1.88392800575e35",
"0x2.4487b7174E+29#37",
Nearest,
"-188392800574747474298435817696599997.78110402106469232200542",
"-0x24487b7173fffffffffffe10171fbd.c7f66ee13f380664eec#192",
Less,
);
// - rm == Nearest && cmp_low < 0 && yy >= half in sub_float_significands_general
// - rm == Nearest && xx < yy && sh <= 0 && cmp_low != -1 in sub_float_significands_general
// - goto_end_of_sub in sub_float_significands_general
test(
"2.36288970224581301467472547462526069521e-27",
"0xb.b3518c72d51185c09977eb6e009c2c0E-23#128",
"3.413020751e-12",
"0x3.c0ae105E-10#30",
Nearest,
"-3.413020751029435178256669624768773569e-12",
"-0x3.c0ae104fffff44cae738d2aee7a3f668E-10#128",
Greater,
);
// - xi >= 0 fourth time in exponent_shift_compare
// - diff_exp >= Limb::WIDTH in exponent_shift_compare second time
// - xs[xi] == yy in exponent_shift_compare
test(
"1125899906842624.0",
"0x4000000000000.000000000000#98",
"1.166815364554e-61",
"0x2.ffffffff80E-51#39",
Nearest,
"1125899906842624.0",
"0x4000000000000.000000000000#98",
Greater,
);
// - 0 < diff_exp < Limb::WIDTH && yi >= 0 in exponent_shift_compare
// - xs[xi] != yy in exponent_shift_compare
test(
"9671406556917033397649408.0",
"0x800000000000000000000.0000#99",
"65536.015624999999999999946",
"0x10000.03ffffffffffffff00#87",
Nearest,
"9671406556917033397583871.98438",
"0x7fffffffffffffffeffff.fc00#99",
Less,
);
// - diff_exp == 0 && yi >= 0 in exponent_shift_compare
test(
"1.3877787807814456370485565165946e-17",
"0xf.ffffffffffffe007ffffffff8E-15#101",
"128.0000000000000000000000000008077935669463159990585083341",
"0x80.00000000000000000000003ffffffffffffe0000000000#190",
Nearest,
"-127.9999999999999999861222121929933371964607508331127668586",
"-0x7f.ffffffffffffff00000000400001ff7ffffe0008000000#190",
Equal,
);
// - rm == Nearest && xx == yy && sh <= 0 && cmp_low != -1 in sub_float_significands_general
// - cmp_low < 0 in sub_float_significands_general second time
test(
"2.220581574517834801066783605693002897371795957735742517101e-16",
"0x1.0003fffffe00000000007ffffffffffffffffffffff000feE-13#192",
"8.881784e-16",
"0x4.00000E-13#21",
Nearest,
"-6.661202622483417522322269739033559602628204042264257482898e-16",
"-0x2.fffc000001ffffffffff80000000000000000000000fff00E-13#192",
Greater,
);
// - diff_exp < Limb::WIDTH && yi < 0 in exponent_shift_compare
test(
"-1.8e-12",
"-0x1.fcE-10#7",
"-524288.0000000000017621525",
"-0x80000.0000000001f00078#81",
Nearest,
"524287.9999999999999573739",
"0x7ffff.fffffffffff40078#81",
Equal,
);
// - (yi >= 0 || lasty != 0) && high_dif == 0 && dif == 1 in exponent_shift_compare
// - xi >= 0 third time in exponent_shift_compare
// - yi >= 0 && diff_exp != 0 in exponent_shift_compare
// - high_dif != 0 in exponent_shift_compare
// - dif == 0 in exponent_shift_compare
test(
"3.99999999999999999957",
"0x3.fffffffffffffff80#67",
"4.0",
"0x4.00000000000000000#68",
Nearest,
"-4.33680868994201773603e-19",
"-0x8.0000000000000000E-16#68",
Equal,
);
// - xi < 0 third time in exponent_shift_compare
// - cancel1 >= xs_len in sub_float_significands_general
test(
"6.77626357803440271254657930615627554e-21",
"0x1.ffffffffffffffffffffc01fff800E-17#117",
"7.0e-21",
"0x2.0E-17#4",
Nearest,
"-6.99280860154738521672154778865541105e-46",
"-0x3.fe000800000000000000000000000E-38#117",
Equal,
);
// - yi >= 0 && diff_exp == 0 in exponent_shift_compare
// - dif != 0 in exponent_shift_compare
test(
"1.45519152351431153846750277125465800054371356958e-11",
"0x1.00000001ffffffffffffffffffffffffffffffcE-9#155",
"1.455191523514311538467502771254658000526607875496523229114700566610230516799191954282190\
364e-11",
"0x1.00000001fffffffffffffffffffffffc0000000000000000000000000000fffffffffff87f8E-9#301",
Nearest,
"1.710569408086637569000134230861426729009957349416545362986887684243433631257558931055548\
3967e-49",
"0x3.ffffffbfffffffffffffffffffff00000000000780800000000000000000000000000000000E-41#301",
Equal,
);
// - xs[xi] == 0 in exponent_shift_compare
// - xi < 0 second time in exponent_shift_compare
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000E-7#69",
Nearest,
"0.0",
"0x0.0",
Equal,
);
// - xi >= 0 second time in exponent_shift_compare
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000000000000000000000000000000000000E-7#200",
Nearest,
"0.0",
"0x0.0",
Equal,
);
// - rm != Nearest in sub_float_significands_general
// - rm != Nearest && carry == 0 in sub_float_significands_general
test(
"2.0", "0x2.0#1", "1.0", "0x1.0#2", Down, "1.0", "0x1.0#2", Equal,
);
// - rm != Nearest && carry != 0 in sub_float_significands_general
// - rm == Floor || rm == Down in sub_float_significands_general
test(
"0.5", "0x0.8#1", "3.0", "0x3.0#2", Down, "-2.0", "-0x2.0#2", Greater,
);
// - rm == Ceiling || rm == Up in sub_float_significands_general
// - (rm == Ceiling || rm == Up) && !carry in sub_float_significands_general
test(
"0.5", "0x0.8#1", "3.0", "0x3.0#2", Up, "-3.0", "-0x3.0#2", Less,
);
// - (rm == Ceiling || rm == Up) && carry in sub_float_significands_general
test(
"4.0", "0x4.0#1", "0.5", "0x0.8#2", Up, "4.0", "0x4.0#2", Greater,
);
// - cmp_low < 0 && (rm == Floor || rm == Down) in sub_float_significands_general
test(
"0.1952943266615587806218370459",
"0x0.31fecf1a1b1180be748fe5b8#91",
"5.04217616231508488430478600129900999076e-13",
"0x8.decb552f6cf9a70a64d0c0d7a367802E-11#127",
Down,
"0.195294326661054563005605537435615043117",
"0x0.31fecf1a1a8394092199161d8f59b2f38#127",
Less,
);
// - cmp_low < 0 && (rm == Ceiling || rm == Up) in sub_float_significands_general
test(
"1.1718977744e31",
"0x9.3ea0f304E+25#34",
"1910333504687680.9305",
"0x6c9702df30e40.ee38#64",
Ceiling,
"1.171897774363652748e31",
"0x9.3ea0f303ffff937E+25#64",
Greater,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#2", Floor, "-0.0", "-0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#2", Ceiling, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#2", Down, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#2", Up, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#2", Nearest, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#2", Exact, "0.0", "0x0.0", Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000E-7#69",
Floor,
"-0.0",
"-0x0.0",
Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000E-7#69",
Ceiling,
"0.0",
"0x0.0",
Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000E-7#69",
Down,
"0.0",
"0x0.0",
Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000E-7#69",
Up,
"0.0",
"0x0.0",
Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000E-7#69",
Nearest,
"0.0",
"0x0.0",
Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000E-7#69",
Exact,
"0.0",
"0x0.0",
Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000000000000000000000000000000000000E-7#200",
Floor,
"-0.0",
"-0x0.0",
Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000000000000000000000000000000000000E-7#200",
Ceiling,
"0.0",
"0x0.0",
Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000000000000000000000000000000000000E-7#200",
Down,
"0.0",
"0x0.0",
Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000000000000000000000000000000000000E-7#200",
Up,
"0.0",
"0x0.0",
Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000000000000000000000000000000000000E-7#200",
Nearest,
"0.0",
"0x0.0",
Equal,
);
test(
"7.0e-9",
"0x2.0E-7#2",
"7.450580596923828125e-9",
"0x2.00000000000000000000000000000000000000000000000000E-7#200",
Exact,
"0.0",
"0x0.0",
Equal,
);
}
#[test]
fn sub_round_fail() {
assert_panic!(Float::one_prec(1).sub_round(Float::from_unsigned_prec(4u8, 1).0, Exact));
assert_panic!({
Float::one_prec(1).sub_round_val_ref(&Float::from_unsigned_prec(4u8, 1).0, Exact)
});
assert_panic!(Float::one_prec(1).sub_round_ref_val(Float::from_unsigned_prec(4u8, 1).0, Exact));
assert_panic!({
Float::one_prec(1).sub_round_ref_ref(&Float::from_unsigned_prec(4u8, 1).0, Exact)
});
assert_panic!(parse_hex_string("0x1.0#1").sub_round(parse_hex_string("0x0.001#1"), Exact));
assert_panic!(
parse_hex_string("0x1.0#1").sub_round_val_ref(&parse_hex_string("0x0.001#1"), Exact)
);
assert_panic!(
parse_hex_string("0x1.0#1").sub_round_ref_val(parse_hex_string("0x0.001#1"), Exact)
);
assert_panic!(
parse_hex_string("0x1.0#1").sub_round_ref_ref(&parse_hex_string("0x0.001#1"), Exact)
);
assert_panic!(parse_hex_string("0x1.0000000000000000#64")
.sub_round(parse_hex_string("0x2.0000000000000002#64"), Exact));
assert_panic!(parse_hex_string("0x1.0000000000000000#64")
.sub_round_val_ref(&parse_hex_string("0x2.0000000000000002#64"), Exact));
assert_panic!(parse_hex_string("0x1.0000000000000000#64")
.sub_round_ref_val(parse_hex_string("0x2.0000000000000002#64"), Exact));
assert_panic!(parse_hex_string("0x1.0000000000000000#64")
.sub_round_ref_ref(&parse_hex_string("0x2.0000000000000002#64"), Exact));
assert_panic!(parse_hex_string("0x1.0000000000000000#65")
.sub_round(parse_hex_string("0x2.0000000000000001#65"), Exact));
assert_panic!(parse_hex_string("0x1.0000000000000000#65")
.sub_round_val_ref(&parse_hex_string("0x2.0000000000000001#65"), Exact));
assert_panic!(parse_hex_string("0x1.0000000000000000#65")
.sub_round_ref_val(parse_hex_string("0x2.0000000000000001#65"), Exact));
assert_panic!(parse_hex_string("0x1.0000000000000000#65")
.sub_round_ref_ref(&parse_hex_string("0x2.0000000000000001#65"), Exact));
assert_panic!(
parse_hex_string("0x1.00000000000000000000000000000000#128").sub_round(
parse_hex_string("0x2.00000000000000000000000000000002#128"),
Exact
)
);
assert_panic!(
parse_hex_string("0x1.00000000000000000000000000000000#128").sub_round_val_ref(
&parse_hex_string("0x2.00000000000000000000000000000002#128"),
Exact
)
);
assert_panic!(
parse_hex_string("0x1.00000000000000000000000000000000#128").sub_round_ref_val(
parse_hex_string("0x2.00000000000000000000000000000002#128"),
Exact
)
);
assert_panic!(
parse_hex_string("0x1.00000000000000000000000000000000#128").sub_round_ref_ref(
&parse_hex_string("0x2.00000000000000000000000000000002#128"),
Exact
)
);
assert_panic!(
parse_hex_string("0x1.00000000000000000000000000000000#129").sub_round(
parse_hex_string("0x2.00000000000000000000000000000003#129"),
Exact
)
);
assert_panic!(
parse_hex_string("0x1.00000000000000000000000000000000#129").sub_round_val_ref(
&parse_hex_string("0x2.00000000000000000000000000000003#129"),
Exact
)
);
assert_panic!(
parse_hex_string("0x1.00000000000000000000000000000000#129").sub_round_ref_val(
parse_hex_string("0x2.00000000000000000000000000000003#129"),
Exact
)
);
assert_panic!(
parse_hex_string("0x1.00000000000000000000000000000000#129").sub_round_ref_ref(
&parse_hex_string("0x2.00000000000000000000000000000003#129"),
Exact
)
);
assert_panic!(
parse_hex_string("0x1.000000000000000000000000000000000000000000000000#192").sub_round(
parse_hex_string("0x2.000000000000000000000000000000000000000000000002#192"),
Exact
)
);
assert_panic!(
parse_hex_string("0x1.000000000000000000000000000000000000000000000000#192")
.sub_round_val_ref(
&parse_hex_string("0x2.000000000000000000000000000000000000000000000002#192"),
Exact
)
);
assert_panic!(
parse_hex_string("0x1.000000000000000000000000000000000000000000000000#192")
.sub_round_ref_val(
parse_hex_string("0x2.000000000000000000000000000000000000000000000002#192"),
Exact
)
);
assert_panic!(
parse_hex_string("0x1.000000000000000000000000000000000000000000000000#192")
.sub_round_ref_ref(
&parse_hex_string("0x2.000000000000000000000000000000000000000000000002#192"),
Exact
)
);
assert_panic!(parse_hex_string("0x0.8#1").sub_round(parse_hex_string("0x3.0#2"), Exact));
assert_panic!(
parse_hex_string("0x0.8#1").sub_round_val_ref(&parse_hex_string("0x3.0#2"), Exact)
);
assert_panic!({
parse_hex_string("0x0.8#1").sub_round_ref_val(parse_hex_string("0x3.0#2"), Exact)
});
assert_panic!(
parse_hex_string("0x0.8#1").sub_round_ref_ref(&parse_hex_string("0x3.0#2"), Exact)
);
assert_panic!({
let mut x = Float::one_prec(1);
x.sub_round_assign(Float::from_unsigned_prec(4u8, 1).0, Exact)
});
assert_panic!({
let mut x = Float::one_prec(1);
x.sub_round_assign_ref(&Float::from_unsigned_prec(4u8, 1).0, Exact)
});
assert_panic!({
let mut x = parse_hex_string("0x1.0#1");
x.sub_round_assign(parse_hex_string("0x0.001#1"), Exact)
});
assert_panic!({
let mut x = parse_hex_string("0x1.0#1");
x.sub_round_assign_ref(&parse_hex_string("0x0.001#1"), Exact)
});
assert_panic!({
let mut x = parse_hex_string("0x1.0000000000000000#64");
x.sub_round_assign(parse_hex_string("0x2.0000000000000002#64"), Exact)
});
assert_panic!({
let mut x = parse_hex_string("0x1.0000000000000000#64");
x.sub_round_assign_ref(&parse_hex_string("0x2.0000000000000002#64"), Exact)
});
assert_panic!({
let mut x = parse_hex_string("0x1.0000000000000000#65");
x.sub_round_assign(parse_hex_string("0x2.0000000000000001#65"), Exact)
});
assert_panic!({
let mut x = parse_hex_string("0x1.0000000000000000#65");
x.sub_round_assign_ref(&parse_hex_string("0x2.0000000000000001#65"), Exact)
});
assert_panic!({
let mut x = parse_hex_string("0x1.00000000000000000000000000000000#128");
x.sub_round_assign(
parse_hex_string("0x2.00000000000000000000000000000002#128"),
Exact,
)
});
assert_panic!({
let mut x = parse_hex_string("0x1.00000000000000000000000000000000#128");
x.sub_round_assign_ref(
&parse_hex_string("0x2.00000000000000000000000000000002#128"),
Exact,
)
});
assert_panic!({
let mut x = parse_hex_string("0x1.00000000000000000000000000000000#129");
x.sub_round_assign(
parse_hex_string("0x2.00000000000000000000000000000003#129"),
Exact,
)
});
assert_panic!({
let mut x = parse_hex_string("0x1.00000000000000000000000000000000#129");
x.sub_round_assign_ref(
&parse_hex_string("0x2.00000000000000000000000000000003#129"),
Exact,
)
});
assert_panic!({
let mut x = parse_hex_string("0x1.000000000000000000000000000000000000000000000000#192");
x.sub_round_assign(
parse_hex_string("0x2.000000000000000000000000000000000000000000000002#192"),
Exact,
)
});
assert_panic!({
let mut x = parse_hex_string("0x1.000000000000000000000000000000000000000000000000#192");
x.sub_round_assign_ref(
&parse_hex_string("0x2.000000000000000000000000000000000000000000000002#192"),
Exact,
)
});
assert_panic!({
let mut x = parse_hex_string("0x0.8#1");
x.sub_round_assign(parse_hex_string("0x3.0#2"), Exact)
});
assert_panic!({
let mut x = parse_hex_string("0x0.8#1");
x.sub_round_assign_ref(&parse_hex_string("0x3.0#2"), Exact)
});
}
#[test]
fn test_sub_prec_round() {
let test = |s, s_hex, t, t_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 y = parse_hex_string(t_hex);
assert_eq!(y.to_string(), t);
let (diff, o) = x.clone().sub_prec_round(y.clone(), prec, rm);
assert!(diff.is_valid());
assert_eq!(diff.to_string(), out);
assert_eq!(to_hex_string(&diff), out_hex);
assert_eq!(o, o_out);
let (diff_alt, o_alt) = x.clone().sub_prec_round_val_ref(&y, prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let (diff_alt, o_alt) = x.sub_prec_round_ref_val(y.clone(), prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let (diff_alt, o_alt) = x.sub_prec_round_ref_ref(&y, prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_prec_round_assign(y.clone(), prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_prec_round_assign_ref(&y, prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o_out);
let (diff_alt, o_alt) = add_prec_round_naive(x.clone(), -&y, prec, rm);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_diff, rug_o) = rug_sub_prec_round(
&rug::Float::exact_from(&x),
&rug::Float::exact_from(&y),
prec,
rm,
);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff),
);
assert_eq!(rug_o, o);
}
};
test("NaN", "NaN", "NaN", "NaN", 1, Floor, "NaN", "NaN", Equal);
test("NaN", "NaN", "NaN", "NaN", 1, Ceiling, "NaN", "NaN", Equal);
test("NaN", "NaN", "NaN", "NaN", 1, Down, "NaN", "NaN", Equal);
test("NaN", "NaN", "NaN", "NaN", 1, Up, "NaN", "NaN", Equal);
test("NaN", "NaN", "NaN", "NaN", 1, Nearest, "NaN", "NaN", Equal);
test("NaN", "NaN", "NaN", "NaN", 1, Exact, "NaN", "NaN", Equal);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
1,
Floor,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
1,
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
1,
Down,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
1,
Up,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
1,
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-Infinity",
"-Infinity",
1,
Exact,
"NaN",
"NaN",
Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", 1, Floor, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", 1, Ceiling, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", 1, Down, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", 1, Up, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", 1, Nearest, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "Infinity", "Infinity", 1, Exact, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "-0.0", "-0x0.0", 1, Floor, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "-0.0", "-0x0.0", 1, Ceiling, "NaN", "NaN", Equal,
);
test("NaN", "NaN", "-0.0", "-0x0.0", 1, Down, "NaN", "NaN", Equal);
test("NaN", "NaN", "-0.0", "-0x0.0", 1, Up, "NaN", "NaN", Equal);
test(
"NaN", "NaN", "-0.0", "-0x0.0", 1, Nearest, "NaN", "NaN", Equal,
);
test(
"NaN", "NaN", "-0.0", "-0x0.0", 1, Exact, "NaN", "NaN", Equal,
);
test("NaN", "NaN", "0.0", "0x0.0", 1, Floor, "NaN", "NaN", Equal);
test(
"NaN", "NaN", "0.0", "0x0.0", 1, Ceiling, "NaN", "NaN", Equal,
);
test("NaN", "NaN", "0.0", "0x0.0", 1, Down, "NaN", "NaN", Equal);
test("NaN", "NaN", "0.0", "0x0.0", 1, Up, "NaN", "NaN", Equal);
test(
"NaN", "NaN", "0.0", "0x0.0", 1, Nearest, "NaN", "NaN", Equal,
);
test("NaN", "NaN", "0.0", "0x0.0", 1, Exact, "NaN", "NaN", Equal);
test(
"Infinity", "Infinity", "NaN", "NaN", 1, Floor, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "NaN", "NaN", 1, Ceiling, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "NaN", "NaN", 1, Down, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "NaN", "NaN", 1, Up, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "NaN", "NaN", 1, Nearest, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "NaN", "NaN", 1, Exact, "NaN", "NaN", Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
1,
Floor,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
1,
Ceiling,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
1,
Down,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
1,
Up,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
1,
Nearest,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-Infinity",
"-Infinity",
1,
Exact,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", 1, Floor, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", 1, Ceiling, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", 1, Down, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", 1, Up, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", 1, Nearest, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "Infinity", "Infinity", 1, Exact, "NaN", "NaN", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", 1, Floor, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", 1, Ceiling, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", 1, Down, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", 1, Up, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", 1, Nearest, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-0.0", "-0x0.0", 1, Exact, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", 1, Floor, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", 1, Ceiling, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", 1, Down, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", 1, Up, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", 1, Nearest, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "0.0", "0x0.0", 1, Exact, "Infinity", "Infinity", Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
1,
Floor,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
1,
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
1,
Down,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
1,
Up,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
1,
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"NaN",
"NaN",
1,
Exact,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
1,
Floor,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
1,
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
1,
Down,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
1,
Up,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
1,
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-Infinity",
"-Infinity",
1,
Exact,
"NaN",
"NaN",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
1,
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
1,
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
1,
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
1,
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
1,
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"Infinity",
"Infinity",
1,
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
1,
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
1,
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
1,
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
1,
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
1,
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-0.0",
"-0x0.0",
1,
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
1,
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
1,
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
1,
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
1,
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
1,
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"0.0",
"0x0.0",
1,
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test("0.0", "0x0.0", "NaN", "NaN", 1, Floor, "NaN", "NaN", Equal);
test(
"0.0", "0x0.0", "NaN", "NaN", 1, Ceiling, "NaN", "NaN", Equal,
);
test("0.0", "0x0.0", "NaN", "NaN", 1, Down, "NaN", "NaN", Equal);
test("0.0", "0x0.0", "NaN", "NaN", 1, Up, "NaN", "NaN", Equal);
test(
"0.0", "0x0.0", "NaN", "NaN", 1, Nearest, "NaN", "NaN", Equal,
);
test("0.0", "0x0.0", "NaN", "NaN", 1, Exact, "NaN", "NaN", Equal);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
1,
Floor,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
1,
Ceiling,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
1,
Down,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
1,
Up,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
1,
Nearest,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-Infinity",
"-Infinity",
1,
Exact,
"Infinity",
"Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
1,
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
1,
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
1,
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
1,
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
1,
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"Infinity",
"Infinity",
1,
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0", "0x0.0", "-0.0", "-0x0.0", 1, Floor, "0.0", "0x0.0", Equal,
);
test(
"0.0", "0x0.0", "-0.0", "-0x0.0", 1, Ceiling, "0.0", "0x0.0", Equal,
);
test(
"0.0", "0x0.0", "-0.0", "-0x0.0", 1, Down, "0.0", "0x0.0", Equal,
);
test(
"0.0", "0x0.0", "-0.0", "-0x0.0", 1, Up, "0.0", "0x0.0", Equal,
);
test(
"0.0", "0x0.0", "-0.0", "-0x0.0", 1, Nearest, "0.0", "0x0.0", Equal,
);
test(
"0.0", "0x0.0", "-0.0", "-0x0.0", 1, Exact, "0.0", "0x0.0", Equal,
);
// Note different behavior for Floor
test(
"0.0", "0x0.0", "0.0", "0x0.0", 1, Floor, "-0.0", "-0x0.0", Equal,
);
test(
"0.0", "0x0.0", "0.0", "0x0.0", 1, Ceiling, "0.0", "0x0.0", Equal,
);
test(
"0.0", "0x0.0", "0.0", "0x0.0", 1, Down, "0.0", "0x0.0", Equal,
);
test("0.0", "0x0.0", "0.0", "0x0.0", 1, Up, "0.0", "0x0.0", Equal);
test(
"0.0", "0x0.0", "0.0", "0x0.0", 1, Nearest, "0.0", "0x0.0", Equal,
);
test(
"0.0", "0x0.0", "0.0", "0x0.0", 1, Exact, "0.0", "0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "NaN", "NaN", 1, Floor, "NaN", "NaN", Equal,
);
test(
"-0.0", "-0x0.0", "NaN", "NaN", 1, Ceiling, "NaN", "NaN", Equal,
);
test("-0.0", "-0x0.0", "NaN", "NaN", 1, Down, "NaN", "NaN", Equal);
test("-0.0", "-0x0.0", "NaN", "NaN", 1, Up, "NaN", "NaN", Equal);
test(
"-0.0", "-0x0.0", "NaN", "NaN", 1, Nearest, "NaN", "NaN", Equal,
);
test(
"-0.0", "-0x0.0", "NaN", "NaN", 1, Exact, "NaN", "NaN", Equal,
);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
1,
Floor,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
1,
Ceiling,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
1,
Down,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
1,
Up,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
1,
Nearest,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"-Infinity",
"-Infinity",
1,
Exact,
"Infinity",
"Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
1,
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
1,
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
1,
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
1,
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
1,
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-0.0",
"-0x0.0",
"Infinity",
"Infinity",
1,
Exact,
"-Infinity",
"-Infinity",
Equal,
);
// Note different behavior for Floor
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", 1, Floor, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", 1, Ceiling, "0.0", "0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", 1, Down, "0.0", "0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", 1, Up, "0.0", "0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", 1, Nearest, "0.0", "0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "-0.0", "-0x0.0", 1, Exact, "0.0", "0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", 1, Floor, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", 1, Ceiling, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", 1, Down, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", 1, Up, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", 1, Nearest, "-0.0", "-0x0.0", Equal,
);
test(
"-0.0", "-0x0.0", "0.0", "0x0.0", 1, Exact, "-0.0", "-0x0.0", Equal,
);
test(
"123.0", "0x7b.0#7", "NaN", "NaN", 1, Floor, "NaN", "NaN", Equal,
);
test(
"123.0", "0x7b.0#7", "NaN", "NaN", 1, Ceiling, "NaN", "NaN", Equal,
);
test(
"123.0", "0x7b.0#7", "NaN", "NaN", 1, Down, "NaN", "NaN", Equal,
);
test(
"123.0", "0x7b.0#7", "NaN", "NaN", 1, Up, "NaN", "NaN", Equal,
);
test(
"123.0", "0x7b.0#7", "NaN", "NaN", 1, Nearest, "NaN", "NaN", Equal,
);
test(
"123.0", "0x7b.0#7", "NaN", "NaN", 1, Exact, "NaN", "NaN", Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
1,
Floor,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
1,
Ceiling,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
1,
Down,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
1,
Up,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
1,
Nearest,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-Infinity",
"-Infinity",
1,
Exact,
"Infinity",
"Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
1,
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
1,
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
1,
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
1,
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
1,
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"Infinity",
"Infinity",
1,
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test(
"123.0",
"0x7b.0#7",
"-0.0",
"-0x0.0",
1,
Floor,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"123.0",
"0x7b.0#7",
"-0.0",
"-0x0.0",
1,
Ceiling,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"123.0",
"0x7b.0#7",
"-0.0",
"-0x0.0",
1,
Down,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"123.0",
"0x7b.0#7",
"-0.0",
"-0x0.0",
1,
Up,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"123.0",
"0x7b.0#7",
"-0.0",
"-0x0.0",
1,
Nearest,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"123.0",
"0x7b.0#7",
"0.0",
"0x0.0",
1,
Floor,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"123.0",
"0x7b.0#7",
"0.0",
"0x0.0",
1,
Ceiling,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"123.0",
"0x7b.0#7",
"0.0",
"0x0.0",
1,
Down,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"123.0",
"0x7b.0#7",
"0.0",
"0x0.0",
1,
Up,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"123.0",
"0x7b.0#7",
"0.0",
"0x0.0",
1,
Nearest,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"NaN",
"NaN",
"-123.0",
"-0x7b.0#7",
1,
Floor,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-123.0",
"-0x7b.0#7",
1,
Ceiling,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-123.0",
"-0x7b.0#7",
1,
Down,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-123.0",
"-0x7b.0#7",
1,
Up,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-123.0",
"-0x7b.0#7",
1,
Nearest,
"NaN",
"NaN",
Equal,
);
test(
"NaN",
"NaN",
"-123.0",
"-0x7b.0#7",
1,
Exact,
"NaN",
"NaN",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
1,
Floor,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
1,
Ceiling,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
1,
Down,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
1,
Up,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
1,
Nearest,
"Infinity",
"Infinity",
Equal,
);
test(
"Infinity",
"Infinity",
"-123.0",
"-0x7b.0#7",
1,
Exact,
"Infinity",
"Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
1,
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
1,
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
1,
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
1,
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
1,
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123.0",
"-0x7b.0#7",
1,
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
1,
Floor,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
1,
Ceiling,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
1,
Down,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
1,
Up,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"0.0",
"0x0.0",
"-123.0",
"-0x7b.0#7",
1,
Nearest,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
1,
Floor,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
1,
Ceiling,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
1,
Down,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
1,
Up,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"-0.0",
"-0x0.0",
"-123.0",
"-0x7b.0#7",
1,
Nearest,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", 1, Floor, "2.0", "0x2.0#1", Less,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", 1, Ceiling, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", 1, Down, "2.0", "0x2.0#1", Less,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", 1, Up, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#1", 1, Nearest, "4.0", "0x4.0#1", Greater,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#1",
10,
Floor,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#1",
10,
Ceiling,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#1",
10,
Down,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#1",
10,
Up,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#1",
10,
Nearest,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#1",
10,
Exact,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", 1, Floor, "2.0", "0x2.0#1", Less,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", 1, Ceiling, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", 1, Down, "2.0", "0x2.0#1", Less,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", 1, Up, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#1", "-2.0", "-0x2.0#2", 1, Nearest, "4.0", "0x4.0#1", Greater,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#2",
10,
Floor,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#2",
10,
Ceiling,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#2",
10,
Down,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#2",
10,
Up,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#2",
10,
Nearest,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-2.0",
"-0x2.0#2",
10,
Exact,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", 1, Floor, "2.0", "0x2.0#1", Less,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", 1, Ceiling, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", 1, Down, "2.0", "0x2.0#1", Less,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", 1, Up, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#1", 1, Nearest, "4.0", "0x4.0#1", Greater,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#1",
10,
Floor,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#1",
10,
Ceiling,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#1",
10,
Down,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#1",
10,
Up,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#1",
10,
Nearest,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#1",
10,
Exact,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", 1, Floor, "2.0", "0x2.0#1", Less,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", 1, Ceiling, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", 1, Down, "2.0", "0x2.0#1", Less,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", 1, Up, "4.0", "0x4.0#1", Greater,
);
test(
"1.0", "0x1.0#2", "-2.0", "-0x2.0#2", 1, Nearest, "4.0", "0x4.0#1", Greater,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#2",
10,
Floor,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#2",
10,
Ceiling,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#2",
10,
Down,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#2",
10,
Up,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#2",
10,
Nearest,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.0#2",
"-2.0",
"-0x2.0#2",
10,
Exact,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
1,
Floor,
"2.0",
"0x2.0#1",
Less,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
1,
Ceiling,
"4.0",
"0x4.0#1",
Greater,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
1,
Down,
"2.0",
"0x2.0#1",
Less,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
1,
Up,
"4.0",
"0x4.0#1",
Greater,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
1,
Nearest,
"4.0",
"0x4.0#1",
Greater,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
10,
Floor,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
10,
Ceiling,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
10,
Down,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
10,
Up,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
10,
Nearest,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.0",
"0x1.000#10",
"-2.0",
"-0x2.00#10",
10,
Exact,
"3.0",
"0x3.00#10",
Equal,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Floor,
"4.555",
"0x4.8e#10",
Less,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Ceiling,
"4.56",
"0x4.90#10",
Greater,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Down,
"4.555",
"0x4.8e#10",
Less,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Up,
"4.56",
"0x4.90#10",
Greater,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Nearest,
"4.555",
"0x4.8e#10",
Less,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Floor,
"-1.729",
"-0x1.ba8#10",
Less,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Ceiling,
"-1.727",
"-0x1.ba0#10",
Greater,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Down,
"-1.727",
"-0x1.ba0#10",
Greater,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Up,
"-1.729",
"-0x1.ba8#10",
Less,
);
test(
"1.4142135623730951",
"0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Nearest,
"-1.727",
"-0x1.ba0#10",
Greater,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Floor,
"1.727",
"0x1.ba0#10",
Less,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Ceiling,
"1.729",
"0x1.ba8#10",
Greater,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Down,
"1.727",
"0x1.ba0#10",
Less,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Up,
"1.729",
"0x1.ba8#10",
Greater,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
10,
Nearest,
"1.727",
"0x1.ba0#10",
Less,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Floor,
"-4.56",
"-0x4.90#10",
Less,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Ceiling,
"-4.555",
"-0x4.8e#10",
Greater,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Down,
"-4.555",
"-0x4.8e#10",
Greater,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Up,
"-4.56",
"-0x4.90#10",
Less,
);
test(
"-1.4142135623730951",
"-0x1.6a09e667f3bcd#53",
"3.1415926535897931",
"0x3.243f6a8885a30#53",
10,
Nearest,
"-4.555",
"-0x4.8e#10",
Greater,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
1,
Floor,
"1.0",
"0x1.0#1",
Less,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
1,
Ceiling,
"2.0",
"0x2.0#1",
Greater,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
1,
Down,
"1.0",
"0x1.0#1",
Less,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
1,
Up,
"2.0",
"0x2.0#1",
Greater,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
1,
Nearest,
"1.0",
"0x1.0#1",
Less,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
20,
Floor,
"1.000244",
"0x1.00100#20",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
20,
Ceiling,
"1.000244",
"0x1.00100#20",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
20,
Down,
"1.000244",
"0x1.00100#20",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
20,
Up,
"1.000244",
"0x1.00100#20",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
20,
Nearest,
"1.000244",
"0x1.00100#20",
Equal,
);
test(
"1.0",
"0x1.0#1",
"-0.0002",
"-0x0.001#1",
20,
Exact,
"1.000244",
"0x1.00100#20",
Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", 10, Floor, "-0.0", "-0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", 10, Ceiling, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", 10, Down, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", 10, Up, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", 10, Nearest, "0.0", "0x0.0", Equal,
);
test(
"1.0", "0x1.0#1", "1.0", "0x1.0#1", 10, Exact, "0.0", "0x0.0", Equal,
);
// - rm != Nearest in round_helper
// - (rm == Up || rm == Ceiling) && sb | rb != 0 in round_helper
// - !increment third time in round_helper
test(
"13104.5238818416080254535",
"0x3330.861d1ed0acba8a3a#77",
"2.854e-35",
"0x2.5fE-29#10",
17,
Ceiling,
"13104.6",
"0x3330.a#17",
Greater,
);
// - sh != 0 && (rm != Nearest && rb != 0) in round_helper
// - rm == Down || rm == Floor in round_helper
test(
"2.8979948183270175762296398212780973e-12",
"0x3.2fb688bd98f0271a53708f0554568E-10#115",
"8.270488650862e23",
"0xa.f2268a8074E+19#42",
2,
Down,
"-6.0e23",
"-0x8.0E+19#2",
Greater,
);
// - (rm == Up || rm == Ceiling) && sb | rb == 0 in round_helper
test(
"1.503764257662314e22",
"0x3.2f31367a9800E+18#48",
"7.3839e-20",
"0x1.5cb2E-16#17",
39,
Ceiling,
"1.503764257662e22",
"0x3.2f31367a98E+18#39",
Greater,
);
// - increment third time in round_helper
test(
"4.70916604581e-30",
"0x5.f8363584bE-25#39",
"341290809831481093.63402342431195212374059",
"0x4bc822eed1c5f05.a24f5bf051591756f951#139",
1,
Floor,
"-6.0e17",
"-0x8.0E+14#1",
Less,
);
// - cmp_low > 0 && (rm == Floor || rm == Down) in sub_float_significands_general
test(
"559935046210054011882951826578284118061013900.5853448",
"0x191bbd3588c78488c2f4d122814d5fb34edb8c.95d928#170",
"3.027932e11",
"0x4.67fe2E+9#22",
63,
Down,
"5.599350462100540119e44",
"0x1.91bbd3588c78488cE+37#63",
Less,
);
// - cmp_low > 0 && (rm == Ceiling || rm == Up) in sub_float_significands_general
// - cmp_low > 0 && (rm == Ceiling || rm == Up) && !carry in sub_float_significands_general
test(
"1.3111820218254081035114504135472568116036464005e-6",
"0x0.000015ff7be10e865ada82cd25acef5baa9c89c25f4#152",
"2.51465891601e-20",
"0x7.6c05c64a8E-17#38",
128,
Ceiling,
"1.311182021825382956922290308381837960614e-6",
"0x0.000015ff7be10e85e41a26687dacef5baa9ca#128",
Greater,
);
// - cmp_low > 0 && (rm == Ceiling || rm == Up) && carry in sub_float_significands_general
test(
"1.19e-7",
"0x2.0E-6#6",
"2722258925226302905881161717745111269376.0000001187",
"0x7ffffff800000000000003fe7c0000000.000001fe0#164",
28,
Up,
"-2.72225894e39",
"-0x8.000000E+32#28",
Less,
);
}
#[test]
fn sub_prec_round_fail() {
assert_panic!(Float::one_prec(1).sub_prec_round(Float::two_prec(1), 0, Floor));
assert_panic!(Float::one_prec(1).sub_prec_round_val_ref(&Float::two_prec(1), 0, Floor));
assert_panic!(Float::one_prec(1).sub_prec_round_ref_val(Float::two_prec(1), 0, Floor));
assert_panic!(Float::one_prec(1).sub_prec_round_ref_ref(&Float::two_prec(1), 0, Floor));
assert_panic!({
let mut x = Float::one_prec(1);
x.sub_prec_round_assign(Float::two_prec(1), 0, Floor)
});
assert_panic!({
let mut x = Float::one_prec(1);
x.sub_prec_round_assign_ref(&Float::two_prec(1), 0, Floor)
});
assert_panic!(Float::one_prec(1).sub_prec_round(-Float::two_prec(1), 1, Exact));
assert_panic!(Float::one_prec(1).sub_prec_round_val_ref(&-Float::two_prec(1), 1, Exact));
assert_panic!(Float::one_prec(1).sub_prec_round_ref_val(-Float::two_prec(1), 1, Exact));
assert_panic!(Float::one_prec(1).sub_prec_round_ref_ref(&-Float::two_prec(1), 1, Exact));
assert_panic!({
let mut x = Float::one_prec(1);
x.sub_prec_round_assign(-Float::two_prec(1), 1, Exact)
});
assert_panic!({
let mut x = Float::one_prec(1);
x.sub_prec_round_assign_ref(&-Float::two_prec(1), 1, Exact)
});
}
#[test]
fn test_sub_rational() {
let test = |s, s_hex, t, out: &str, out_hex: &str| {
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let y = Rational::from_str(t).unwrap();
let diff = x.clone() - y.clone();
assert!(diff.is_valid());
assert_eq!(diff.to_string(), out);
assert_eq!(to_hex_string(&diff), out_hex);
let diff_alt = x.clone() - &y;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
let diff_alt = &x - y.clone();
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
let diff_alt = &x - &y;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
let diff_alt = y.clone() - x.clone();
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloat(-&diff), ComparableFloat(diff_alt));
let diff_alt = y.clone() - &x;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloat(-&diff), ComparableFloat(diff_alt));
let diff_alt = &y - x.clone();
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloat(-&diff), ComparableFloat(diff_alt));
let diff_alt = &y - &x;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloat(-&diff), ComparableFloat(diff_alt));
let mut diff_alt = x.clone();
diff_alt -= y.clone();
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
let mut diff_alt = x.clone();
diff_alt -= &y;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(
ComparableFloatRef(&Float::from(&rug_sub_rational(
&rug::Float::exact_from(&x),
&rug::Rational::from(&y)
))),
ComparableFloatRef(&diff)
);
let diff_alt =
add_rational_prec_round_naive(x.clone(), -&y, x.significant_bits(), Nearest).0;
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
};
test("NaN", "NaN", "-123", "NaN", "NaN");
test("Infinity", "Infinity", "-123", "Infinity", "Infinity");
test("-Infinity", "-Infinity", "-123", "-Infinity", "-Infinity");
test("0.0", "0x0.0", "0", "0.0", "0x0.0");
test("-0.0", "-0x0.0", "0", "-0.0", "-0x0.0");
test("0.0", "0x0.0", "-123", "1.0e2", "0x8.0E+1#1");
test("-0.0", "-0x0.0", "-123", "1.0e2", "0x8.0E+1#1");
test("0.0", "0x0.0", "-1/3", "0.2", "0x0.4#1");
test("-0.0", "-0x0.0", "-1/3", "0.2", "0x0.4#1");
test("123.0", "0x7b.0#7", "0", "123.0", "0x7b.0#7");
test("1.0", "0x1.0#1", "-2", "4.0", "0x4.0#1");
test("1.0", "0x1.0#2", "-2", "3.0", "0x3.0#2");
test("1.0", "0x1.000#10", "-2", "3.0", "0x3.00#10");
test("1.0", "0x1.000#10", "-1/3", "1.334", "0x1.558#10");
test(
"1.0",
"0x1.0000000000000000000000000#100",
"-1/3",
"1.333333333333333333333333333334",
"0x1.5555555555555555555555556#100",
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
"3.4749259869231266",
"0x3.7994bfdddaf86#53",
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
"2.8082593202564596",
"0x2.ceea1533304da#53",
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
"-2.8082593202564596",
"-0x2.ceea1533304da#53",
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
"-3.4749259869231266",
"-0x3.7994bfdddaf86#53",
);
test("1.0", "0x1.0#1", "-1/50000", "1.0", "0x1.0#1");
test("1.0", "0x1.0#1", "1", "0.0", "0x0.0");
}
#[test]
fn test_sub_rational_prec() {
let test = |s, s_hex, t, prec, out: &str, out_hex: &str, o_out| {
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let y = Rational::from_str(t).unwrap();
let (diff, o) = x.clone().sub_rational_prec(y.clone(), prec);
assert!(diff.is_valid());
assert_eq!(o, o_out);
assert_eq!(diff.to_string(), out);
assert_eq!(to_hex_string(&diff), out_hex);
let (diff_alt, o_alt) = x.clone().sub_rational_prec_val_ref(&y, prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_rational_prec_ref_val(y.clone(), prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_rational_prec_ref_ref(&y, prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_rational_prec_assign(y.clone(), prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_rational_prec_assign_ref(&y, prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = add_rational_prec_round_naive(x.clone(), -&y, prec, Nearest);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (rug_diff, rug_o) = rug_sub_rational_prec(
&rug::Float::exact_from(&x),
&rug::Rational::exact_from(&y),
prec,
);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff)
);
assert_eq!(rug_o, o);
};
test("NaN", "NaN", "-123", 1, "NaN", "NaN", Equal);
test(
"Infinity", "Infinity", "-123", 1, "Infinity", "Infinity", Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
1,
"-Infinity",
"-Infinity",
Equal,
);
test("0.0", "0x0.0", "0", 1, "0.0", "0x0.0", Equal);
test("-0.0", "-0x0.0", "0", 1, "-0.0", "-0x0.0", Equal);
test("0.0", "0x0.0", "-123", 1, "1.0e2", "0x8.0E+1#1", Greater);
test("-0.0", "-0x0.0", "-123", 1, "1.0e2", "0x8.0E+1#1", Greater);
test("0.0", "0x0.0", "-1/3", 1, "0.2", "0x0.4#1", Less);
test("-0.0", "-0x0.0", "-1/3", 1, "0.2", "0x0.4#1", Less);
test("123.0", "0x7b.0#7", "0", 1, "1.0e2", "0x8.0E+1#1", Greater);
test("1.0", "0x1.0#1", "-2", 1, "4.0", "0x4.0#1", Greater);
test("1.0", "0x1.0#1", "-2", 2, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.0#2", "-2", 1, "4.0", "0x4.0#1", Greater);
test("1.0", "0x1.0#2", "-2", 2, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.000#10", "-2", 1, "4.0", "0x4.0#1", Greater);
test("1.0", "0x1.000#10", "-2", 2, "3.0", "0x3.0#2", Equal);
test(
"1.0",
"0x1.000#10",
"-1/3",
100,
"1.333333333333333333333333333334",
"0x1.5555555555555555555555556#100",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
10,
"3.477",
"0x3.7a#10",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
10,
"2.809",
"0x2.cf#10",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
10,
"-2.809",
"-0x2.cf#10",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
10,
"-3.477",
"-0x3.7a#10",
Less,
);
test("1.0", "0x1.0#1", "-1/50000", 10, "1.0", "0x1.000#10", Less);
test("1.0", "0x1.0#1", "1", 10, "0.0", "0x0.0", Equal);
}
#[test]
fn sub_rational_prec_fail() {
assert_panic!(Float::NAN.sub_rational_prec(Rational::ZERO, 0));
assert_panic!(Float::NAN.sub_rational_prec_val_ref(&Rational::ZERO, 0));
assert_panic!(Float::NAN.sub_rational_prec_ref_val(Rational::ZERO, 0));
assert_panic!(Float::NAN.sub_rational_prec_ref_ref(&Rational::ZERO, 0));
assert_panic!({
let mut x = Float::NAN;
x.sub_rational_prec_assign(Rational::ZERO, 0)
});
assert_panic!({
let mut x = Float::NAN;
x.sub_rational_prec_assign_ref(&Rational::ZERO, 0)
});
}
#[test]
fn test_sub_rational_round() {
let test = |s, s_hex, t, rm, out: &str, out_hex: &str, o_out| {
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let y = Rational::from_str(t).unwrap();
let (diff, o) = x.clone().sub_rational_round(y.clone(), rm);
assert!(diff.is_valid());
assert_eq!(o, o_out);
assert_eq!(diff.to_string(), out);
assert_eq!(to_hex_string(&diff), out_hex);
let (diff_alt, o_alt) = x.clone().sub_rational_round_val_ref(&y, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_rational_round_ref_val(y.clone(), rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_rational_round_ref_ref(&y, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_rational_round_assign(y.clone(), rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_rational_round_assign_ref(&y, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_diff, rug_o) = rug_sub_rational_round(
&rug::Float::exact_from(&x),
&rug::Rational::exact_from(&y),
rm,
);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff)
);
assert_eq!(rug_o, o);
}
let (diff_alt, o_alt) =
add_rational_prec_round_naive(x.clone(), -&y, x.significant_bits(), rm);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
};
test("NaN", "NaN", "-123", Floor, "NaN", "NaN", Equal);
test("NaN", "NaN", "-123", Ceiling, "NaN", "NaN", Equal);
test("NaN", "NaN", "-123", Down, "NaN", "NaN", Equal);
test("NaN", "NaN", "-123", Up, "NaN", "NaN", Equal);
test("NaN", "NaN", "-123", Nearest, "NaN", "NaN", Equal);
test("NaN", "NaN", "-123", Exact, "NaN", "NaN", Equal);
test(
"Infinity", "Infinity", "-123", Floor, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-123", Ceiling, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-123", Down, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-123", Up, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-123", Nearest, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-123", Exact, "Infinity", "Infinity", Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test("0.0", "0x0.0", "0", Floor, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0", Ceiling, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0", Down, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0", Up, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0", Nearest, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0", Exact, "0.0", "0x0.0", Equal);
test("-0.0", "-0x0.0", "0", Floor, "-0.0", "-0x0.0", Equal);
test("-0.0", "-0x0.0", "0", Ceiling, "-0.0", "-0x0.0", Equal);
test("-0.0", "-0x0.0", "0", Down, "-0.0", "-0x0.0", Equal);
test("-0.0", "-0x0.0", "0", Up, "-0.0", "-0x0.0", Equal);
test("-0.0", "-0x0.0", "0", Nearest, "-0.0", "-0x0.0", Equal);
test("-0.0", "-0x0.0", "0", Exact, "-0.0", "-0x0.0", Equal);
test("0.0", "0x0.0", "-123", Floor, "6.0e1", "0x4.0E+1#1", Less);
test(
"0.0",
"0x0.0",
"-123",
Ceiling,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test("0.0", "0x0.0", "-123", Down, "6.0e1", "0x4.0E+1#1", Less);
test("0.0", "0x0.0", "-123", Up, "1.0e2", "0x8.0E+1#1", Greater);
test(
"0.0",
"0x0.0",
"-123",
Nearest,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test("-0.0", "-0x0.0", "-123", Floor, "6.0e1", "0x4.0E+1#1", Less);
test(
"-0.0",
"-0x0.0",
"-123",
Ceiling,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test("-0.0", "-0x0.0", "-123", Down, "6.0e1", "0x4.0E+1#1", Less);
test("-0.0", "-0x0.0", "-123", Up, "1.0e2", "0x8.0E+1#1", Greater);
test(
"-0.0",
"-0x0.0",
"-123",
Nearest,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test("123.0", "0x7b.0#7", "0", Floor, "123.0", "0x7b.0#7", Equal);
test(
"123.0", "0x7b.0#7", "0", Ceiling, "123.0", "0x7b.0#7", Equal,
);
test("123.0", "0x7b.0#7", "0", Down, "123.0", "0x7b.0#7", Equal);
test("123.0", "0x7b.0#7", "0", Up, "123.0", "0x7b.0#7", Equal);
test(
"123.0", "0x7b.0#7", "0", Nearest, "123.0", "0x7b.0#7", Equal,
);
test("123.0", "0x7b.0#7", "0", Exact, "123.0", "0x7b.0#7", Equal);
test("0.0", "0x0.0", "-1/3", Floor, "0.2", "0x0.4#1", Less);
test("0.0", "0x0.0", "-1/3", Ceiling, "0.5", "0x0.8#1", Greater);
test("0.0", "0x0.0", "-1/3", Down, "0.2", "0x0.4#1", Less);
test("0.0", "0x0.0", "-1/3", Up, "0.5", "0x0.8#1", Greater);
test("0.0", "0x0.0", "-1/3", Nearest, "0.2", "0x0.4#1", Less);
test("-0.0", "-0x0.0", "-1/3", Floor, "0.2", "0x0.4#1", Less);
test("-0.0", "-0x0.0", "-1/3", Ceiling, "0.5", "0x0.8#1", Greater);
test("-0.0", "-0x0.0", "-1/3", Down, "0.2", "0x0.4#1", Less);
test("-0.0", "-0x0.0", "-1/3", Up, "0.5", "0x0.8#1", Greater);
test("-0.0", "-0x0.0", "-1/3", Nearest, "0.2", "0x0.4#1", Less);
test("1.0", "0x1.0#1", "-2", Floor, "2.0", "0x2.0#1", Less);
test("1.0", "0x1.0#1", "-2", Ceiling, "4.0", "0x4.0#1", Greater);
test("1.0", "0x1.0#1", "-2", Down, "2.0", "0x2.0#1", Less);
test("1.0", "0x1.0#1", "-2", Up, "4.0", "0x4.0#1", Greater);
test("1.0", "0x1.0#1", "-2", Nearest, "4.0", "0x4.0#1", Greater);
test("1.0", "0x1.0#2", "-2", Floor, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.0#2", "-2", Ceiling, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.0#2", "-2", Down, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.0#2", "-2", Up, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.0#2", "-2", Nearest, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.0#2", "-2", Exact, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.000#10", "-2", Floor, "3.0", "0x3.00#10", Equal);
test(
"1.0",
"0x1.000#10",
"-2",
Ceiling,
"3.0",
"0x3.00#10",
Equal,
);
test("1.0", "0x1.000#10", "-2", Down, "3.0", "0x3.00#10", Equal);
test("1.0", "0x1.000#10", "-2", Up, "3.0", "0x3.00#10", Equal);
test(
"1.0",
"0x1.000#10",
"-2",
Nearest,
"3.0",
"0x3.00#10",
Equal,
);
test("1.0", "0x1.000#10", "-2", Exact, "3.0", "0x3.00#10", Equal);
test(
"1.0",
"0x1.000#10",
"-1/3",
Floor,
"1.332",
"0x1.550#10",
Less,
);
test(
"1.0",
"0x1.000#10",
"-1/3",
Ceiling,
"1.334",
"0x1.558#10",
Greater,
);
test(
"1.0",
"0x1.000#10",
"-1/3",
Down,
"1.332",
"0x1.550#10",
Less,
);
test(
"1.0",
"0x1.000#10",
"-1/3",
Up,
"1.334",
"0x1.558#10",
Greater,
);
test(
"1.0",
"0x1.000#10",
"-1/3",
Nearest,
"1.334",
"0x1.558#10",
Greater,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
"-1/3",
Floor,
"1.333333333333333333333333333332",
"0x1.5555555555555555555555554#100",
Less,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
"-1/3",
Ceiling,
"1.333333333333333333333333333334",
"0x1.5555555555555555555555556#100",
Greater,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
"-1/3",
Down,
"1.333333333333333333333333333332",
"0x1.5555555555555555555555554#100",
Less,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
"-1/3",
Up,
"1.333333333333333333333333333334",
"0x1.5555555555555555555555556#100",
Greater,
);
test(
"1.0",
"0x1.0000000000000000000000000#100",
"-1/3",
Nearest,
"1.333333333333333333333333333334",
"0x1.5555555555555555555555556#100",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
Floor,
"3.4749259869231262",
"0x3.7994bfdddaf84#53",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
Ceiling,
"3.4749259869231266",
"0x3.7994bfdddaf86#53",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
Down,
"3.4749259869231262",
"0x3.7994bfdddaf84#53",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
Up,
"3.4749259869231266",
"0x3.7994bfdddaf86#53",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
Nearest,
"3.4749259869231266",
"0x3.7994bfdddaf86#53",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
Floor,
"2.8082593202564596",
"0x2.ceea1533304da#53",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
Ceiling,
"2.8082593202564601",
"0x2.ceea1533304dc#53",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
Down,
"2.8082593202564596",
"0x2.ceea1533304da#53",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
Up,
"2.8082593202564601",
"0x2.ceea1533304dc#53",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
Nearest,
"2.8082593202564596",
"0x2.ceea1533304da#53",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
Floor,
"-2.8082593202564601",
"-0x2.ceea1533304dc#53",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
Ceiling,
"-2.8082593202564596",
"-0x2.ceea1533304da#53",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
Down,
"-2.8082593202564596",
"-0x2.ceea1533304da#53",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
Up,
"-2.8082593202564601",
"-0x2.ceea1533304dc#53",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
Nearest,
"-2.8082593202564596",
"-0x2.ceea1533304da#53",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
Floor,
"-3.4749259869231266",
"-0x3.7994bfdddaf86#53",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
Ceiling,
"-3.4749259869231262",
"-0x3.7994bfdddaf84#53",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
Down,
"-3.4749259869231262",
"-0x3.7994bfdddaf84#53",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
Up,
"-3.4749259869231266",
"-0x3.7994bfdddaf86#53",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
Nearest,
"-3.4749259869231266",
"-0x3.7994bfdddaf86#53",
Less,
);
test("1.0", "0x1.0#1", "-1/50000", Floor, "1.0", "0x1.0#1", Less);
test(
"1.0", "0x1.0#1", "-1/50000", Ceiling, "2.0", "0x2.0#1", Greater,
);
test("1.0", "0x1.0#1", "-1/50000", Down, "1.0", "0x1.0#1", Less);
test("1.0", "0x1.0#1", "-1/50000", Up, "2.0", "0x2.0#1", Greater);
test(
"1.0", "0x1.0#1", "-1/50000", Nearest, "1.0", "0x1.0#1", Less,
);
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]
fn sub_rational_round_fail() {
assert_panic!(Float::one_prec(1).sub_rational_round(-Rational::from_unsigneds(1u32, 3), Exact));
assert_panic!(
Float::one_prec(1).sub_rational_round_val_ref(&-Rational::from_unsigneds(1u32, 3), Exact)
);
assert_panic!(
Float::one_prec(1).sub_rational_round_ref_val(-Rational::from_unsigneds(1u32, 3), Exact)
);
assert_panic!(
Float::one_prec(1).sub_rational_round_ref_ref(&-Rational::from_unsigneds(1u32, 3), Exact)
);
assert_panic!({
let mut x = Float::one_prec(1);
x.sub_rational_round_assign(-Rational::from_unsigneds(1u32, 3), Exact)
});
assert_panic!({
let mut x = Float::one_prec(1);
x.sub_rational_round_assign_ref(&-Rational::from_unsigneds(1u32, 3), Exact)
});
}
#[test]
fn test_sub_rational_prec_round() {
let test = |s, s_hex, t, prec, rm, out: &str, out_hex: &str, o_out| {
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let y = Rational::from_str(t).unwrap();
let (diff, o) = x.clone().sub_rational_prec_round(y.clone(), prec, rm);
assert!(diff.is_valid());
assert_eq!(o, o_out);
assert_eq!(diff.to_string(), out);
assert_eq!(to_hex_string(&diff), out_hex);
let (diff_alt, o_alt) = x.clone().sub_rational_prec_round_val_ref(&y, prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_rational_prec_round_ref_val(y.clone(), prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_rational_prec_round_ref_ref(&y, prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_rational_prec_round_assign(y.clone(), prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let mut diff_alt = x.clone();
let o_alt = diff_alt.sub_rational_prec_round_assign_ref(&y, prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = add_rational_prec_round_naive(x.clone(), -&y, prec, rm);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_diff, rug_o) = rug_sub_rational_prec_round(
&rug::Float::exact_from(&x),
&rug::Rational::exact_from(&y),
prec,
rm,
);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff)
);
assert_eq!(rug_o, o);
}
};
test("NaN", "NaN", "-123", 1, Floor, "NaN", "NaN", Equal);
test("NaN", "NaN", "-123", 1, Ceiling, "NaN", "NaN", Equal);
test("NaN", "NaN", "-123", 1, Down, "NaN", "NaN", Equal);
test("NaN", "NaN", "-123", 1, Up, "NaN", "NaN", Equal);
test("NaN", "NaN", "-123", 1, Nearest, "NaN", "NaN", Equal);
test("NaN", "NaN", "-123", 1, Exact, "NaN", "NaN", Equal);
test(
"Infinity", "Infinity", "-123", 1, Floor, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-123", 1, Ceiling, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-123", 1, Down, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-123", 1, Up, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-123", 1, Nearest, "Infinity", "Infinity", Equal,
);
test(
"Infinity", "Infinity", "-123", 1, Exact, "Infinity", "Infinity", Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
1,
Floor,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
1,
Ceiling,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
1,
Down,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
1,
Up,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
1,
Nearest,
"-Infinity",
"-Infinity",
Equal,
);
test(
"-Infinity",
"-Infinity",
"-123",
1,
Exact,
"-Infinity",
"-Infinity",
Equal,
);
test("0.0", "0x0.0", "0", 1, Floor, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0", 1, Ceiling, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0", 1, Down, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0", 1, Up, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0", 1, Nearest, "0.0", "0x0.0", Equal);
test("0.0", "0x0.0", "0", 1, Exact, "0.0", "0x0.0", Equal);
test("-0.0", "-0x0.0", "0", 1, Floor, "-0.0", "-0x0.0", Equal);
test("-0.0", "-0x0.0", "0", 1, Ceiling, "-0.0", "-0x0.0", Equal);
test("-0.0", "-0x0.0", "0", 1, Down, "-0.0", "-0x0.0", Equal);
test("-0.0", "-0x0.0", "0", 1, Up, "-0.0", "-0x0.0", Equal);
test("-0.0", "-0x0.0", "0", 1, Nearest, "-0.0", "-0x0.0", Equal);
test("-0.0", "-0x0.0", "0", 1, Exact, "-0.0", "-0x0.0", Equal);
test(
"0.0",
"0x0.0",
"-123",
1,
Floor,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"0.0",
"0x0.0",
"-123",
1,
Ceiling,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test("0.0", "0x0.0", "-123", 1, Down, "6.0e1", "0x4.0E+1#1", Less);
test(
"0.0",
"0x0.0",
"-123",
1,
Up,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"0.0",
"0x0.0",
"-123",
1,
Nearest,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"-0.0",
"-0x0.0",
"-123",
1,
Floor,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"-0.0",
"-0x0.0",
"-123",
1,
Ceiling,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"-0.0",
"-0x0.0",
"-123",
1,
Down,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"-0.0",
"-0x0.0",
"-123",
1,
Up,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"-0.0",
"-0x0.0",
"-123",
1,
Nearest,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test("0.0", "0x0.0", "-1/3", 1, Floor, "0.2", "0x0.4#1", Less);
test(
"0.0", "0x0.0", "-1/3", 1, Ceiling, "0.5", "0x0.8#1", Greater,
);
test("0.0", "0x0.0", "-1/3", 1, Down, "0.2", "0x0.4#1", Less);
test("0.0", "0x0.0", "-1/3", 1, Up, "0.5", "0x0.8#1", Greater);
test("0.0", "0x0.0", "-1/3", 1, Floor, "0.2", "0x0.4#1", Less);
test("-0.0", "-0x0.0", "-1/3", 1, Floor, "0.2", "0x0.4#1", Less);
test(
"-0.0", "-0x0.0", "-1/3", 1, Ceiling, "0.5", "0x0.8#1", Greater,
);
test("-0.0", "-0x0.0", "-1/3", 1, Down, "0.2", "0x0.4#1", Less);
test("-0.0", "-0x0.0", "-1/3", 1, Up, "0.5", "0x0.8#1", Greater);
test("-0.0", "-0x0.0", "-1/3", 1, Floor, "0.2", "0x0.4#1", Less);
test(
"123.0",
"0x7b.0#7",
"0",
1,
Floor,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"123.0",
"0x7b.0#7",
"0",
1,
Ceiling,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"123.0",
"0x7b.0#7",
"0",
1,
Down,
"6.0e1",
"0x4.0E+1#1",
Less,
);
test(
"123.0",
"0x7b.0#7",
"0",
1,
Up,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test(
"123.0",
"0x7b.0#7",
"0",
1,
Nearest,
"1.0e2",
"0x8.0E+1#1",
Greater,
);
test("1.0", "0x1.0#1", "-2", 1, Floor, "2.0", "0x2.0#1", Less);
test(
"1.0", "0x1.0#1", "-2", 1, Ceiling, "4.0", "0x4.0#1", Greater,
);
test("1.0", "0x1.0#1", "-2", 1, Down, "2.0", "0x2.0#1", Less);
test("1.0", "0x1.0#1", "-2", 1, Up, "4.0", "0x4.0#1", Greater);
test(
"1.0", "0x1.0#1", "-2", 1, Nearest, "4.0", "0x4.0#1", Greater,
);
test("1.0", "0x1.0#1", "-2", 2, Floor, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.0#1", "-2", 2, Ceiling, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.0#1", "-2", 2, Down, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.0#1", "-2", 2, Up, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.0#1", "-2", 2, Nearest, "3.0", "0x3.0#2", Equal);
test("1.0", "0x1.0#1", "-2", 2, Exact, "3.0", "0x3.0#2", Equal);
test(
"1.0",
"0x1.000#10",
"-1/3",
100,
Floor,
"1.333333333333333333333333333332",
"0x1.5555555555555555555555554#100",
Less,
);
test(
"1.0",
"0x1.000#10",
"-1/3",
100,
Ceiling,
"1.333333333333333333333333333334",
"0x1.5555555555555555555555556#100",
Greater,
);
test(
"1.0",
"0x1.000#10",
"-1/3",
100,
Down,
"1.333333333333333333333333333332",
"0x1.5555555555555555555555554#100",
Less,
);
test(
"1.0",
"0x1.000#10",
"-1/3",
100,
Up,
"1.333333333333333333333333333334",
"0x1.5555555555555555555555556#100",
Greater,
);
test(
"1.0",
"0x1.000#10",
"-1/3",
100,
Nearest,
"1.333333333333333333333333333334",
"0x1.5555555555555555555555556#100",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
10,
Floor,
"3.473",
"0x3.79#10",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
10,
Ceiling,
"3.477",
"0x3.7a#10",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
10,
Down,
"3.473",
"0x3.79#10",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
10,
Up,
"3.477",
"0x3.7a#10",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"-1/3",
10,
Nearest,
"3.477",
"0x3.7a#10",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
10,
Floor,
"2.805",
"0x2.ce#10",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
10,
Ceiling,
"2.809",
"0x2.cf#10",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
10,
Down,
"2.805",
"0x2.ce#10",
Less,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
10,
Up,
"2.809",
"0x2.cf#10",
Greater,
);
test(
"3.1415926535897931",
"0x3.243f6a8885a30#53",
"1/3",
10,
Nearest,
"2.809",
"0x2.cf#10",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
10,
Floor,
"-2.809",
"-0x2.cf#10",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
10,
Ceiling,
"-2.805",
"-0x2.ce#10",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
10,
Down,
"-2.805",
"-0x2.ce#10",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
10,
Up,
"-2.809",
"-0x2.cf#10",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"-1/3",
10,
Nearest,
"-2.809",
"-0x2.cf#10",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
10,
Floor,
"-3.477",
"-0x3.7a#10",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
10,
Ceiling,
"-3.473",
"-0x3.79#10",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
10,
Down,
"-3.473",
"-0x3.79#10",
Greater,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
10,
Up,
"-3.477",
"-0x3.7a#10",
Less,
);
test(
"-3.1415926535897931",
"-0x3.243f6a8885a30#53",
"1/3",
10,
Nearest,
"-3.477",
"-0x3.7a#10",
Less,
);
test(
"1.0",
"0x1.0#1",
"-1/50000",
10,
Floor,
"1.0",
"0x1.000#10",
Less,
);
test(
"1.0",
"0x1.0#1",
"-1/50000",
10,
Ceiling,
"1.002",
"0x1.008#10",
Greater,
);
test(
"1.0",
"0x1.0#1",
"-1/50000",
10,
Down,
"1.0",
"0x1.000#10",
Less,
);
test(
"1.0",
"0x1.0#1",
"-1/50000",
10,
Up,
"1.002",
"0x1.008#10",
Greater,
);
test(
"1.0",
"0x1.0#1",
"-1/50000",
10,
Nearest,
"1.0",
"0x1.000#10",
Less,
);
test("1.0", "0x1.0#1", "1", 10, Floor, "-0.0", "-0x0.0", Equal);
test("1.0", "0x1.0#1", "1", 10, Ceiling, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", "1", 10, Down, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", "1", 10, Up, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", "1", 10, Nearest, "0.0", "0x0.0", Equal);
test("1.0", "0x1.0#1", "1", 10, Exact, "0.0", "0x0.0", Equal);
}
#[test]
fn sub_rational_prec_round_fail() {
assert_panic!(Float::one_prec(1).sub_rational_prec_round(
Rational::from_unsigneds(5u32, 8),
1,
Exact
));
assert_panic!(Float::one_prec(1).sub_rational_prec_round_val_ref(
&Rational::from_unsigneds(5u32, 8),
1,
Exact
));
assert_panic!(Float::one_prec(1).sub_rational_prec_round_ref_val(
Rational::from_unsigneds(5u32, 8),
1,
Exact
));
assert_panic!(Float::one_prec(1).sub_rational_prec_round_ref_ref(
&Rational::from_unsigneds(5u32, 8),
1,
Exact
));
assert_panic!({
let mut x = Float::one_prec(1);
x.sub_rational_prec_round_assign(Rational::from_unsigneds(5u32, 8), 1, Exact)
});
assert_panic!({
let mut x = Float::one_prec(1);
x.sub_rational_prec_round_assign_ref(&Rational::from_unsigneds(5u32, 8), 1, Exact)
});
}
#[test]
fn sub_prec_round_properties() {
float_float_unsigned_rounding_mode_quadruple_gen_var_2().test_properties(|(x, y, prec, rm)| {
let (diff, o) = x.clone().sub_prec_round(y.clone(), prec, rm);
assert!(diff.is_valid());
let (diff_alt, o_alt) = x.clone().sub_prec_round_val_ref(&y, prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_prec_round_ref_val(y.clone(), prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_prec_round_ref_ref(&y, prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.sub_prec_round_assign(y.clone(), prec, rm);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.sub_prec_round_assign_ref(&y, prec, rm);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = add_prec_round_naive(x.clone(), -&y, prec, rm);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_diff, rug_o) = rug_sub_prec_round(
&rug::Float::exact_from(&x),
&rug::Float::exact_from(&y),
prec,
rm,
);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff),
);
assert_eq!(rug_o, o);
}
if o == Equal && diff.is_finite() {
assert_eq!(
ComparableFloat(
diff.add_prec_round_ref_ref(&y, x.significant_bits(), Exact)
.0
.abs_negative_zero()
),
ComparableFloat(x.abs_negative_zero_ref())
);
assert_eq!(
ComparableFloat(
x.sub_prec_round_ref_ref(&diff, y.significant_bits(), Exact)
.0
.abs_negative_zero()
),
ComparableFloat(y.abs_negative_zero_ref())
);
}
let r_diff = if diff.is_finite() {
if diff.is_normal() {
assert_eq!(diff.get_prec(), Some(prec));
}
let r_diff = Rational::exact_from(&x) - Rational::exact_from(&y);
assert_eq!(diff.partial_cmp(&r_diff), Some(o));
if o == Less {
let mut next = diff.clone();
next.increment();
assert!(next > r_diff);
} else if o == Greater {
let mut next = diff.clone();
next.decrement();
assert!(next < r_diff);
}
Some(r_diff)
} else {
assert_eq!(o, Equal);
None
};
match (r_diff.is_some() && *r_diff.as_ref().unwrap() >= 0u32, rm) {
(_, Floor) | (true, Down) | (false, Up) => {
assert_ne!(o, Greater);
}
(_, Ceiling) | (true, Up) | (false, Down) => {
assert_ne!(o, Less);
}
(_, Exact) => assert_eq!(o, Equal),
_ => {}
}
let (mut diff_alt, mut o_alt) = y.sub_prec_round_ref_ref(&x, prec, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero_ref()),
ComparableFloat(diff.abs_negative_zero_ref())
);
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.add_prec_round_ref_val(-&y, prec, rm);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (mut diff_alt, mut o_alt) = (-&x).add_prec_round_val_ref(&y, prec, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
assert_eq!(o_alt, o);
let (mut diff_alt, mut o_alt) = (-&x).sub_prec_round(-&y, prec, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
assert_eq!(o_alt, o);
if o == Equal {
for rm in exhaustive_rounding_modes() {
let (d, oo) = x.sub_prec_round_ref_ref(&y, prec, rm);
assert_eq!(
ComparableFloat(d.abs_negative_zero_ref()),
ComparableFloat(diff.abs_negative_zero_ref())
);
assert_eq!(oo, Equal);
}
} else {
assert_panic!(x.sub_prec_round_ref_ref(&y, prec, Exact));
}
});
float_unsigned_rounding_mode_triple_gen_var_1().test_properties(|(x, prec, rm)| {
let (diff, o) = x.sub_prec_round_ref_val(Float::NAN, prec, rm);
assert!(diff.is_nan());
assert_eq!(o, Equal);
let (diff, o) = Float::NAN.sub_prec_round_val_ref(&x, prec, rm);
assert!(diff.is_nan());
assert_eq!(o, Equal);
if !x.is_nan() {
if x != Float::INFINITY {
assert_eq!(
x.sub_prec_round_ref_val(Float::INFINITY, prec, rm),
(Float::NEGATIVE_INFINITY, Equal)
);
assert_eq!(
Float::INFINITY.sub_prec_round_val_ref(&x, prec, rm),
(Float::INFINITY, Equal)
);
}
if x != Float::NEGATIVE_INFINITY {
assert_eq!(
x.sub_prec_round_ref_val(Float::NEGATIVE_INFINITY, prec, rm),
(Float::INFINITY, Equal)
);
assert_eq!(
Float::NEGATIVE_INFINITY.sub_prec_round_val_ref(&x, prec, rm),
(Float::NEGATIVE_INFINITY, Equal)
);
}
}
if !x.is_negative_zero() {
let (diff, o) = x.sub_prec_round_ref_val(Float::ZERO, prec, rm);
let mut diff_alt = x.clone();
let o_alt = diff_alt.set_prec_round(prec, rm);
assert_eq!(
ComparableFloat(diff.abs_negative_zero()),
ComparableFloat(diff_alt.abs_negative_zero())
);
assert_eq!(o, o_alt);
let (diff, o) = Float::ZERO.sub_prec_round_val_ref(&x, prec, rm);
let mut diff_alt = -&x;
let o_alt = diff_alt.set_prec_round(prec, rm);
assert_eq!(
ComparableFloat(diff.abs_negative_zero()),
ComparableFloat(diff_alt.abs_negative_zero())
);
assert_eq!(o, o_alt);
}
if rm != Floor || !x.is_positive_zero() {
let (diff, o) = x.sub_prec_round_ref_val(Float::NEGATIVE_ZERO, prec, rm);
let mut diff_alt = x.clone();
let o_alt = diff_alt.set_prec_round(prec, rm);
assert_eq!(
ComparableFloat(diff.abs_negative_zero()),
ComparableFloat(diff_alt.abs_negative_zero())
);
assert_eq!(o, o_alt);
let (diff, o) = Float::NEGATIVE_ZERO.sub_prec_round_val_ref(&x, prec, rm);
let mut diff_alt = -&x;
let o_alt = diff_alt.set_prec_round(prec, rm);
assert_eq!(
ComparableFloat(diff.abs_negative_zero()),
ComparableFloat(diff_alt.abs_negative_zero())
);
assert_eq!(o, o_alt);
}
});
}
#[test]
fn sub_prec_properties() {
float_float_unsigned_triple_gen_var_1().test_properties(|(x, y, prec)| {
let (diff, o) = x.clone().sub_prec(y.clone(), prec);
assert!(diff.is_valid());
let (diff_alt, o_alt) = x.clone().sub_prec_val_ref(&y, prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_prec_ref_val(y.clone(), prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_prec_ref_ref(&y, prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.sub_prec_assign(y.clone(), prec);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.sub_prec_assign_ref(&y, prec);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = add_prec_round_naive(x.clone(), -&y, prec, Nearest);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (rug_diff, rug_o) = rug_sub_prec(
&rug::Float::exact_from(&x),
&rug::Float::exact_from(&y),
prec,
);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff),
);
assert_eq!(rug_o, o);
if o == Equal && diff.is_finite() {
assert_eq!(
ComparableFloat(
diff.add_prec_ref_ref(&y, x.significant_bits())
.0
.abs_negative_zero()
),
ComparableFloat(x.abs_negative_zero_ref())
);
assert_eq!(
ComparableFloat(
x.sub_prec_ref_ref(&diff, y.significant_bits())
.0
.abs_negative_zero()
),
ComparableFloat(y.abs_negative_zero_ref())
);
}
let (diff_alt, o_alt) = x.sub_prec_round_ref_ref(&y, prec, Nearest);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
if diff.is_finite() {
if diff.is_normal() {
assert_eq!(diff.get_prec(), Some(prec));
}
let r_diff = Rational::exact_from(&x) - Rational::exact_from(&y);
assert_eq!(diff.partial_cmp(&r_diff), Some(o));
if o == Less {
let mut next = diff.clone();
next.increment();
assert!(next > r_diff);
} else if o == Greater {
let mut next = diff.clone();
next.decrement();
assert!(next < r_diff);
}
} else {
assert_eq!(o, Equal);
}
let (mut diff_alt, mut o_alt) = y.sub_prec_ref_ref(&x, prec);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero_ref()),
ComparableFloat(diff.abs_negative_zero_ref())
);
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.add_prec_ref_val(-&y, prec);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
if (x != 0u32 && y != 0u32) || (x.is_sign_positive() && y.is_sign_positive()) {
let (mut diff_alt, mut o_alt) = (-&x).add_prec_val_ref(&y, prec);
diff_alt.neg_assign();
diff_alt.abs_negative_zero_assign();
o_alt = o_alt.reverse();
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (mut diff_alt, mut o_alt) = (-x).sub_prec(-y, prec);
diff_alt.neg_assign();
diff_alt.abs_negative_zero_assign();
o_alt = o_alt.reverse();
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
}
});
float_unsigned_pair_gen_var_1().test_properties(|(x, prec)| {
let (diff, o) = x.sub_prec_ref_val(Float::NAN, prec);
assert!(diff.is_nan());
assert_eq!(o, Equal);
let (diff, o) = Float::NAN.sub_prec_val_ref(&x, prec);
assert!(diff.is_nan());
assert_eq!(o, Equal);
if !x.is_nan() {
if x != Float::INFINITY {
assert_eq!(
x.sub_prec_ref_val(Float::INFINITY, prec),
(Float::NEGATIVE_INFINITY, Equal)
);
assert_eq!(
Float::INFINITY.sub_prec_val_ref(&x, prec),
(Float::INFINITY, Equal)
);
}
if x != Float::NEGATIVE_INFINITY {
assert_eq!(
x.sub_prec_ref_val(Float::NEGATIVE_INFINITY, prec),
(Float::INFINITY, Equal)
);
assert_eq!(
Float::NEGATIVE_INFINITY.sub_prec_val_ref(&x, prec),
(Float::NEGATIVE_INFINITY, Equal)
);
}
}
if !x.is_negative_zero() {
let (diff, o) = x.sub_prec_ref_val(Float::ZERO, prec);
let mut diff_alt = x.clone();
let o_alt = diff_alt.set_prec(prec);
assert_eq!(ComparableFloat(diff), ComparableFloat(diff_alt));
assert_eq!(o, o_alt);
let (diff, o) = Float::ZERO.sub_prec_val_ref(&x, prec);
let mut diff_alt = -&x;
let o_alt = diff_alt.set_prec(prec);
assert_eq!(
ComparableFloat(diff.abs_negative_zero()),
ComparableFloat(diff_alt.abs_negative_zero())
);
assert_eq!(o, o_alt);
}
let (diff, o) = x.sub_prec_ref_val(Float::NEGATIVE_ZERO, prec);
let mut diff_alt = x.clone();
let o_alt = diff_alt.set_prec(prec);
assert_eq!(
ComparableFloat(diff.abs_negative_zero()),
ComparableFloat(diff_alt.abs_negative_zero())
);
assert_eq!(o, o_alt);
let (diff, o) = Float::NEGATIVE_ZERO.sub_prec_val_ref(&x, prec);
let mut diff_alt = -x;
let o_alt = diff_alt.set_prec(prec);
assert_eq!(ComparableFloat(diff), ComparableFloat(diff_alt));
assert_eq!(o, o_alt);
});
}
#[allow(clippy::needless_pass_by_value)]
fn sub_round_properties_helper(x: Float, y: Float, rm: RoundingMode) {
let (diff, o) = x.clone().sub_round(y.clone(), rm);
assert!(diff.is_valid());
let (diff_alt, o_alt) = x.clone().sub_round_val_ref(&y, rm);
assert!(diff_alt.is_valid());
assert_eq!(o_alt, o);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let (diff_alt, o_alt) = x.sub_round_ref_val(y.clone(), rm);
assert!(diff_alt.is_valid());
assert_eq!(o_alt, o);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let (diff_alt, o_alt) = x.sub_round_ref_ref(&y, rm);
assert!(diff_alt.is_valid());
assert_eq!(o_alt, o);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let mut x_alt = x.clone();
let o_alt = x_alt.sub_round_assign(y.clone(), rm);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.sub_round_assign_ref(&y, rm);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = add_prec_round_naive(
x.clone(),
-&y,
max(x.significant_bits(), y.significant_bits()),
rm,
);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) =
x.sub_prec_round_ref_ref(&y, max(x.significant_bits(), y.significant_bits()), rm);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
if o == Equal && diff.is_finite() {
assert_eq!(diff.add_round_ref_ref(&y, Exact).0, x);
assert_eq!(x.sub_round_ref_ref(&diff, Exact).0, y);
}
let r_diff = if diff.is_finite() {
if x.is_normal() && y.is_normal() && diff.is_normal() {
assert_eq!(
diff.get_prec(),
Some(max(x.get_prec().unwrap(), y.get_prec().unwrap()))
);
}
let r_diff = Rational::exact_from(&x) - Rational::exact_from(&y);
assert_eq!(diff.partial_cmp(&r_diff), Some(o));
if o == Less {
let mut next = diff.clone();
next.increment();
assert!(next > r_diff);
} else if o == Greater {
let mut next = diff.clone();
next.decrement();
assert!(next < r_diff);
}
Some(r_diff)
} else {
assert_eq!(o, Equal);
None
};
match (r_diff.is_some() && *r_diff.as_ref().unwrap() >= 0u32, rm) {
(_, Floor) | (true, Down) | (false, Up) => {
assert_ne!(o, Greater);
}
(_, Ceiling) | (true, Up) | (false, Down) => {
assert_ne!(o, Less);
}
(_, Exact) => assert_eq!(o, Equal),
_ => {}
}
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_diff, rug_o) =
rug_sub_round(&rug::Float::exact_from(&x), &rug::Float::exact_from(&y), rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff),
);
assert_eq!(rug_o, o);
}
let (mut diff_alt, mut o_alt) = y.sub_round_ref_ref(&x, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(o_alt, o);
assert_eq!(
ComparableFloatRef(&diff_alt.abs_negative_zero()),
ComparableFloatRef(&diff.abs_negative_zero_ref())
);
let (diff_alt, o_alt) = x.add_round_ref_val(-&y, rm);
assert_eq!(o_alt, o);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let (mut diff_alt, mut o_alt) = (-&x).add_round_val_ref(&y, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(o_alt, o);
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
let (mut diff_alt, mut o_alt) = (-&x).sub_round(-&y, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(o_alt, o);
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
if o == Equal {
for rm in exhaustive_rounding_modes() {
let (d, oo) = x.sub_round_ref_ref(&y, rm);
assert_eq!(
ComparableFloat(d.abs_negative_zero_ref()),
ComparableFloat(diff.abs_negative_zero_ref())
);
assert_eq!(oo, Equal);
}
} else {
assert_panic!(x.sub_round_ref_ref(&y, Exact));
}
}
#[test]
fn sub_round_properties() {
float_float_rounding_mode_triple_gen_var_2().test_properties(|(x, y, rm)| {
sub_round_properties_helper(x, y, rm);
});
float_float_rounding_mode_triple_gen_var_10().test_properties(|(x, y, rm)| {
sub_round_properties_helper(x, y, rm);
});
float_float_rounding_mode_triple_gen_var_11().test_properties(|(x, y, rm)| {
sub_round_properties_helper(x, y, rm);
});
float_float_rounding_mode_triple_gen_var_12().test_properties(|(x, y, rm)| {
sub_round_properties_helper(x, y, rm);
});
float_float_rounding_mode_triple_gen_var_13().test_properties(|(x, y, rm)| {
sub_round_properties_helper(x, y, rm);
});
float_float_rounding_mode_triple_gen_var_14().test_properties(|(x, y, rm)| {
sub_round_properties_helper(x, y, rm);
});
float_float_rounding_mode_triple_gen_var_15().test_properties(|(x, y, rm)| {
sub_round_properties_helper(x, y, rm);
});
float_rounding_mode_pair_gen().test_properties(|(x, rm)| {
let (diff, o) = x.sub_round_ref_val(Float::NAN, rm);
assert!(diff.is_nan());
assert_eq!(o, Equal);
let (diff, o) = Float::NAN.sub_round_val_ref(&x, rm);
assert!(diff.is_nan());
assert_eq!(o, Equal);
if !x.is_nan() {
if x != Float::INFINITY {
assert_eq!(
x.sub_round_ref_val(Float::INFINITY, rm),
(Float::NEGATIVE_INFINITY, Equal)
);
assert_eq!(
Float::INFINITY.sub_round_val_ref(&x, rm),
(Float::INFINITY, Equal)
);
}
if x != Float::NEGATIVE_INFINITY {
assert_eq!(
x.sub_round_ref_val(Float::NEGATIVE_INFINITY, rm),
(Float::INFINITY, Equal)
);
assert_eq!(
Float::NEGATIVE_INFINITY.sub_round_val_ref(&x, rm),
(Float::NEGATIVE_INFINITY, Equal)
);
}
}
if !x.is_negative_zero() {
let (diff, o) = x.sub_round_ref_val(Float::ZERO, rm);
assert_eq!(
ComparableFloat(diff.abs_negative_zero_ref()),
ComparableFloat(x.abs_negative_zero_ref())
);
assert_eq!(o, Equal);
let (diff, o) = Float::ZERO.sub_round_val_ref(&x, rm);
assert_eq!(
ComparableFloat(diff.abs_negative_zero()),
ComparableFloat((-&x).abs_negative_zero())
);
assert_eq!(o, Equal);
}
if rm != Floor || !x.is_positive_zero() {
let (diff, o) = x.sub_round_ref_val(Float::NEGATIVE_ZERO, rm);
assert_eq!(
ComparableFloat(diff.abs_negative_zero_ref()),
ComparableFloat(x.abs_negative_zero_ref())
);
assert_eq!(o, Equal);
let (diff, o) = Float::NEGATIVE_ZERO.sub_round_val_ref(&x, rm);
assert_eq!(
ComparableFloat(diff.abs_negative_zero()),
ComparableFloat((-&x).abs_negative_zero())
);
assert_eq!(o, Equal);
}
});
}
#[allow(clippy::type_repetition_in_bounds)]
fn sub_properties_helper_1()
where
Float: From + PartialOrd,
for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
{
primitive_float_pair_gen::().test_properties(|(x, y)| {
let diff_1 = x - y;
let diff_2 = emulate_primitive_float_fn_2(|x, y, prec| x.sub_prec(y, prec).0, x, y);
assert_eq!(NiceFloat(diff_1), NiceFloat(diff_2));
});
}
#[allow(clippy::needless_pass_by_value)]
fn sub_properties_helper_2(x: Float, y: Float) {
let diff = x.clone() - y.clone();
assert!(diff.is_valid());
let diff_alt = x.clone() - &y;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = &x - y.clone();
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = &x - &y;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let mut x_alt = x.clone();
x_alt -= y.clone();
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
let mut x_alt = x.clone();
x_alt -= &y;
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
let diff_alt = add_prec_round_naive(
x.clone(),
-&y,
max(x.significant_bits(), y.significant_bits()),
Nearest,
)
.0;
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = x
.sub_prec_round_ref_ref(&y, max(x.significant_bits(), y.significant_bits()), Nearest)
.0;
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = x
.sub_prec_ref_ref(&y, max(x.significant_bits(), y.significant_bits()))
.0;
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let (diff_alt, o) = x.sub_round_ref_ref(&y, Nearest);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
if o == Equal && diff.is_finite() {
assert_eq!(&diff + &y, x);
assert_eq!(&x - &diff, y);
}
if diff.is_finite() && x.is_normal() && y.is_normal() && diff.is_normal() {
assert_eq!(
diff.get_prec(),
Some(max(x.get_prec().unwrap(), y.get_prec().unwrap()))
);
let r_diff = Rational::exact_from(&x) - Rational::exact_from(&y);
if diff < r_diff {
let mut next = diff.clone();
next.increment();
assert!(next > r_diff);
} else if diff > r_diff {
let mut next = diff.clone();
next.decrement();
assert!(next < r_diff);
}
}
let rug_diff = rug_sub(&rug::Float::exact_from(&x), &rug::Float::exact_from(&y));
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff),
);
let diff_alt = -(&y - &x);
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
let diff_alt = &x + -&y;
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = -(-&x + &y);
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
let diff_alt = -(-&x - -&y);
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero())
);
}
#[test]
fn sub_properties() {
float_pair_gen().test_properties(|(x, y)| {
sub_properties_helper_2(x, y);
});
float_pair_gen_var_2().test_properties(|(x, y)| {
sub_properties_helper_2(x, y);
});
float_pair_gen_var_3().test_properties(|(x, y)| {
sub_properties_helper_2(x, y);
});
float_pair_gen_var_4().test_properties(|(x, y)| {
sub_properties_helper_2(x, y);
});
float_pair_gen_var_5().test_properties(|(x, y)| {
sub_properties_helper_2(x, y);
});
float_pair_gen_var_6().test_properties(|(x, y)| {
sub_properties_helper_2(x, y);
});
float_pair_gen_var_7().test_properties(|(x, y)| {
sub_properties_helper_2(x, y);
});
apply_fn_to_primitive_floats!(sub_properties_helper_1);
float_gen().test_properties(|x| {
assert!((&x - Float::NAN).is_nan());
assert!((Float::NAN - &x).is_nan());
if !x.is_nan() {
if x != Float::INFINITY {
assert_eq!(&x - Float::INFINITY, Float::NEGATIVE_INFINITY);
assert_eq!(Float::INFINITY - &x, Float::INFINITY);
}
if x != Float::NEGATIVE_INFINITY {
assert_eq!(&x - Float::NEGATIVE_INFINITY, Float::INFINITY);
assert_eq!(Float::NEGATIVE_INFINITY - &x, Float::NEGATIVE_INFINITY);
}
}
assert_eq!(
ComparableFloatRef(&(&x - Float::ZERO)),
ComparableFloatRef(&x)
);
assert_eq!(
ComparableFloat((-(Float::ZERO - &x)).abs_negative_zero()),
ComparableFloat(x.abs_negative_zero_ref())
);
assert_eq!(
ComparableFloat((&x - Float::NEGATIVE_ZERO).abs_negative_zero()),
ComparableFloat(x.abs_negative_zero_ref())
);
assert_eq!(
ComparableFloatRef(&-(Float::NEGATIVE_ZERO - &x)),
ComparableFloatRef(&x)
);
});
}
#[test]
fn sub_rational_prec_round_properties() {
float_rational_unsigned_rounding_mode_quadruple_gen_var_2().test_properties(
|(x, y, prec, rm)| {
let (diff, o) = x.clone().sub_rational_prec_round(y.clone(), prec, rm);
assert!(diff.is_valid());
let (diff_alt, o_alt) = x.clone().sub_rational_prec_round_val_ref(&y, prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_rational_prec_round_ref_val(y.clone(), prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_rational_prec_round_ref_ref(&y, prec, rm);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.sub_rational_prec_round_assign(y.clone(), prec, rm);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.sub_rational_prec_round_assign_ref(&y, prec, rm);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = add_rational_prec_round_naive(x.clone(), -&y, prec, rm);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_diff, rug_o) = rug_sub_rational_prec_round(
&rug::Float::exact_from(&x),
&rug::Rational::exact_from(&y),
prec,
rm,
);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff)
);
assert_eq!(rug_o, o);
}
if o == Equal && diff.is_finite() {
assert_eq!(
ComparableFloat(
diff.add_rational_prec_round_ref_ref(&y, x.significant_bits(), Exact)
.0
.abs_negative_zero()
),
ComparableFloat(x.abs_negative_zero_ref())
);
// TODO additional test
}
let r_diff = if diff.is_finite() {
if diff.is_normal() {
assert_eq!(diff.get_prec(), Some(prec));
}
let r_diff = Rational::exact_from(&x) - &y;
assert_eq!(diff.partial_cmp(&r_diff), Some(o));
if o == Less {
let mut next = diff.clone();
next.increment();
assert!(next > r_diff);
} else if o == Greater {
let mut next = diff.clone();
next.decrement();
assert!(next < r_diff);
}
Some(r_diff)
} else {
assert_eq!(o, Equal);
None
};
match (r_diff.is_some() && *r_diff.as_ref().unwrap() >= 0u32, rm) {
(_, Floor) | (true, Down) | (false, Up) => {
assert_ne!(o, Greater);
}
(_, Ceiling) | (true, Up) | (false, Down) => {
assert_ne!(o, Less);
}
(_, Exact) => assert_eq!(o, Equal),
_ => {}
}
let (diff_alt, o_alt) = x.add_rational_prec_round_ref_val(-&y, prec, rm);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (mut diff_alt, mut o_alt) = (-&x).add_rational_prec_round_val_ref(&y, prec, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
assert_eq!(o_alt, o);
let (mut diff_alt, mut o_alt) = (-&x).sub_rational_prec_round(-&y, prec, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
assert_eq!(o_alt, o);
if o == Equal {
for rm in exhaustive_rounding_modes() {
let (d, oo) = x.sub_rational_prec_round_ref_ref(&y, prec, rm);
assert_eq!(
ComparableFloat(d.abs_negative_zero_ref()),
ComparableFloat(diff.abs_negative_zero_ref())
);
assert_eq!(oo, Equal);
}
} else {
assert_panic!(x.sub_rational_prec_round_ref_ref(&y, prec, Exact));
}
},
);
float_unsigned_rounding_mode_triple_gen_var_1().test_properties(|(x, prec, rm)| {
if !x.is_negative_zero() {
let (diff, o) = x.sub_rational_prec_round_ref_val(Rational::ZERO, prec, rm);
let mut diff_alt = x.clone();
let o_alt = diff_alt.set_prec_round(prec, rm);
assert_eq!(ComparableFloat(diff), ComparableFloat(diff_alt));
assert_eq!(o, o_alt);
}
});
rational_unsigned_rounding_mode_triple_gen_var_1().test_properties(|(x, prec, rm)| {
let (diff, o) = Float::NAN.sub_rational_prec_round_val_ref(&x, prec, rm);
assert!(diff.is_nan());
assert_eq!(o, Equal);
assert_eq!(
Float::INFINITY.sub_rational_prec_round_val_ref(&x, prec, rm),
(Float::INFINITY, Equal)
);
assert_eq!(
Float::NEGATIVE_INFINITY.sub_rational_prec_round_val_ref(&x, prec, rm),
(Float::NEGATIVE_INFINITY, Equal)
);
let (diff, o) = Float::ZERO.sub_rational_prec_round_val_ref(&x, prec, rm);
let (mut diff_alt, mut o_alt) = Float::from_rational_prec_round_ref(&x, prec, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(
ComparableFloat(diff.abs_negative_zero()),
ComparableFloat(diff_alt.abs_negative_zero())
);
assert_eq!(o, o_alt);
let (diff, o) = Float::NEGATIVE_ZERO.sub_rational_prec_round_val_ref(&x, prec, rm);
let (mut diff_alt, mut o_alt) = Float::from_rational_prec_round_ref(&x, prec, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(ComparableFloat(diff), ComparableFloat(diff_alt));
assert_eq!(o, o_alt);
});
}
#[test]
fn sub_rational_prec_properties() {
float_rational_unsigned_triple_gen_var_1().test_properties(|(x, y, prec)| {
let (diff, o) = x.clone().sub_rational_prec(y.clone(), prec);
assert!(diff.is_valid());
let (diff_alt, o_alt) = x.clone().sub_rational_prec_val_ref(&y, prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_rational_prec_ref_val(y.clone(), prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_rational_prec_ref_ref(&y, prec);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.sub_rational_prec_assign(y.clone(), prec);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.sub_rational_prec_assign_ref(&y, prec);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = add_rational_prec_round_naive(x.clone(), -&y, prec, Nearest);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (rug_diff, rug_o) = rug_sub_rational_prec(
&rug::Float::exact_from(&x),
&rug::Rational::exact_from(&y),
prec,
);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff)
);
assert_eq!(rug_o, o);
if o == Equal && diff.is_finite() {
assert_eq!(
ComparableFloat(
diff.add_rational_prec_ref_ref(&y, x.significant_bits())
.0
.abs_negative_zero()
),
ComparableFloat(x.abs_negative_zero_ref())
);
// TODO additional test
}
let (diff_alt, o_alt) = x.sub_rational_prec_round_ref_ref(&y, prec, Nearest);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
if diff.is_finite() {
if diff.is_normal() {
assert_eq!(diff.get_prec(), Some(prec));
}
let r_diff = Rational::exact_from(&x) - &y;
assert_eq!(diff.partial_cmp(&r_diff), Some(o));
if o == Less {
let mut next = diff.clone();
next.increment();
assert!(next > r_diff);
} else if o == Greater {
let mut next = diff.clone();
next.decrement();
assert!(next < r_diff);
}
} else {
assert_eq!(o, Equal);
}
let (diff_alt, o_alt) = x.add_rational_prec_ref_val(-&y, prec);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
if (x != 0u32 && y != 0u32) || x.is_sign_positive() {
let (mut diff_alt, mut o_alt) = (-&x).add_rational_prec_val_ref(&y, prec);
diff_alt.neg_assign();
diff_alt.abs_negative_zero_assign();
o_alt = o_alt.reverse();
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (mut diff_alt, mut o_alt) = (-x).sub_rational_prec(-y, prec);
diff_alt.neg_assign();
diff_alt.abs_negative_zero_assign();
o_alt = o_alt.reverse();
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
}
});
float_unsigned_pair_gen_var_1().test_properties(|(x, prec)| {
if !x.is_negative_zero() {
let (diff, o) = x.sub_rational_prec_ref_val(Rational::ZERO, prec);
let mut diff_alt = x.clone();
let o_alt = diff_alt.set_prec(prec);
assert_eq!(ComparableFloat(diff), ComparableFloat(diff_alt));
assert_eq!(o, o_alt);
}
});
rational_unsigned_pair_gen_var_3().test_properties(|(x, prec)| {
let (diff, o) = Float::NAN.sub_rational_prec_val_ref(&x, prec);
assert!(diff.is_nan());
assert_eq!(o, Equal);
assert_eq!(
Float::INFINITY.sub_rational_prec_val_ref(&x, prec),
(Float::INFINITY, Equal)
);
assert_eq!(
Float::NEGATIVE_INFINITY.sub_rational_prec_val_ref(&x, prec),
(Float::NEGATIVE_INFINITY, Equal)
);
let (diff, o) = Float::ZERO.sub_rational_prec_val_ref(&x, prec);
let (mut diff_alt, mut o_alt) = Float::from_rational_prec_ref(&x, prec);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(
ComparableFloat(diff.abs_negative_zero()),
ComparableFloat(diff_alt.abs_negative_zero())
);
assert_eq!(o, o_alt);
let (diff, o) = Float::NEGATIVE_ZERO.sub_rational_prec_val_ref(&x, prec);
let (mut diff_alt, mut o_alt) = Float::from_rational_prec_ref(&x, prec);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(ComparableFloat(diff), ComparableFloat(diff_alt));
assert_eq!(o, o_alt);
});
}
#[test]
fn sub_rational_round_properties() {
float_rational_rounding_mode_triple_gen_var_2().test_properties(|(x, y, rm)| {
let (diff, o) = x.clone().sub_rational_round(y.clone(), rm);
assert!(diff.is_valid());
let (diff_alt, o_alt) = x.clone().sub_rational_round_val_ref(&y, rm);
assert!(diff_alt.is_valid());
assert_eq!(o_alt, o);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let (diff_alt, o_alt) = x.sub_rational_round_ref_val(y.clone(), rm);
assert!(diff_alt.is_valid());
assert_eq!(o_alt, o);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let (diff_alt, o_alt) = x.sub_rational_round_ref_ref(&y, rm);
assert!(diff_alt.is_valid());
assert_eq!(o_alt, o);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let mut x_alt = x.clone();
let o_alt = x_alt.sub_rational_round_assign(y.clone(), rm);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let mut x_alt = x.clone();
let o_alt = x_alt.sub_rational_round_assign_ref(&y, rm);
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) =
add_rational_prec_round_naive(x.clone(), -&y, x.significant_bits(), rm);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
let (diff_alt, o_alt) = x.sub_rational_prec_round_ref_ref(&y, x.significant_bits(), rm);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
assert_eq!(o_alt, o);
if o == Equal && diff.is_finite() && diff != 0 {
assert_eq!(diff.add_rational_round_ref_ref(&y, Exact).0, x);
// TODO additional test
}
let r_diff = if diff.is_finite() {
if x.is_normal() && diff.is_normal() {
assert_eq!(diff.get_prec(), Some(x.get_prec().unwrap()));
}
let r_diff = Rational::exact_from(&x) - &y;
assert_eq!(diff.partial_cmp(&r_diff), Some(o));
if o == Less {
let mut next = diff.clone();
next.increment();
assert!(next > r_diff);
} else if o == Greater {
let mut next = diff.clone();
next.decrement();
assert!(next < r_diff);
}
Some(r_diff)
} else {
assert_eq!(o, Equal);
None
};
match (r_diff.is_some() && *r_diff.as_ref().unwrap() >= 0u32, rm) {
(_, Floor) | (true, Down) | (false, Up) => {
assert_ne!(o, Greater);
}
(_, Ceiling) | (true, Up) | (false, Down) => {
assert_ne!(o, Less);
}
(_, Exact) => assert_eq!(o, Equal),
_ => {}
}
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_diff, rug_o) = rug_sub_rational_round(
&rug::Float::exact_from(&x),
&rug::Rational::exact_from(&y),
rm,
);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff)
);
assert_eq!(rug_o, o);
}
let (diff_alt, o_alt) = x.add_rational_round_ref_val(-&y, rm);
assert_eq!(o_alt, o);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let (mut diff_alt, mut o_alt) = (-&x).add_rational_round_val_ref(&y, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(o_alt, o);
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
let (mut diff_alt, mut o_alt) = (-&x).sub_rational_round(-&y, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(o_alt, o);
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
if o == Equal {
for rm in exhaustive_rounding_modes() {
let (d, oo) = x.sub_rational_round_ref_ref(&y, rm);
assert_eq!(
ComparableFloat(d.abs_negative_zero_ref()),
ComparableFloat(diff.abs_negative_zero_ref())
);
assert_eq!(oo, Equal);
}
} else {
assert_panic!(x.sub_rational_round_ref_ref(&y, Exact));
}
});
float_rounding_mode_pair_gen().test_properties(|(x, rm)| {
if !x.is_negative_zero() {
let (diff, o) = x.sub_rational_round_ref_val(Rational::ZERO, rm);
assert_eq!(ComparableFloat(diff), ComparableFloat(x));
assert_eq!(o, Equal);
}
});
rational_rounding_mode_pair_gen_var_6().test_properties(|(x, rm)| {
let (diff, o) = Float::NAN.sub_rational_round_val_ref(&x, rm);
assert!(diff.is_nan());
assert_eq!(o, Equal);
assert_eq!(
Float::INFINITY.sub_rational_round_val_ref(&x, rm),
(Float::INFINITY, Equal)
);
assert_eq!(
Float::NEGATIVE_INFINITY.sub_rational_round_val_ref(&x, rm),
(Float::NEGATIVE_INFINITY, Equal)
);
let (diff, o) = Float::ZERO.sub_rational_round_val_ref(&x, rm);
let (mut diff_alt, mut o_alt) = Float::from_rational_prec_round_ref(&x, 1, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(
ComparableFloat(diff.abs_negative_zero()),
ComparableFloat(diff_alt.abs_negative_zero())
);
assert_eq!(o, o_alt);
let (diff, o) = Float::NEGATIVE_ZERO.sub_rational_round_val_ref(&x, rm);
let (mut diff_alt, mut o_alt) = Float::from_rational_prec_round_ref(&x, 1, -rm);
diff_alt.neg_assign();
o_alt = o_alt.reverse();
assert_eq!(ComparableFloatRef(&diff), ComparableFloatRef(&diff_alt));
assert_eq!(o, o_alt);
});
}
#[test]
fn sub_rational_properties() {
float_rational_pair_gen().test_properties(|(x, y)| {
let diff = x.clone() - y.clone();
assert!(diff.is_valid());
let diff_alt = x.clone() - &y;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = &x - y.clone();
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = &x - &y;
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = -(y.clone() - x.clone());
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = -(y.clone() - &x);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = -(&y - x.clone());
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = -(&y - &x);
assert!(diff_alt.is_valid());
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let mut x_alt = x.clone();
x_alt -= y.clone();
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
let mut x_alt = x.clone();
x_alt -= &y;
assert!(x_alt.is_valid());
assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&diff));
let diff_alt =
add_rational_prec_round_naive(x.clone(), -&y, x.significant_bits(), Nearest).0;
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = x
.sub_rational_prec_round_ref_ref(&y, x.significant_bits(), Nearest)
.0;
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let diff_alt = x.sub_rational_prec_ref_ref(&y, x.significant_bits()).0;
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
let (diff_alt, o) = x.sub_rational_round_ref_ref(&y, Nearest);
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
if o == Equal && diff.is_finite() && diff != 0 {
assert_eq!(&diff + &y, x);
// TODO additional test
}
if diff.is_finite() && x.is_normal() && diff.is_normal() {
assert_eq!(diff.get_prec(), Some(x.get_prec().unwrap()));
let r_diff = Rational::exact_from(&x) - &y;
if diff < r_diff {
let mut next = diff.clone();
next.increment();
assert!(next > r_diff);
} else if diff > r_diff {
let mut next = diff.clone();
next.decrement();
assert!(next < r_diff);
}
}
let rug_diff = rug_sub_rational(&rug::Float::exact_from(&x), &rug::Rational::from(&y));
assert_eq!(
ComparableFloatRef(&Float::from(&rug_diff)),
ComparableFloatRef(&diff),
);
let diff_alt = &x + -&y;
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
if (x != 0u32 && y != 0u32) || x.is_sign_positive() {
let diff_alt = -(-&x + &y);
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
let diff_alt = -(-&x - -&y);
assert_eq!(
ComparableFloat(diff_alt.abs_negative_zero()),
ComparableFloat(diff.abs_negative_zero_ref())
);
}
let diff_alt =
add_rational_prec_round_naive(x.clone(), -&y, x.significant_bits(), Nearest).0;
assert_eq!(ComparableFloatRef(&diff_alt), ComparableFloatRef(&diff));
});
float_gen().test_properties(|x| {
assert_eq!(
ComparableFloatRef(&(&x - Rational::ZERO)),
ComparableFloatRef(&x)
);
assert_eq!(
ComparableFloatRef(&-(Rational::ZERO - &x)),
ComparableFloatRef(&x)
);
});
rational_gen().test_properties(|x| {
assert!((&x - Float::NAN).is_nan());
assert!((Float::NAN - &x).is_nan());
assert_eq!(&x - Float::INFINITY, Float::NEGATIVE_INFINITY);
assert_eq!(Float::INFINITY - &x, Float::INFINITY);
assert_eq!(&x - Float::NEGATIVE_INFINITY, Float::INFINITY);
assert_eq!(Float::NEGATIVE_INFINITY - &x, Float::NEGATIVE_INFINITY);
let diff_alt = Float::from_rational_prec_ref(&x, 1).0;
assert_eq!(
ComparableFloat((&x - Float::ZERO).abs_negative_zero()),
ComparableFloat(diff_alt.abs_negative_zero_ref())
);
assert_eq!(
ComparableFloat((Float::ZERO - &x).abs_negative_zero()),
ComparableFloat((-&diff_alt).abs_negative_zero())
);
assert_eq!(
ComparableFloat(&x - Float::NEGATIVE_ZERO),
ComparableFloat(diff_alt.clone())
);
assert_eq!(
ComparableFloat(Float::NEGATIVE_ZERO - &x),
ComparableFloat(-diff_alt)
);
});
}