// 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::{Ceiling, Floor};
use malachite_base::num::basic::integers::PrimitiveInt;
use malachite_base::num::basic::signeds::PrimitiveSigned;
use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, NegativeOne, OneHalf};
use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
use malachite_base::num::comparison::traits::PartialOrdAbs;
use malachite_base::num::conversion::from::{SignedFromFloatError, UnsignedFromFloatError};
use malachite_base::num::conversion::traits::{ConvertibleFrom, ExactFrom, RoundingFrom};
use malachite_base::rounding_modes::RoundingMode::{self, *};
use malachite_base::strings::ToDebugString;
use malachite_base::test_util::generators::{signed_gen, unsigned_gen};
use malachite_float::test_util::common::parse_hex_string;
use malachite_float::test_util::generators::{
float_gen, float_gen_var_4, float_gen_var_5, float_rounding_mode_pair_gen_var_4,
float_rounding_mode_pair_gen_var_5,
};
use malachite_float::Float;
use malachite_nz::integer::Integer;
use malachite_nz::natural::Natural;
use malachite_q::Rational;
use std::cmp::Ordering::{self, *};
use std::panic::catch_unwind;
#[allow(clippy::type_repetition_in_bounds)]
#[test]
fn test_try_from_float() {
fn test_helper_u>(
s: &str,
s_hex: &str,
out: &str,
) where
for<'a> T: TryFrom<&'a Float, Error = UnsignedFromFloatError>,
{
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let on = T::try_from(x.clone());
assert_eq!(on.to_debug_string(), out);
let on = T::try_from(&x);
assert_eq!(on.to_debug_string(), out);
}
fn test_helper_u2>()
where
for<'a> T: TryFrom<&'a Float, Error = UnsignedFromFloatError>,
{
test_helper_u::("NaN", "NaN", "Err(FloatInfiniteOrNan)");
test_helper_u::("Infinity", "Infinity", "Err(FloatInfiniteOrNan)");
test_helper_u::("-Infinity", "-Infinity", "Err(FloatInfiniteOrNan)");
test_helper_u::("0.0", "0x0.0", "Ok(0)");
test_helper_u::("-0.0", "-0x0.0", "Ok(0)");
test_helper_u::("1.0", "0x1.0#1", "Ok(1)");
test_helper_u::("2.0", "0x2.0#1", "Ok(2)");
test_helper_u::("0.5", "0x0.8#1", "Err(FloatNonIntegerOrOutOfRange)");
test_helper_u::(
"0.33333333333333331",
"0x0.55555555555554#53",
"Err(FloatNonIntegerOrOutOfRange)",
);
test_helper_u::("123.0", "0x7b.0#7", "Ok(123)");
test_helper_u::("-1.0", "-0x1.0#1", "Err(FloatNegative)");
test_helper_u::("-2.0", "-0x2.0#1", "Err(FloatNegative)");
test_helper_u::("-0.5", "-0x0.8#1", "Err(FloatNegative)");
test_helper_u::(
"-0.33333333333333331",
"-0x0.55555555555554#53",
"Err(FloatNegative)",
);
test_helper_u::("-123.0", "-0x7b.0#7", "Err(FloatNegative)");
test_helper_u::(
"-1000000000000.0",
"-0xe8d4a51000.0#40",
"Err(FloatNegative)",
);
}
apply_fn_to_unsigneds!(test_helper_u2);
test_helper_u::("1000000000000.0", "0xe8d4a51000.0#40", "Ok(1000000000000)");
fn test_helper_i>(
s: &str,
s_hex: &str,
out: &str,
) where
for<'a> T: TryFrom<&'a Float, Error = SignedFromFloatError>,
{
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let on = T::try_from(x.clone());
assert_eq!(on.to_debug_string(), out);
let on = T::try_from(&x);
assert_eq!(on.to_debug_string(), out);
}
fn test_helper_i2>()
where
for<'a> T: TryFrom<&'a Float, Error = SignedFromFloatError>,
{
test_helper_i::("NaN", "NaN", "Err(FloatInfiniteOrNan)");
test_helper_i::("Infinity", "Infinity", "Err(FloatInfiniteOrNan)");
test_helper_i::("-Infinity", "-Infinity", "Err(FloatInfiniteOrNan)");
test_helper_i::("0.0", "0x0.0", "Ok(0)");
test_helper_i::("-0.0", "-0x0.0", "Ok(0)");
test_helper_i::("1.0", "0x1.0#1", "Ok(1)");
test_helper_i::("2.0", "0x2.0#1", "Ok(2)");
test_helper_i::("0.5", "0x0.8#1", "Err(FloatNonIntegerOrOutOfRange)");
test_helper_i::(
"0.33333333333333331",
"0x0.55555555555554#53",
"Err(FloatNonIntegerOrOutOfRange)",
);
test_helper_i::("123.0", "0x7b.0#7", "Ok(123)");
test_helper_i::("-1.0", "-0x1.0#1", "Ok(-1)");
test_helper_i::("-2.0", "-0x2.0#1", "Ok(-2)");
test_helper_i::("-0.5", "-0x0.8#1", "Err(FloatNonIntegerOrOutOfRange)");
test_helper_i::(
"-0.33333333333333331",
"-0x0.55555555555554#53",
"Err(FloatNonIntegerOrOutOfRange)",
);
test_helper_i::("-123.0", "-0x7b.0#7", "Ok(-123)");
}
apply_fn_to_signeds!(test_helper_i2);
test_helper_i::("1000000000000.0", "0xe8d4a51000.0#40", "Ok(1000000000000)");
test_helper_i::(
"-1000000000000.0",
"-0xe8d4a51000.0#40",
"Ok(-1000000000000)",
);
}
#[test]
fn test_convertible_from_float() {
#[allow(clippy::type_repetition_in_bounds)]
fn test_helper(s: &str, s_hex: &str, out: bool)
where
for<'a> T: ConvertibleFrom<&'a Float>,
{
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
assert_eq!(T::convertible_from(&x), out);
}
#[allow(clippy::type_repetition_in_bounds)]
fn test_helper_u()
where
for<'a> T: ConvertibleFrom<&'a Float>,
{
test_helper::("NaN", "NaN", false);
test_helper::("Infinity", "Infinity", false);
test_helper::("-Infinity", "-Infinity", false);
test_helper::("0.0", "0x0.0", true);
test_helper::("-0.0", "-0x0.0", true);
test_helper::("1.0", "0x1.0#1", true);
test_helper::("2.0", "0x2.0#1", true);
test_helper::("0.5", "0x0.8#1", false);
test_helper::("0.33333333333333331", "0x0.55555555555554#53", false);
test_helper::("123.0", "0x7b.0#7", true);
test_helper::("-1.0", "-0x1.0#1", false);
test_helper::("-2.0", "-0x2.0#1", false);
test_helper::("-0.5", "-0x0.8#1", false);
test_helper::("-0.33333333333333331", "-0x0.55555555555554#53", false);
test_helper::("-123.0", "-0x7b.0#7", false);
test_helper::("-1000000000000.0", "-0xe8d4a51000.0#40", false);
}
apply_fn_to_unsigneds!(test_helper_u);
test_helper::("1000000000000.0", "0xe8d4a51000.0#40", true);
#[allow(clippy::type_repetition_in_bounds)]
fn test_helper_i()
where
for<'a> T: ConvertibleFrom<&'a Float>,
{
test_helper::("NaN", "NaN", false);
test_helper::("Infinity", "Infinity", false);
test_helper::("-Infinity", "-Infinity", false);
test_helper::("0.0", "0x0.0", true);
test_helper::("-0.0", "-0x0.0", true);
test_helper::("1.0", "0x1.0#1", true);
test_helper::("2.0", "0x2.0#1", true);
test_helper::("0.5", "0x0.8#1", false);
test_helper::("0.33333333333333331", "0x0.55555555555554#53", false);
test_helper::("123.0", "0x7b.0#7", true);
test_helper::("-1.0", "-0x1.0#1", true);
test_helper::("-2.0", "-0x2.0#1", true);
test_helper::("-0.5", "-0x0.8#1", false);
test_helper::("-0.33333333333333331", "-0x0.55555555555554#53", false);
test_helper::("-123.0", "-0x7b.0#7", true);
}
apply_fn_to_signeds!(test_helper_i);
test_helper::("1000000000000.0", "0xe8d4a51000.0#40", true);
test_helper::("-1000000000000.0", "-0xe8d4a51000.0#40", true);
}
#[test]
fn test_rounding_from_float() {
#[allow(clippy::type_repetition_in_bounds)]
fn test_helper>(
s: &str,
s_hex: &str,
rm: RoundingMode,
out: &str,
o_out: Ordering,
) where
for<'a> T: RoundingFrom<&'a Float>,
{
let x = parse_hex_string(s_hex);
assert_eq!(x.to_string(), s);
let (n, o) = T::rounding_from(x.clone(), rm);
assert_eq!(n.to_string(), out);
assert_eq!(o, o_out);
let (n, o) = T::rounding_from(&x, rm);
assert_eq!(n.to_string(), out);
assert_eq!(o, o_out);
}
#[allow(clippy::type_repetition_in_bounds)]
fn test_helper_u>()
where
for<'a> T: RoundingFrom<&'a Float>,
{
test_helper::("-Infinity", "-Infinity", Ceiling, "0", Greater);
test_helper::("-Infinity", "-Infinity", Down, "0", Greater);
test_helper::("-Infinity", "-Infinity", Nearest, "0", Greater);
test_helper::("0.0", "0x0.0", Floor, "0", Equal);
test_helper::("0.0", "0x0.0", Ceiling, "0", Equal);
test_helper::("0.0", "0x0.0", Down, "0", Equal);
test_helper::("0.0", "0x0.0", Up, "0", Equal);
test_helper::("0.0", "0x0.0", Nearest, "0", Equal);
test_helper::("0.0", "0x0.0", Exact, "0", Equal);
test_helper::("-0.0", "-0x0.0", Floor, "0", Equal);
test_helper::("-0.0", "-0x0.0", Ceiling, "0", Equal);
test_helper::("-0.0", "-0x0.0", Down, "0", Equal);
test_helper::("-0.0", "-0x0.0", Up, "0", Equal);
test_helper::("-0.0", "-0x0.0", Nearest, "0", Equal);
test_helper::("-0.0", "-0x0.0", Exact, "0", Equal);
test_helper::("1.0", "0x1.0#1", Floor, "1", Equal);
test_helper::("1.0", "0x1.0#1", Ceiling, "1", Equal);
test_helper::("1.0", "0x1.0#1", Down, "1", Equal);
test_helper::("1.0", "0x1.0#1", Up, "1", Equal);
test_helper::("1.0", "0x1.0#1", Nearest, "1", Equal);
test_helper::("1.0", "0x1.0#1", Exact, "1", Equal);
test_helper::("2.0", "0x2.0#1", Floor, "2", Equal);
test_helper::("2.0", "0x2.0#1", Ceiling, "2", Equal);
test_helper::("2.0", "0x2.0#1", Down, "2", Equal);
test_helper::("2.0", "0x2.0#1", Up, "2", Equal);
test_helper::("2.0", "0x2.0#1", Nearest, "2", Equal);
test_helper::("2.0", "0x2.0#1", Exact, "2", Equal);
test_helper::("0.5", "0x0.8#1", Floor, "0", Less);
test_helper::("0.5", "0x0.8#1", Ceiling, "1", Greater);
test_helper::("0.5", "0x0.8#1", Down, "0", Less);
test_helper::("0.5", "0x0.8#1", Up, "1", Greater);
test_helper::("0.5", "0x0.8#1", Nearest, "0", Less);
test_helper::(
"0.33333333333333331",
"0x0.55555555555554#53",
Floor,
"0",
Less,
);
test_helper::(
"0.33333333333333331",
"0x0.55555555555554#53",
Ceiling,
"1",
Greater,
);
test_helper::(
"0.33333333333333331",
"0x0.55555555555554#53",
Down,
"0",
Less,
);
test_helper::(
"0.33333333333333331",
"0x0.55555555555554#53",
Up,
"1",
Greater,
);
test_helper::(
"0.33333333333333331",
"0x0.55555555555554#53",
Nearest,
"0",
Less,
);
test_helper::(
"0.6666666666666666",
"0x0.aaaaaaaaaaaaa8#53",
Floor,
"0",
Less,
);
test_helper::(
"0.6666666666666666",
"0x0.aaaaaaaaaaaaa8#53",
Ceiling,
"1",
Greater,
);
test_helper::(
"0.6666666666666666",
"0x0.aaaaaaaaaaaaa8#53",
Down,
"0",
Less,
);
test_helper::(
"0.6666666666666666",
"0x0.aaaaaaaaaaaaa8#53",
Up,
"1",
Greater,
);
test_helper::(
"0.6666666666666666",
"0x0.aaaaaaaaaaaaa8#53",
Nearest,
"1",
Greater,
);
test_helper::("1.5", "0x1.8#2", Floor, "1", Less);
test_helper::("1.5", "0x1.8#2", Ceiling, "2", Greater);
test_helper::("1.5", "0x1.8#2", Down, "1", Less);
test_helper::("1.5", "0x1.8#2", Up, "2", Greater);
test_helper::("1.5", "0x1.8#2", Nearest, "2", Greater);
test_helper::("2.5", "0x2.8#3", Floor, "2", Less);
test_helper::("2.5", "0x2.8#3", Ceiling, "3", Greater);
test_helper::("2.5", "0x2.8#3", Down, "2", Less);
test_helper::("2.5", "0x2.8#3", Up, "3", Greater);
test_helper::("2.5", "0x2.8#3", Nearest, "2", Less);
test_helper::("123.0", "0x7b.0#7", Floor, "123", Equal);
test_helper::("123.0", "0x7b.0#7", Ceiling, "123", Equal);
test_helper::("123.0", "0x7b.0#7", Down, "123", Equal);
test_helper::("123.0", "0x7b.0#7", Up, "123", Equal);
test_helper::("123.0", "0x7b.0#7", Nearest, "123", Equal);
test_helper::("123.0", "0x7b.0#7", Exact, "123", Equal);
test_helper::("-1.0", "-0x1.0#1", Ceiling, "0", Greater);
test_helper::("-1.0", "-0x1.0#1", Down, "0", Greater);
test_helper::("-1.0", "-0x1.0#1", Nearest, "0", Greater);
test_helper::("-2.0", "-0x2.0#1", Ceiling, "0", Greater);
test_helper::("-2.0", "-0x2.0#1", Down, "0", Greater);
test_helper::("-2.0", "-0x2.0#1", Nearest, "0", Greater);
test_helper::("-0.5", "-0x0.8#1", Ceiling, "0", Greater);
test_helper::("-0.5", "-0x0.8#1", Down, "0", Greater);
test_helper::("-0.5", "-0x0.8#1", Nearest, "0", Greater);
test_helper::(
"-0.33333333333333331",
"-0x0.55555555555554#53",
Ceiling,
"0",
Greater,
);
test_helper::(
"-0.33333333333333331",
"-0x0.55555555555554#53",
Down,
"0",
Greater,
);
test_helper::(
"-0.33333333333333331",
"-0x0.55555555555554#53",
Nearest,
"0",
Greater,
);
test_helper::(
"-0.6666666666666666",
"-0x0.aaaaaaaaaaaaa8#53",
Ceiling,
"0",
Greater,
);
test_helper::(
"-0.6666666666666666",
"-0x0.aaaaaaaaaaaaa8#53",
Down,
"0",
Greater,
);
test_helper::(
"-0.6666666666666666",
"-0x0.aaaaaaaaaaaaa8#53",
Nearest,
"0",
Greater,
);
test_helper::("-1.5", "-0x1.8#2", Ceiling, "0", Greater);
test_helper::("-1.5", "-0x1.8#2", Down, "0", Greater);
test_helper::("-1.5", "-0x1.8#2", Nearest, "0", Greater);
test_helper::("-2.5", "-0x2.8#3", Ceiling, "0", Greater);
test_helper::("-2.5", "-0x2.8#3", Down, "0", Greater);
test_helper::("-2.5", "-0x2.8#3", Nearest, "0", Greater);
test_helper::("-123.0", "-0x7b.0#7", Ceiling, "0", Greater);
test_helper::("-123.0", "-0x7b.0#7", Down, "0", Greater);
test_helper::("-123.0", "-0x7b.0#7", Nearest, "0", Greater);
}
apply_fn_to_unsigneds!(test_helper_u);
#[allow(clippy::type_repetition_in_bounds)]
fn test_helper_i>()
where
for<'a> T: RoundingFrom<&'a Float>,
{
test_helper::("0.0", "0x0.0", Floor, "0", Equal);
test_helper::("0.0", "0x0.0", Ceiling, "0", Equal);
test_helper::("0.0", "0x0.0", Down, "0", Equal);
test_helper::("0.0", "0x0.0", Up, "0", Equal);
test_helper::("0.0", "0x0.0", Nearest, "0", Equal);
test_helper::("0.0", "0x0.0", Exact, "0", Equal);
test_helper::("-0.0", "-0x0.0", Floor, "0", Equal);
test_helper::("-0.0", "-0x0.0", Ceiling, "0", Equal);
test_helper::("-0.0", "-0x0.0", Down, "0", Equal);
test_helper::("-0.0", "-0x0.0", Up, "0", Equal);
test_helper::("-0.0", "-0x0.0", Nearest, "0", Equal);
test_helper::("-0.0", "-0x0.0", Exact, "0", Equal);
test_helper::("1.0", "0x1.0#1", Floor, "1", Equal);
test_helper::("1.0", "0x1.0#1", Ceiling, "1", Equal);
test_helper::("1.0", "0x1.0#1", Down, "1", Equal);
test_helper::("1.0", "0x1.0#1", Up, "1", Equal);
test_helper::("1.0", "0x1.0#1", Nearest, "1", Equal);
test_helper::("1.0", "0x1.0#1", Exact, "1", Equal);
test_helper::("2.0", "0x2.0#1", Floor, "2", Equal);
test_helper::("2.0", "0x2.0#1", Ceiling, "2", Equal);
test_helper::("2.0", "0x2.0#1", Down, "2", Equal);
test_helper::("2.0", "0x2.0#1", Up, "2", Equal);
test_helper::("2.0", "0x2.0#1", Nearest, "2", Equal);
test_helper::("2.0", "0x2.0#1", Exact, "2", Equal);
test_helper::("0.5", "0x0.8#1", Floor, "0", Less);
test_helper::("0.5", "0x0.8#1", Ceiling, "1", Greater);
test_helper::("0.5", "0x0.8#1", Down, "0", Less);
test_helper::("0.5", "0x0.8#1", Up, "1", Greater);
test_helper::("0.5", "0x0.8#1", Nearest, "0", Less);
test_helper::(
"0.33333333333333331",
"0x0.55555555555554#53",
Floor,
"0",
Less,
);
test_helper::(
"0.33333333333333331",
"0x0.55555555555554#53",
Ceiling,
"1",
Greater,
);
test_helper::(
"0.33333333333333331",
"0x0.55555555555554#53",
Down,
"0",
Less,
);
test_helper::(
"0.33333333333333331",
"0x0.55555555555554#53",
Up,
"1",
Greater,
);
test_helper::(
"0.33333333333333331",
"0x0.55555555555554#53",
Nearest,
"0",
Less,
);
test_helper::(
"0.6666666666666666",
"0x0.aaaaaaaaaaaaa8#53",
Floor,
"0",
Less,
);
test_helper::(
"0.6666666666666666",
"0x0.aaaaaaaaaaaaa8#53",
Ceiling,
"1",
Greater,
);
test_helper::(
"0.6666666666666666",
"0x0.aaaaaaaaaaaaa8#53",
Down,
"0",
Less,
);
test_helper::(
"0.6666666666666666",
"0x0.aaaaaaaaaaaaa8#53",
Up,
"1",
Greater,
);
test_helper::(
"0.6666666666666666",
"0x0.aaaaaaaaaaaaa8#53",
Nearest,
"1",
Greater,
);
test_helper::("1.5", "0x1.8#2", Floor, "1", Less);
test_helper::("1.5", "0x1.8#2", Ceiling, "2", Greater);
test_helper::("1.5", "0x1.8#2", Down, "1", Less);
test_helper::("1.5", "0x1.8#2", Up, "2", Greater);
test_helper::("1.5", "0x1.8#2", Nearest, "2", Greater);
test_helper::("2.5", "0x2.8#3", Floor, "2", Less);
test_helper::("2.5", "0x2.8#3", Ceiling, "3", Greater);
test_helper::("2.5", "0x2.8#3", Down, "2", Less);
test_helper::("2.5", "0x2.8#3", Up, "3", Greater);
test_helper::("2.5", "0x2.8#3", Nearest, "2", Less);
test_helper::("123.0", "0x7b.0#7", Floor, "123", Equal);
test_helper::("123.0", "0x7b.0#7", Ceiling, "123", Equal);
test_helper::("123.0", "0x7b.0#7", Down, "123", Equal);
test_helper::("123.0", "0x7b.0#7", Up, "123", Equal);
test_helper::("123.0", "0x7b.0#7", Nearest, "123", Equal);
test_helper::("123.0", "0x7b.0#7", Exact, "123", Equal);
test_helper::("-1.0", "-0x1.0#1", Floor, "-1", Equal);
test_helper::("-1.0", "-0x1.0#1", Ceiling, "-1", Equal);
test_helper::("-1.0", "-0x1.0#1", Down, "-1", Equal);
test_helper::("-1.0", "-0x1.0#1", Up, "-1", Equal);
test_helper::("-1.0", "-0x1.0#1", Nearest, "-1", Equal);
test_helper::("-1.0", "-0x1.0#1", Exact, "-1", Equal);
test_helper::("-2.0", "-0x2.0#1", Floor, "-2", Equal);
test_helper::("-2.0", "-0x2.0#1", Ceiling, "-2", Equal);
test_helper::("-2.0", "-0x2.0#1", Down, "-2", Equal);
test_helper::("-2.0", "-0x2.0#1", Up, "-2", Equal);
test_helper::("-2.0", "-0x2.0#1", Nearest, "-2", Equal);
test_helper::("-2.0", "-0x2.0#1", Exact, "-2", Equal);
test_helper::("-0.5", "-0x0.8#1", Floor, "-1", Less);
test_helper::("-0.5", "-0x0.8#1", Ceiling, "0", Greater);
test_helper::("-0.5", "-0x0.8#1", Down, "0", Greater);
test_helper::("-0.5", "-0x0.8#1", Up, "-1", Less);
test_helper::("-0.5", "-0x0.8#1", Nearest, "0", Greater);
test_helper::(
"-0.33333333333333331",
"-0x0.55555555555554#53",
Floor,
"-1",
Less,
);
test_helper::(
"-0.33333333333333331",
"-0x0.55555555555554#53",
Ceiling,
"0",
Greater,
);
test_helper::(
"-0.33333333333333331",
"-0x0.55555555555554#53",
Down,
"0",
Greater,
);
test_helper::(
"-0.33333333333333331",
"-0x0.55555555555554#53",
Up,
"-1",
Less,
);
test_helper::(
"-0.33333333333333331",
"-0x0.55555555555554#53",
Nearest,
"0",
Greater,
);
test_helper::(
"-0.6666666666666666",
"-0x0.aaaaaaaaaaaaa8#53",
Floor,
"-1",
Less,
);
test_helper::(
"-0.6666666666666666",
"-0x0.aaaaaaaaaaaaa8#53",
Ceiling,
"0",
Greater,
);
test_helper::(
"-0.6666666666666666",
"-0x0.aaaaaaaaaaaaa8#53",
Down,
"0",
Greater,
);
test_helper::(
"-0.6666666666666666",
"-0x0.aaaaaaaaaaaaa8#53",
Up,
"-1",
Less,
);
test_helper::(
"-0.6666666666666666",
"-0x0.aaaaaaaaaaaaa8#53",
Nearest,
"-1",
Less,
);
test_helper::("-1.5", "-0x1.8#2", Floor, "-2", Less);
test_helper::("-1.5", "-0x1.8#2", Ceiling, "-1", Greater);
test_helper::("-1.5", "-0x1.8#2", Down, "-1", Greater);
test_helper::("-1.5", "-0x1.8#2", Up, "-2", Less);
test_helper::("-1.5", "-0x1.8#2", Nearest, "-2", Less);
test_helper::("-2.5", "-0x2.8#3", Floor, "-3", Less);
test_helper::("-2.5", "-0x2.8#3", Ceiling, "-2", Greater);
test_helper::("-2.5", "-0x2.8#3", Down, "-2", Greater);
test_helper::("-2.5", "-0x2.8#3", Up, "-3", Less);
test_helper::("-2.5", "-0x2.8#3", Nearest, "-2", Greater);
test_helper::("-123.0", "-0x7b.0#7", Floor, "-123", Equal);
test_helper::("-123.0", "-0x7b.0#7", Ceiling, "-123", Equal);
test_helper::