// 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 core::cmp::Ordering::{self, *}; use malachite_base::num::arithmetic::traits::{NegAssign, Reciprocal, ReciprocalAssign}; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::traits::{ Infinity, NaN, NegativeInfinity, NegativeOne, NegativeZero, One, Zero, }; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::conversion::traits::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::common::GenConfig; use malachite_base::test_util::generators::{ primitive_float_gen, rounding_mode_gen, unsigned_gen_var_11, unsigned_rounding_mode_pair_gen_var_3, }; use malachite_float::test_util::arithmetic::reciprocal::{ reciprocal_prec_round_naive_1, reciprocal_prec_round_naive_2, rug_reciprocal, rug_reciprocal_prec, rug_reciprocal_prec_round, rug_reciprocal_round, }; use malachite_float::test_util::common::{ emulate_primitive_float_fn, parse_hex_string, rug_round_try_from_rounding_mode, to_hex_string, }; use malachite_float::test_util::generators::{ float_gen, float_gen_var_11, float_gen_var_6, float_gen_var_7, float_gen_var_8, float_rounding_mode_pair_gen_var_13, float_rounding_mode_pair_gen_var_14, float_rounding_mode_pair_gen_var_15, float_rounding_mode_pair_gen_var_16, float_rounding_mode_pair_gen_var_17, float_unsigned_pair_gen_var_1, float_unsigned_rounding_mode_triple_gen_var_3, }; use malachite_float::{ComparableFloat, ComparableFloatRef, Float}; use malachite_nz::platform::Limb; use malachite_q::Rational; use std::panic::catch_unwind; #[test] fn test_reciprocal() { let test = |s, s_hex, out: &str, out_hex: &str| { let x = parse_hex_string(s_hex); assert_eq!(x.to_string(), s); let reciprocal = x.clone().reciprocal(); assert!(reciprocal.is_valid()); assert_eq!(reciprocal.to_string(), out); assert_eq!(to_hex_string(&reciprocal), out_hex); let reciprocal_alt = (&x).reciprocal(); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal), ComparableFloatRef(&reciprocal_alt) ); let mut reciprocal_alt = x.clone(); reciprocal_alt.reciprocal_assign(); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal), ComparableFloatRef(&reciprocal_alt) ); let reciprocal_alt = reciprocal_prec_round_naive_1(x.clone(), x.significant_bits(), Nearest).0; assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); let reciprocal_alt = reciprocal_prec_round_naive_2(x.clone(), x.significant_bits(), Nearest).0; assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); let rug_reciprocal = rug_reciprocal(&rug::Float::exact_from(&x)); assert_eq!( ComparableFloatRef(&Float::from(&rug_reciprocal)), ComparableFloatRef(&reciprocal), ); }; test("NaN", "NaN", "NaN", "NaN"); test("Infinity", "Infinity", "0.0", "0x0.0"); test("-Infinity", "-Infinity", "-0.0", "-0x0.0"); test("0.0", "0x0.0", "Infinity", "Infinity"); test("-0.0", "-0x0.0", "-Infinity", "-Infinity"); test("1.0", "0x1.0#1", "1.0", "0x1.0#1"); test("-1.0", "-0x1.0#1", "-1.0", "-0x1.0#1"); test( "1.0", "0x1.0000000000000000000000000#100", "1.0", "0x1.0000000000000000000000000#100", ); test( "-1.0", "-0x1.0000000000000000000000000#100", "-1.0", "-0x1.0000000000000000000000000#100", ); test("123.0", "0x7b.0#7", "0.0082", "0x0.0218#7"); test("-123.0", "-0x7b.0#7", "-0.0082", "-0x0.0218#7"); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", "0.7071067811865475", "0x0.b504f333f9de60#53", ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", "-0.7071067811865475", "-0x0.b504f333f9de60#53", ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", "0.31830988618379069", "0x0.517cc1b727220c#53", ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", "-0.31830988618379069", "-0x0.517cc1b727220c#53", ); // - x.is_power_of_2() in reciprocal_prec_round // - !x.is_power_of_2() in reciprocal_prec_round // - in reciprocal_float_significand_same_prec_lt_w // - x != HIGH_BIT in reciprocal_float_significand_same_prec_lt_w // - (q + 2) & (mask >> 1) > 2 in reciprocal_float_significand_same_prec_lt_w; // - round_bit != 0 || sticky_bit != 0 in reciprocal_float_significand_same_prec_lt_w // - rm == Nearest in reciprocal_float_significand_same_prec_lt_w // - rm == Nearest && round_bit != 0 && (sticky_bit != 0 && reciprocal & shift_bit != 0) in // reciprocal_float_significand_same_prec_lt_w test("1.5", "0x1.8#2", "0.8", "0x0.c#2"); // - rm == Nearest && (round_bit == 0 || sticky_bit == 0 && reciprocal & shift_bit == 0) in // reciprocal_float_significand_same_prec_lt_w test("1.2", "0x1.4#3", "0.8", "0x0.c#3"); // - (q + 2) & (mask >> 1) <= 2 in reciprocal_float_significand_same_prec_lt_w // - hi == 0 && lo < x first time in reciprocal_float_significand_same_prec_lt_w // - hi == 0 && lo < x second time in reciprocal_float_significand_same_prec_lt_w test( "3615091.606162289805", "0x372973.9b2d73aac8#61", "2.7661816322867136e-7", "0x4.a410e30d72ea318E-6#61", ); // - in reciprocal_float_significand_same_prec_w // - x != HIGH_BIT in reciprocal_float_significand_same_prec_w // - hi == 0 && lo < x first time in reciprocal_float_significand_same_prec_w // - hi == 0 && lo < x second time in reciprocal_float_significand_same_prec_w // - !round_bit in reciprocal_float_significand_same_prec_w // - round_bit || sticky_bit != 0 in reciprocal_float_significand_same_prec_w // - rm == Exact in reciprocal_float_significand_same_prec_w // - rm == Exact && (!round_bit || sticky_bit == 0 && reciprocal.even()) in // reciprocal_float_significand_same_prec_w test( "1.0000000000000000001", "0x1.0000000000000002#64", "0.99999999999999999989", "0x0.fffffffffffffffe#64", ); // - round_bit in reciprocal_float_significand_same_prec_w // - rm == Exact && round_bit && (sticky_bit != 0 || reciprocal.even() in // reciprocal_float_significand_same_prec_w test( "0.113243462684988497952", "0x0.1cfd8608b7c32de2a#64", "8.830531814288645436", "0x8.d49dbba4a843592#64", ); // - in reciprocal_float_significand_same_prec_gt_w_lt_2w // - x_0 != 0 || x_1 != HIGH_BIT in reciprocal_float_significand_same_prec_gt_w_lt_2w // - in reciprocal_float_2_approx // - x_1 != Limb::MAX in reciprocal_float_2_approx // - yy == 0 in reciprocal_float_2_approx // - r_0 != 0 || yy == 0 in reciprocal_float_2_approx // - carry in reciprocal_float_2_approx // - r_1 == 0 in reciprocal_float_2_approx // - (q_0.wrapping_add(21)) & (mask >> 1) <= 21 in // reciprocal_float_significand_same_prec_gt_w_lt_2w // - s_1 != 0 || s_0 != 0 in reciprocal_float_significand_same_prec_gt_w_lt_2w // - s_2 > 0 || s_1 > x_1 || s_1 == x_1 && s_0 >= x_0 in // reciprocal_float_significand_same_prec_gt_w_lt_2w // - s_1 < x_1 || s_1 == x_1 && s_0 < x_0 in reciprocal_float_significand_same_prec_gt_w_lt_2w // - round_bit != 0 || sticky_bit != 0 in reciprocal_float_significand_same_prec_gt_w_lt_2w // - rm == Nearest in reciprocal_float_significand_same_prec_gt_w_lt_2w // - rm == Nearest && (round_bit == 0 || sticky_bit == 0 && z_0 & shift_bit == 0) in // reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.00000000000000000005", "0x1.0000000000000001#65", "0.99999999999999999995", "0x0.ffffffffffffffff0#65", ); // - r_1 != 0 in reciprocal_float_2_approx // - s_1 >= x_1 && (s_1 != x_1 || s_0 >= x_0) in // reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.00000000000000000011", "0x1.0000000000000002#65", "0.99999999999999999989", "0x0.fffffffffffffffe0#65", ); // - yy != 0 in reciprocal_float_2_approx test( "1.00000000000000000003", "0x1.00000000000000008#66", "0.99999999999999999997", "0x0.ffffffffffffffff8#66", ); // - (q_0.wrapping_add(21)) & (mask >> 1) > 21 in // reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.00000000000000000016", "0x1.0000000000000003#65", "0.99999999999999999984", "0x0.fffffffffffffffd0#65", ); // - rm != Nearest && round_bit != 0 && (sticky_bit != 0 || z_0 & shift_bit != 0) && !carry in // reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.44020837962004126031156726e28", "0x2.e891fdf020840728c0894E+23#85", "6.9434396726939059937558762e-29", "0x5.804bfffff864a7e6a3c7cE-24#85", ); // - s_2 <= 0 && s_1 <= x_1 && (s_1 != x_1 || s_0 < x_0) in // reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.1066650957130428898050817125418740852e-35", "0xe.b5c943322fb9cafab82fc881e3c1f4E-30#123", "90361574054676697026138186100092211.86", "0x11672b68e1cda153b96db5b555ad33.dc#123", ); // - x_1 == Limb::MAX in reciprocal_float_2_approx test( "4.9517601571415210995e27", "0xf.fffffffffffffff8E+22#65", "2.019483917365790222e-28", "0x1.0000000000000001E-23#65", ); // - !carry in reciprocal_float_2_approx test( "1.809457589959748038781206513903043742e-25", "0x3.800000000000000000000000000000E-21#121", "5526518032524019084371090.285714285714", "0x492492492492492492492.4924924924#121", ); // - s_1 == 0 && s_0 == 0 in reciprocal_float_significand_same_prec_gt_w_lt_2w test( "4095.75", "0xfff.c00000000000000000000000000#120", "0.0002441555270707440639687480925349447598", "0x0.001000400100040010004001000400100#120", ); // - in reciprocal_float_significand_general // - extra_bit in reciprocal_float_significand_general // - qs_len < MPFR_DIV_THRESHOLD || ds_len < MPFR_DIV_THRESHOLD in // reciprocal_float_significand_general // - rm != Nearest || shift != 0 in reciprocal_float_significand_general // - ds_len >= qs_2_len in reciprocal_float_significand_general // - qs_2_len == qs_len in reciprocal_float_significand_general // - sticky_bit != 0 || sticky_3 != 0 in reciprocal_float_significand_general // - ds_len <= qs_2_len in reciprocal_float_significand_general // - ds_len <= qs_2_len && rm == Nearest in reciprocal_float_significand_general // - cleanup == None in reciprocal_float_significand_general // - cleanup == None && rm == Nearest && (round_bit != 0 || sticky_bit != 0) in // reciprocal_float_significand_general // - cleanup == None && rm == Nearest && (round_bit != 0 || sticky_bit != 0) && round_bit == 0 // in reciprocal_float_significand_general test( "1.000000000000000000000000000000000000003", "0x1.00000000000000000000000000000001#129", "0.999999999999999999999999999999999999997", "0x0.ffffffffffffffffffffffffffffffff0#129", ); // - !extra_bit in reciprocal_float_significand_general test( "3.8524937267946719191140399538619613749184e-10", "0x1.a7960ee660129a7bc6beccda5d8bb012f0E-8#135", "2595721293.573692163399156109109436743137", "0x9ab7904d.92dd7d57c55752828aeb2a056a#135", ); // - cleanup == None && rm == Nearest && (round_bit != 0 || sticky_bit != 0) && round_bit != 0 // && sticky_bit == 0 in reciprocal_float_significand_general test( "59494692712728004820788608585666.4829798", "0x2eeedb85c9cdc503a8e25ed4fc2.7ba490#129", "1.680822195062896543011322450000404260061e-32", "0x5.745f58c91536fd9586859912d6b99220E-27#129", ); // - rm == Nearest && shift == 0 in reciprocal_float_significand_general // - ds_len < qs_2_len in reciprocal_float_significand_general // - qs_2_len != qs_len in reciprocal_float_significand_general test( "2.652265028059746721807174554033221706564e-11", "0x1.d29765de1f777af51db92558a3d9f542E-9#128", "37703622730.7776167463689706185944181549", "0x8c74fa04a.c711e41e7a061938aeb7ca7#128", ); // - qs_len >= MPFR_DIV_THRESHOLD && ds_len >= MPFR_DIV_THRESHOLD in // reciprocal_float_significand_general // - ds_len < n in reciprocal_float_significand_general // - !q_high first time in reciprocal_float_significand_general test( "99775868891207693182758620905617766484977359141657322302733467080906379945858675686059451\ 2527853476231275058799551652072546.7114971760702609364731573674336745185834760605451122614\ 680178551142556046183482705875960001033145321970465204907865385015751310573750415565593472\ 515573584122133946534420508845514863685042630834456885627933663697385547769664847990486584\ 336882273751721721644989648370590667737234950547668737865047573751482757356022197920174371\ 088074314780588737501583713833755004374512024407585163195094394292034507503368814534990168\ 9912721166210129145585", "0x1826427338bc8ee8c907c3ce5e6a2a793f6ba67df6e738f22dc8aee7eb1838ddc4290e49186e61bdbedb847\ d19c5d8c4bf88c62.b624adce6b0a3564827e04608c1aec0c8b10390491e15df75402c1788241935e791ebd5f4\ 25d73042c03e3bad5f0d11257d8bcdab6c8bae677785865be19fa4f42690ddb02174b09bb2c1c9ce6cf3dc2d80\ 9f0b0b79c42ae70f14ec682ac3850e91ee3b6ef02555e18758417024bf2e8801a759e710b3ac91f28b15277ff4\ f6380b7ba380aa56c032ce8db2107bfd99a9c789098467f2b27a7b3e1bb6a9e7804ef8a26a3baea51e9a8da4d5\ 02af09995fd6ced97b00#1859", "1.002246345847779005201453959044909523251487705121768272318254782834562788571992915761065\ 827618366102604676901058851697875789517863827988808181377939460972322574747531876040609995\ 972589309563651666694269954573404860608746408716939006674422401722850836821062009150256011\ 720454011696660779666788543360159960577274185817743487975811370456064842946971427355525804\ 257690941749159301402957505054859414089331855848531064209977516186532202351442372831975270\ 870077932986581025601789533966442159881772178301189187013534424007199259091978932352502557\ 2202453587766889671779e-123", "0xa.99c4846d5eeedd01292b3ecbfdcde3e23e86f2c0de91a7853e3f16d01225356463802a0309555fe6a982a\ b689ccb12d932eab55b6ffd61c4fdd7cd737afd36bd5acda69948c10851f5fd1a254537be41d4c013aa43aaa09\ 93fccd821acb36881a3a14540999fa35a76a34b052ec4c6e62c85b8890330ad74145c3af385378890639293f97\ 87eeb51c942fb1b0480f7e5dcadd2da6f8bbf05ac6e562e773bff36faf231658530929fef9e7c5b84843c5674a\ 883eede0deef889addd0d20f57f1eaeb61dfb8dd23ed0ba6dfc00929192924d8b397f3d5d4913b580d5176e47b\ 5900b7857bdc095ca14E-103#1859", ); // - r_0 == 0 && yy != 0 in reciprocal_float_2_approx test( "206158430208.00000000558794", "0x3000000000.000000180000#83", "4.850638409455617268748732e-12", "0x5.5555555555555552aaabE-10#83", ); } #[test] fn test_reciprocal_prec() { let test = |s, s_hex, prec: u64, out: &str, out_hex: &str, o_out: Ordering| { let x = parse_hex_string(s_hex); assert_eq!(x.to_string(), s); let (reciprocal, o) = x.clone().reciprocal_prec(prec); assert!(reciprocal.is_valid()); assert_eq!(reciprocal.to_string(), out); assert_eq!(to_hex_string(&reciprocal), out_hex); assert_eq!(o, o_out); let (reciprocal_alt, o_alt) = x.reciprocal_prec_ref(prec); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal), ComparableFloatRef(&reciprocal_alt) ); assert_eq!(o_alt, o_out); let mut reciprocal_alt = x.clone(); let o_alt = reciprocal_alt.reciprocal_prec_assign(prec); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal), ComparableFloatRef(&reciprocal_alt) ); assert_eq!(o_alt, o_out); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_1(x.clone(), prec, Nearest); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_2(x.clone(), prec, Nearest); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let (rug_reciprocal, rug_o) = rug_reciprocal_prec(&rug::Float::exact_from(&x), prec); assert_eq!( ComparableFloatRef(&Float::from(&rug_reciprocal)), ComparableFloatRef(&reciprocal), ); assert_eq!(rug_o, o); }; test("NaN", "NaN", 1, "NaN", "NaN", Equal); test("Infinity", "Infinity", 1, "0.0", "0x0.0", Equal); test("-Infinity", "-Infinity", 1, "-0.0", "-0x0.0", Equal); test("0.0", "0x0.0", 1, "Infinity", "Infinity", Equal); test("-0.0", "-0x0.0", 1, "-Infinity", "-Infinity", Equal); test("1.0", "0x1.0#1", 1, "1.0", "0x1.0#1", Equal); test("1.0", "0x1.0#1", 10, "1.0", "0x1.000#10", Equal); test("-1.0", "-0x1.0#1", 1, "-1.0", "-0x1.0#1", Equal); test("-1.0", "-0x1.0#1", 10, "-1.0", "-0x1.000#10", Equal); test( "1.0", "0x1.0000000000000000000000000#100", 1, "1.0", "0x1.0#1", Equal, ); test( "-1.0", "-0x1.0000000000000000000000000#100", 1, "-1.0", "-0x1.0#1", Equal, ); test("123.0", "0x7b.0#7", 1, "0.008", "0x0.02#1", Less); test("123.0", "0x7b.0#7", 10, "0.00813", "0x0.0215#10", Greater); test("-123.0", "-0x7b.0#7", 1, "-0.008", "-0x0.02#1", Greater); test("-123.0", "-0x7b.0#7", 10, "-0.00813", "-0x0.0215#10", Less); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 1, "0.5", "0x0.8#1", Less, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 10, "0.707", "0x0.b50#10", Less, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 1, "-0.5", "-0x0.8#1", Greater, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 10, "-0.707", "-0x0.b50#10", Greater, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 1, "0.2", "0x0.4#1", Less, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 10, "0.3184", "0x0.518#10", Greater, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 1, "-0.2", "-0x0.4#1", Greater, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 10, "-0.3184", "-0x0.518#10", Less, ); // yyy // - in reciprocal_float_significand_short // - in limbs_reciprocal_limb_to_out_mod_with_fraction // - fraction_len != 0 in limbs_reciprocal_limb_to_out_mod_with_fraction // - out_last == 0 in reciprocal_float_significand_short // - out_last == 0 && shift != 0 in reciprocal_float_significand_short // - round_bit == 0 && sticky_bit != 0 in reciprocal_float_significand_short // - rm == Nearest in reciprocal_float_significand_short // - rm == Nearest && (round_bit == 0 || sticky_bit == 0 && out[0] & shift_bit == 0) in // reciprocal_float_significand_short test("1.5", "0x1.8#2", 1, "0.5", "0x0.8#1", Less); // - rm == Nearest && round_bit != 0 && (sticky_bit != 0 || out[0] & shift_bit != 0) in // reciprocal_float_significand_short test("1.5", "0x1.8#2", 4, "0.7", "0x0.b#4", Greater); // - ds_len > qs_2_len in reciprocal_float_significand_general // - inex != Equal in reciprocal_float_significand_general // - ds_len > qs_2_len && rm == Nearest in reciprocal_float_significand_general // - sticky_3 > 1 in reciprocal_float_significand_general test( "0.000199046277632504184666664672269768242929310652018203552191617720205649", "0x0.000d0b7140b8f3aea60aad60c1dc3b2ee0d83e2eba33dcfb6f874df52d78#225", 26, "5023.9573", "0x139f.f510#26", Less, ); // - out_last == 0 && shift == 0 in reciprocal_float_significand_short // - out_last == 0 && shift == 0 && c >= y - c test( "1.4904942e-19", "0x2.bfddbE-16#22", 64, "6709184284559176977.0", "0x5d1bcf8f5dc87511.0#64", Greater, ); // - sticky_3 <= 1 in reciprocal_float_significand_general // - !q_high second time in reciprocal_float_significand_general // - !q_high_2 in reciprocal_float_significand_general // - cmp_s_r != Equal in reciprocal_float_significand_general // - cmp_s_r <= Equal first time in reciprocal_float_significand_general test( "13104.5238818416080254535", "0x3330.861d1ed0acba8a3a#77", 61, "0.00007630952555137529844", "0x0.00050042eaa75fe3e40#61", Less, ); // - cmp_s_r > Equal first time in reciprocal_float_significand_general // - cmp_s_r > Equal && !q_high_2 in reciprocal_float_significand_general // - cmp_s_r <= Equal second time in reciprocal_float_significand_general // - sticky_3 != 1 && round_bit != 0 in reciprocal_float_significand_general test( "4047252243163522937320069504914937843.384444039", "0x30b78f117589e437888c5573227d7f3.626aecb#150", 126, "2.47081214591743090926825573642415225879e-37", "0x5.413cf35bf8a6be7eed9713c3529cac4E-31#126", Less, ); // - out_last == 0 && shift == 0 && c < y - c in reciprocal_float_significand_short test( "0.252", "0x0.408#8", 64, "3.9689922480620155039", "0x3.f80fe03f80fe03f8#64", Less, ); // - sticky_3 != 1 && round_bit == 0 in reciprocal_float_significand_general // - cmp_s_r != Equal || shift != 0 in reciprocal_float_significand_general // - rm == Nearest || ((rm == Ceiling || rm == Up) && inex != Equal) in // reciprocal_float_significand_general // - cleanup == TruncateCheckQHigh in reciprocal_float_significand_general // - !q_high third time in reciprocal_float_significand_general test( "13486082141.77132281557478202754", "0x323d5485d.c575697b8d65625d0#99", 60, "7.41505197349076425e-11", "0x5.187840c7b7df518E-9#60", Greater, ); // - sticky_3 == 1 in reciprocal_float_significand_general test( "1.22280082196367917099634553e-19", "0x2.41738c7082eda42f40f3f0E-16#87", 62, "8177946743559704448.0", "0x717de73c11f04f80.0#62", Less, ); // - cmp_s_r > Equal second time in reciprocal_float_significand_general // - cmp_s_r > Equal && rm == Nearest in reciprocal_float_significand_general // - cmp_s_r > Equal && rm == Nearest && shift == 1 in reciprocal_float_significand_general // - cmp_s_r > Equal && rm == Nearest && shift == 1 && round_bit == 0 in // reciprocal_float_significand_general // - cleanup == Sub2Ulp in reciprocal_float_significand_general test( "18686733767405.50192797818236099916512095073138146049740456616", "0x10fed820d2ed.807e5a1b3d9ab71287cc373ef7f3521609fa72f#201", 63, "5.351389988464750895e-14", "0xf.1015372ed29c6daE-12#63", Less, ); // - cmp_s_r > Equal && rm == Nearest && shift == 1 && round_bit != 0 in // reciprocal_float_significand_general test( "5.1485428388978050057923204436e-7", "0x8.a348459137c894fe7ce2ce4E-6#94", 63, "1942297.1339480570737", "0x1da319.224a6b7c7e8#63", Greater, ); // - q_high second time in reciprocal_float_significand_general // - q_high third time in reciprocal_float_significand_general test( "77371252455336267181195267.98438", "0x4000000000000000000003.fc00#101", 21, "1.29247e-26", "0x4.00000E-22#21", Greater, ); // - cmp_s_r > Equal && rm == Nearest && shift != 1 in reciprocal_float_significand_general test( "2658455991647202407967140029027844095.999984793", "0x2000000003fffdfffffffffff7fffff.ffff00e#150", 126, "3.76158192252184441821673862447332945247e-37", "0x7.ffffffff000080001fffe0020400060E-31#126", Greater, ); // - cmp_s_r == Equal in reciprocal_float_significand_general // - !slice_test_zero(sp_lo) in reciprocal_float_significand_general test( "1.00000000000000000000000000000000000000000000035028", "0x1.00000000000000000000000000000000000001fff#165", 9, "1.0", "0x1.00#9", Greater, ); // - ds_len >= n in reciprocal_float_significand_general test( "0.055494458197186880675630915676192867532090892470422627386324587939238035948781984969197\ 293549419550977162311955781124943110956302191334821801709357381779895051695270613703928454\ 324596584327643817343816609304133584205767499993731432854297161698269943482406592768874444\ 537959922587924718339566077249075342435855861361805700477320039260219431275491192763683820\ 335274971653357747385666948482136785955293678142161982025522843889154198503897563042426395\ 128128925013857602497675148024154470366154782845358820106881972937537492453282371069714224\ 342987087633028783648188309716648625167308459669051113846104707695985727291553732092985376\ 828259777127224883258056131830095048084139109366273880047266946456087245977725112865710579\ 525111935320391211042996099454878241904334424644681645423208503968089041208566140555448097\ 852910157786980160921009881876094041863058139126904649967001982231878732430835123816538920\ 677999964668461960985136485079991108378659476109039768366016053541284627738754596865400997\ 112674267336505852768050602674774522669073467755292625683686148376948941511306559626232154\ 752250188007464931234370449669484827725942224651581822979291904312419637250173763557353262\ 213949126273235198961215664565140295983002285722717251104994492638175694612259962414559660\ 670986455111669460799863783422503680534332809871688740315758114042751185650495859242221856\ 676315059490112305738127164937772981750053994564437960009449100953381044642977719710987666\ 446442147625231494914221140350124646594870978197268779196749153799654193158076220975432784\ 285250458268961487489605062990550609833462756239703423977438296502233632161406744847227123\ 129345837972247611423244017961911382138681216321381679915794615975763676728759826413970576\ 860022980739678182223426387634227578298610034617798500806276338343012622846552838812662393\ 624312342667652111927682534015047744310614980669350777266223429538479188836406048087315918\ 309894499222120214872928367335411152843249721184424372084873571670196566303743654124450236\ 183156500319414376380635601282651645722305689309629762280330704861001884908133936528480642\ 756123234", "0x0.0e34e28310efa672de91bbf3447b991e67d8318cdf0c4058e4c9c730c71dc5b4bf675e849e3ac19fa3e70\ d9cbfb926620de7c9c66fc396364a70516bd66e253f5b318c8f82fabc4da09cab178fa55b2cd32603f085d4149\ a70fb07eb0959a5a78a00603aae495e7a094d9ee04b63747d7a023fb4369e5bf83efc20d6dfe31bafee72256df\ 1e39a8949cb554b519bb7b532f0ffb97b7fe5238cb68f0cfca74556fd7588422c7b383f4183a4193de48c69bae\ 7faf54820ec3c71871cbb288daf37266ee4f1fd3e40e483ed25f601b87f9c4a92b8cec5ec0e8d7edbd4234fba3\ 1a0a463a29b8f32d02f0d1f55195b2ec33db71548c7ccaf7e3a658ee71d308649653be586268e028c9f15d7788\ cbbd9d825fadf58d6f13183242c54015f254a271b4c89cfc1d82fc8c6182b0d0c620d53cf81728d495822994c6\ 63bb058d661f74be0ae8c8c10381afa72bc89a2a01da15a5f6d117b31e04e34a6e11e0aa8ad521b7a6117ce813\ b8e9326335c30e14052e4aa58c9062245ce2b058e7ca1221aa19af3c21653dac76aa59bb843a7a0ad8c6e22992\ 639766e47bfcc7de81f7a5a43e5faba0bd029002632b5d26d5a4303d9bbf4cf2664d57e50df98491d49ceb0f2f\ a1db2579ec23c459066023beebebd800fc879d76d59a3d6d2949650b07ef7b31e752ca051f4f107c7ff4af3f56\ 43eb287784ebcbcbefaa6a9496458e1b5afa0a74a27a47545d2f9091189f54f315a8bc904dedd3248f8cfbf32b\ 19df9037d47bd021b075b70aaa2087c30b755c65f93508e4564f2d998430e8f68565d451de80e317a96c18493e\ 662aa4f6ed98647d9051d9c993accc85820fe55a06d956025618ac1fbd020af906edd248ee088ee34f3ec8fc99\ 1e9392efafd1acd495d65fe834644d939ef5fa91d984969c79257afb98f8d94a3551a1a4b533c182b0d198d8a9\ 53e030b1532cd0e54117934099dd0b0027cd6058fb4190686ba78ded239aca8ac146e13f4c88052537903cb587\ 95eae03289ef10a0dee81bb143567c686a600364a57829437fc75160f8660a0ac48daacd98471fb2c0c490cd90\ 2cea0ea9aa3a814462dd78ab7d573f356b8c0ee7ac1f0c13819e3aeb5b2c8ea9f3a386bf90e5898fb38867db59\ a9e8ae436df1ececb24a9e478c52dd17ad020f761aca8761acb63eb70ac73687a85f5fc45a10ab7873104f3489\ 9df7961eaa91080cf7a#6892", 2006, "18.01981733827778674260325184800154550178488687484021553354418910902303106544992907597073\ 029189149288233180017138039419588169269797921955767649134253967949783482048904124978427680\ 356665076989426379081885511868423028921432842040598017121872298172949413285212017353511719\ 635837927429422415155120291649700552853758008370658383590920718577880818445566446372050296\ 508733341553853089827665379953621398768316388977766832203115700511569639084749508682625973\ 200934933860726967306493882349632958444320046459537281159643562613023877018494385007867594\ 9194217635032456311998703209522721567033904823795308705191538464412", "0x12.0512bfc3cbff370e13079bf70f24c8fc14fb1154aa0638c41252b425cfb276f04379cf0908b1732ae3ca\ 5d5ce2ef398eca257c87dfb650e9648bf8397dd443e42a5fd3663c3d58b9b6cd2a1ebf3c9246c45a1f6086158e\ a1e93d0f78945b71e8bdf265700c826de9776e648ce900159a0f4f2716ec326e2b8289920112637767e8fee268\ 3363b8e4c4bf07c685c226e6b97d260fdc2910d7e8a10fada9bda175aeb73def046bae399c664bfe3cfb3f7e73\ 136427cf5ca96cad226976adc2a9a0117dd38cbd0aaf5edbdb6a9e925126c38670a8946bc5ee1840200876c486\ de477d9c4b50e410143b115c27f9ba57c1176894c9d33effdbbd50928#2006", Less, ); // - q_high first time in reciprocal_float_significand_general // - !round_helper_2 in reciprocal_float_significand_general test( "3.725290298461914062500000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000011016237598729697344643067035553076048795855845749823769296583726265856513\ 808851994012395922156678620494270052333942368952051919368238891272218333e-9", "0x1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000003fffffffffffffffffffffffffffffffffffffffffffff\ ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeE-7#3520", 1969, "268435456.0", "0x10000000.000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 00000000000000000000000000000000000000000000000#1969", Greater, ); } #[test] fn reciprocal_prec_fail() { assert_panic!(Float::NAN.reciprocal_prec(0)); assert_panic!(Float::NAN.reciprocal_prec_ref(0)); assert_panic!({ let mut x = Float::NAN; x.reciprocal_prec_assign(0) }); } #[test] fn test_reciprocal_round() { let test = |s, s_hex, rm, out: &str, out_hex: &str, o_out| { let x = parse_hex_string(s_hex); assert_eq!(x.to_string(), s); let (reciprocal, o) = x.clone().reciprocal_round(rm); assert!(reciprocal.is_valid()); assert_eq!(reciprocal.to_string(), out); assert_eq!(to_hex_string(&reciprocal), out_hex); assert_eq!(o, o_out); let (reciprocal_alt, o_alt) = x.reciprocal_round_ref(rm); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal), ComparableFloatRef(&reciprocal_alt) ); assert_eq!(o_alt, o_out); let mut reciprocal_alt = x.clone(); let o_alt = reciprocal_alt.reciprocal_round_assign(rm); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal), ComparableFloatRef(&reciprocal_alt) ); assert_eq!(o_alt, o_out); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_1(x.clone(), x.significant_bits(), rm); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_2(x.clone(), x.significant_bits(), rm); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); if let Ok(rm) = rug_round_try_from_rounding_mode(rm) { let (rug_reciprocal, rug_o) = rug_reciprocal_round(&rug::Float::exact_from(&x), rm); assert_eq!( ComparableFloatRef(&Float::from(&rug_reciprocal)), ComparableFloatRef(&reciprocal), ); assert_eq!(rug_o, o); } }; test("NaN", "NaN", Floor, "NaN", "NaN", Equal); test("NaN", "NaN", Ceiling, "NaN", "NaN", Equal); test("NaN", "NaN", Down, "NaN", "NaN", Equal); test("NaN", "NaN", Up, "NaN", "NaN", Equal); test("NaN", "NaN", Nearest, "NaN", "NaN", Equal); test("NaN", "NaN", Exact, "NaN", "NaN", Equal); test("Infinity", "Infinity", Floor, "0.0", "0x0.0", Equal); test("Infinity", "Infinity", Ceiling, "0.0", "0x0.0", Equal); test("Infinity", "Infinity", Down, "0.0", "0x0.0", Equal); test("Infinity", "Infinity", Up, "0.0", "0x0.0", Equal); test("Infinity", "Infinity", Nearest, "0.0", "0x0.0", Equal); test("Infinity", "Infinity", Exact, "0.0", "0x0.0", Equal); test("-Infinity", "-Infinity", Floor, "-0.0", "-0x0.0", Equal); test("-Infinity", "-Infinity", Ceiling, "-0.0", "-0x0.0", Equal); test("-Infinity", "-Infinity", Down, "-0.0", "-0x0.0", Equal); test("-Infinity", "-Infinity", Up, "-0.0", "-0x0.0", Equal); test("-Infinity", "-Infinity", Nearest, "-0.0", "-0x0.0", Equal); test("-Infinity", "-Infinity", Exact, "-0.0", "-0x0.0", Equal); test("0.0", "0x0.0", Floor, "Infinity", "Infinity", Equal); test("0.0", "0x0.0", Ceiling, "Infinity", "Infinity", Equal); test("0.0", "0x0.0", Down, "Infinity", "Infinity", Equal); test("0.0", "0x0.0", Up, "Infinity", "Infinity", Equal); test("0.0", "0x0.0", Nearest, "Infinity", "Infinity", Equal); test("0.0", "0x0.0", Exact, "Infinity", "Infinity", Equal); test("-0.0", "-0x0.0", Floor, "-Infinity", "-Infinity", Equal); test("-0.0", "-0x0.0", Ceiling, "-Infinity", "-Infinity", Equal); test("-0.0", "-0x0.0", Down, "-Infinity", "-Infinity", Equal); test("-0.0", "-0x0.0", Up, "-Infinity", "-Infinity", Equal); test("-0.0", "-0x0.0", Nearest, "-Infinity", "-Infinity", Equal); test("-0.0", "-0x0.0", Exact, "-Infinity", "-Infinity", Equal); test("1.0", "0x1.0#1", Floor, "1.0", "0x1.0#1", Equal); test("1.0", "0x1.0#1", Ceiling, "1.0", "0x1.0#1", Equal); test("1.0", "0x1.0#1", Down, "1.0", "0x1.0#1", Equal); test("1.0", "0x1.0#1", Up, "1.0", "0x1.0#1", Equal); test("1.0", "0x1.0#1", Nearest, "1.0", "0x1.0#1", Equal); test("1.0", "0x1.0#1", Exact, "1.0", "0x1.0#1", Equal); test("-1.0", "-0x1.0#1", Floor, "-1.0", "-0x1.0#1", Equal); test("-1.0", "-0x1.0#1", Ceiling, "-1.0", "-0x1.0#1", Equal); test("-1.0", "-0x1.0#1", Down, "-1.0", "-0x1.0#1", Equal); test("-1.0", "-0x1.0#1", Up, "-1.0", "-0x1.0#1", Equal); test("-1.0", "-0x1.0#1", Nearest, "-1.0", "-0x1.0#1", Equal); test("-1.0", "-0x1.0#1", Exact, "-1.0", "-0x1.0#1", Equal); test( "1.0", "0x1.0000000000000000000000000#100", Floor, "1.0", "0x1.0000000000000000000000000#100", Equal, ); test( "1.0", "0x1.0000000000000000000000000#100", Ceiling, "1.0", "0x1.0000000000000000000000000#100", Equal, ); test( "1.0", "0x1.0000000000000000000000000#100", Down, "1.0", "0x1.0000000000000000000000000#100", Equal, ); test( "1.0", "0x1.0000000000000000000000000#100", Up, "1.0", "0x1.0000000000000000000000000#100", Equal, ); test( "1.0", "0x1.0000000000000000000000000#100", Nearest, "1.0", "0x1.0000000000000000000000000#100", Equal, ); test( "1.0", "0x1.0000000000000000000000000#100", Exact, "1.0", "0x1.0000000000000000000000000#100", Equal, ); test( "-1.0", "-0x1.0000000000000000000000000#100", Floor, "-1.0", "-0x1.0000000000000000000000000#100", Equal, ); test( "-1.0", "-0x1.0000000000000000000000000#100", Ceiling, "-1.0", "-0x1.0000000000000000000000000#100", Equal, ); test( "-1.0", "-0x1.0000000000000000000000000#100", Down, "-1.0", "-0x1.0000000000000000000000000#100", Equal, ); test( "-1.0", "-0x1.0000000000000000000000000#100", Up, "-1.0", "-0x1.0000000000000000000000000#100", Equal, ); test( "-1.0", "-0x1.0000000000000000000000000#100", Nearest, "-1.0", "-0x1.0000000000000000000000000#100", Equal, ); test( "-1.0", "-0x1.0000000000000000000000000#100", Exact, "-1.0", "-0x1.0000000000000000000000000#100", Equal, ); test("123.0", "0x7b.0#7", Floor, "0.0081", "0x0.0210#7", Less); test( "123.0", "0x7b.0#7", Ceiling, "0.0082", "0x0.0218#7", Greater, ); test("123.0", "0x7b.0#7", Down, "0.0081", "0x0.0210#7", Less); test("123.0", "0x7b.0#7", Up, "0.0082", "0x0.0218#7", Greater); test( "123.0", "0x7b.0#7", Nearest, "0.0082", "0x0.0218#7", Greater, ); test("-123.0", "-0x7b.0#7", Floor, "-0.0082", "-0x0.0218#7", Less); test( "-123.0", "-0x7b.0#7", Ceiling, "-0.0081", "-0x0.0210#7", Greater, ); test( "-123.0", "-0x7b.0#7", Down, "-0.0081", "-0x0.0210#7", Greater, ); test("-123.0", "-0x7b.0#7", Up, "-0.0082", "-0x0.0218#7", Less); test( "-123.0", "-0x7b.0#7", Nearest, "-0.0082", "-0x0.0218#7", Less, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", Floor, "0.7071067811865475", "0x0.b504f333f9de60#53", Less, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", Ceiling, "0.7071067811865476", "0x0.b504f333f9de68#53", Greater, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", Down, "0.7071067811865475", "0x0.b504f333f9de60#53", Less, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", Up, "0.7071067811865476", "0x0.b504f333f9de68#53", Greater, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", Nearest, "0.7071067811865475", "0x0.b504f333f9de60#53", Less, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", Floor, "-0.7071067811865476", "-0x0.b504f333f9de68#53", Less, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", Ceiling, "-0.7071067811865475", "-0x0.b504f333f9de60#53", Greater, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", Down, "-0.7071067811865475", "-0x0.b504f333f9de60#53", Greater, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", Up, "-0.7071067811865476", "-0x0.b504f333f9de68#53", Less, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", Nearest, "-0.7071067811865475", "-0x0.b504f333f9de60#53", Greater, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", Floor, "0.31830988618379064", "0x0.517cc1b7272208#53", Less, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", Ceiling, "0.31830988618379069", "0x0.517cc1b727220c#53", Greater, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", Down, "0.31830988618379064", "0x0.517cc1b7272208#53", Less, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", Up, "0.31830988618379069", "0x0.517cc1b727220c#53", Greater, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", Nearest, "0.31830988618379069", "0x0.517cc1b727220c#53", Greater, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", Floor, "-0.31830988618379069", "-0x0.517cc1b727220c#53", Less, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", Ceiling, "-0.31830988618379064", "-0x0.517cc1b7272208#53", Greater, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", Down, "-0.31830988618379064", "-0x0.517cc1b7272208#53", Greater, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", Up, "-0.31830988618379069", "-0x0.517cc1b727220c#53", Less, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", Nearest, "-0.31830988618379069", "-0x0.517cc1b727220c#53", Less, ); // yyy // - rm == Floor || rm == Down in reciprocal_float_significand_same_prec_lt_w test("1.5", "0x1.8#2", Down, "0.5", "0x0.8#2", Less); // - rm == Ceiling || rm == Up in reciprocal_float_significand_same_prec_lt_w test("1.5", "0x1.8#2", Up, "0.8", "0x0.c#2", Greater); // - rm == Floor || rm == Down in reciprocal_float_significand_same_prec_w test( "1.0000000000000000001", "0x1.0000000000000002#64", Down, "0.99999999999999999989", "0x0.fffffffffffffffe#64", Less, ); // - rm == Ceiling || rm == Up in reciprocal_float_significand_same_prec_w test( "1.0000000000000000001", "0x1.0000000000000002#64", Up, "0.99999999999999999995", "0x0.ffffffffffffffff#64", Greater, ); // - rm == Floor || rm == Down in reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.00000000000000000005", "0x1.0000000000000001#65", Down, "0.99999999999999999995", "0x0.ffffffffffffffff0#65", Less, ); // - rm == Ceiling || rm == Up in reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.00000000000000000005", "0x1.0000000000000001#65", Up, "0.99999999999999999997", "0x0.ffffffffffffffff8#65", Greater, ); // - ds_len <= qs_2_len && rm == Ceiling || rm == Up && inex != Equal in // reciprocal_float_significand_general // - cleanup == None && (rm == Ceiling || rm == Up) && (round_bit != 0 || sticky_bit != 0) in // reciprocal_float_significand_general test( "2.4914040842493675536005152793625253098043524808533216867315977e-8", "0x6.b014710df6d8d0fb1901206ed24e1e002b4411ac77d2348fd2E-7#202", Up, "40138009.17811728321982547739205337771132288200540084196230409", "0x2647519.2d9918224811b1eb5289a86e1aa22ec284493440dbd2#202", Greater, ); // - ds_len <= qs_2_len && rm == Floor || rm == Down || (rm != Nearest && inex == Equal) in // reciprocal_float_significand_general // - cleanup == None && (rm == Floor || rm == Down || round_bit == 0 && sticky_bit == 0) in // reciprocal_float_significand_general test( "2.4914040842493675536005152793625253098043524808533216867315977e-8", "0x6.b014710df6d8d0fb1901206ed24e1e002b4411ac77d2348fd2E-7#202", Down, "40138009.17811728321982547739205337771132288200540084196230408", "0x2647519.2d9918224811b1eb5289a86e1aa22ec284493440dbd1#202", Less, ); // - x.is_power_of_2() in reciprocal_prec_round // - !x.is_power_of_2() in reciprocal_prec_round // - in reciprocal_float_significand_same_prec_lt_w // - x != HIGH_BIT in reciprocal_float_significand_same_prec_lt_w // - (q + 2) & (mask >> 1) > 2 in reciprocal_float_significand_same_prec_lt_w; // - round_bit != 0 || sticky_bit != 0 in reciprocal_float_significand_same_prec_lt_w // - rm == Nearest in reciprocal_float_significand_same_prec_lt_w // - rm == Nearest && round_bit != 0 && (sticky_bit != 0 && reciprocal & shift_bit != 0) in // reciprocal_float_significand_same_prec_lt_w test("1.5", "0x1.8#2", Nearest, "0.8", "0x0.c#2", Greater); // - rm == Nearest && (round_bit == 0 || sticky_bit == 0 && reciprocal & shift_bit == 0) in // reciprocal_float_significand_same_prec_lt_w test("1.2", "0x1.4#3", Nearest, "0.8", "0x0.c#3", Less); // - (q + 2) & (mask >> 1) <= 2 in reciprocal_float_significand_same_prec_lt_w // - hi == 0 && lo < x first time in reciprocal_float_significand_same_prec_lt_w // - hi == 0 && lo < x second time in reciprocal_float_significand_same_prec_lt_w test( "3615091.606162289805", "0x372973.9b2d73aac8#61", Nearest, "2.7661816322867136e-7", "0x4.a410e30d72ea318E-6#61", Less, ); // - in reciprocal_float_significand_same_prec_w // - x != HIGH_BIT in reciprocal_float_significand_same_prec_w // - hi == 0 && lo < x first time in reciprocal_float_significand_same_prec_w // - hi == 0 && lo < x second time in reciprocal_float_significand_same_prec_w // - !round_bit in reciprocal_float_significand_same_prec_w // - round_bit || sticky_bit != 0 in reciprocal_float_significand_same_prec_w // - rm == Exact in reciprocal_float_significand_same_prec_w // - rm == Exact && (!round_bit || sticky_bit == 0 && reciprocal.even()) in // reciprocal_float_significand_same_prec_w test( "1.0000000000000000001", "0x1.0000000000000002#64", Nearest, "0.99999999999999999989", "0x0.fffffffffffffffe#64", Less, ); // - round_bit in reciprocal_float_significand_same_prec_w // - rm == Exact && round_bit && (sticky_bit != 0 || reciprocal.even() in // reciprocal_float_significand_same_prec_w test( "0.113243462684988497952", "0x0.1cfd8608b7c32de2a#64", Nearest, "8.830531814288645436", "0x8.d49dbba4a843592#64", Greater, ); // - in reciprocal_float_significand_same_prec_gt_w_lt_2w // - x_0 != 0 || x_1 != HIGH_BIT in reciprocal_float_significand_same_prec_gt_w_lt_2w // - in reciprocal_float_2_approx // - x_1 != Limb::MAX in reciprocal_float_2_approx // - yy == 0 in reciprocal_float_2_approx // - r_0 != 0 || yy == 0 in reciprocal_float_2_approx // - carry in reciprocal_float_2_approx // - r_1 == 0 in reciprocal_float_2_approx // - (q_0.wrapping_add(21)) & (mask >> 1) <= 21 in // reciprocal_float_significand_same_prec_gt_w_lt_2w // - s_1 != 0 || s_0 != 0 in reciprocal_float_significand_same_prec_gt_w_lt_2w // - s_2 > 0 || s_1 > x_1 || s_1 == x_1 && s_0 >= x_0 in // reciprocal_float_significand_same_prec_gt_w_lt_2w // - s_1 < x_1 || s_1 == x_1 && s_0 < x_0 in reciprocal_float_significand_same_prec_gt_w_lt_2w // - round_bit != 0 || sticky_bit != 0 in reciprocal_float_significand_same_prec_gt_w_lt_2w // - rm == Nearest in reciprocal_float_significand_same_prec_gt_w_lt_2w // - rm == Nearest && (round_bit == 0 || sticky_bit == 0 && z_0 & shift_bit == 0) in // reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.00000000000000000005", "0x1.0000000000000001#65", Nearest, "0.99999999999999999995", "0x0.ffffffffffffffff0#65", Less, ); // - r_1 != 0 in reciprocal_float_2_approx // - s_1 >= x_1 && (s_1 != x_1 || s_0 >= x_0) in // reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.00000000000000000011", "0x1.0000000000000002#65", Nearest, "0.99999999999999999989", "0x0.fffffffffffffffe0#65", Less, ); // - yy != 0 in reciprocal_float_2_approx test( "1.00000000000000000003", "0x1.00000000000000008#66", Nearest, "0.99999999999999999997", "0x0.ffffffffffffffff8#66", Less, ); // - (q_0.wrapping_add(21)) & (mask >> 1) > 21 in // reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.00000000000000000016", "0x1.0000000000000003#65", Nearest, "0.99999999999999999984", "0x0.fffffffffffffffd0#65", Less, ); // - rm != Nearest && round_bit != 0 && (sticky_bit != 0 || z_0 & shift_bit != 0) && !carry in // reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.44020837962004126031156726e28", "0x2.e891fdf020840728c0894E+23#85", Nearest, "6.9434396726939059937558762e-29", "0x5.804bfffff864a7e6a3c7cE-24#85", Greater, ); // - s_2 <= 0 && s_1 <= x_1 && (s_1 != x_1 || s_0 < x_0) in // reciprocal_float_significand_same_prec_gt_w_lt_2w test( "1.1066650957130428898050817125418740852e-35", "0xe.b5c943322fb9cafab82fc881e3c1f4E-30#123", Nearest, "90361574054676697026138186100092211.86", "0x11672b68e1cda153b96db5b555ad33.dc#123", Greater, ); // - x_1 == Limb::MAX in reciprocal_float_2_approx test( "4.9517601571415210995e27", "0xf.fffffffffffffff8E+22#65", Nearest, "2.019483917365790222e-28", "0x1.0000000000000001E-23#65", Greater, ); // - !carry in reciprocal_float_2_approx test( "1.809457589959748038781206513903043742e-25", "0x3.800000000000000000000000000000E-21#121", Nearest, "5526518032524019084371090.285714285714", "0x492492492492492492492.4924924924#121", Less, ); // - s_1 == 0 && s_0 == 0 in reciprocal_float_significand_same_prec_gt_w_lt_2w test( "4095.75", "0xfff.c00000000000000000000000000#120", Nearest, "0.0002441555270707440639687480925349447598", "0x0.001000400100040010004001000400100#120", Less, ); // - in reciprocal_float_significand_general // - extra_bit in reciprocal_float_significand_general // - qs_len < MPFR_DIV_THRESHOLD || ds_len < MPFR_DIV_THRESHOLD in // reciprocal_float_significand_general // - rm != Nearest || shift != 0 in reciprocal_float_significand_general // - ds_len >= qs_2_len in reciprocal_float_significand_general // - qs_2_len == qs_len in reciprocal_float_significand_general // - sticky_bit != 0 || sticky_3 != 0 in reciprocal_float_significand_general // - ds_len <= qs_2_len in reciprocal_float_significand_general // - ds_len <= qs_2_len && rm == Nearest in reciprocal_float_significand_general // - cleanup == None in reciprocal_float_significand_general // - cleanup == None && rm == Nearest && (round_bit != 0 || sticky_bit != 0) in // reciprocal_float_significand_general // - cleanup == None && rm == Nearest && (round_bit != 0 || sticky_bit != 0) && round_bit == 0 // in reciprocal_float_significand_general test( "1.000000000000000000000000000000000000003", "0x1.00000000000000000000000000000001#129", Nearest, "0.999999999999999999999999999999999999997", "0x0.ffffffffffffffffffffffffffffffff0#129", Less, ); // - !extra_bit in reciprocal_float_significand_general test( "3.8524937267946719191140399538619613749184e-10", "0x1.a7960ee660129a7bc6beccda5d8bb012f0E-8#135", Nearest, "2595721293.573692163399156109109436743137", "0x9ab7904d.92dd7d57c55752828aeb2a056a#135", Less, ); // - cleanup == None && rm == Nearest && (round_bit != 0 || sticky_bit != 0) && round_bit != 0 // && sticky_bit == 0 in reciprocal_float_significand_general test( "59494692712728004820788608585666.4829798", "0x2eeedb85c9cdc503a8e25ed4fc2.7ba490#129", Nearest, "1.680822195062896543011322450000404260061e-32", "0x5.745f58c91536fd9586859912d6b99220E-27#129", Greater, ); // - rm == Nearest && shift == 0 in reciprocal_float_significand_general // - ds_len < qs_2_len in reciprocal_float_significand_general // - qs_2_len != qs_len in reciprocal_float_significand_general test( "2.652265028059746721807174554033221706564e-11", "0x1.d29765de1f777af51db92558a3d9f542E-9#128", Nearest, "37703622730.7776167463689706185944181549", "0x8c74fa04a.c711e41e7a061938aeb7ca7#128", Greater, ); // - qs_len >= MPFR_DIV_THRESHOLD && ds_len >= MPFR_DIV_THRESHOLD in // reciprocal_float_significand_general // - ds_len < n in reciprocal_float_significand_general // - !q_high first time in reciprocal_float_significand_general test( "99775868891207693182758620905617766484977359141657322302733467080906379945858675686059451\ 2527853476231275058799551652072546.7114971760702609364731573674336745185834760605451122614\ 680178551142556046183482705875960001033145321970465204907865385015751310573750415565593472\ 515573584122133946534420508845514863685042630834456885627933663697385547769664847990486584\ 336882273751721721644989648370590667737234950547668737865047573751482757356022197920174371\ 088074314780588737501583713833755004374512024407585163195094394292034507503368814534990168\ 9912721166210129145585", "0x1826427338bc8ee8c907c3ce5e6a2a793f6ba67df6e738f22dc8aee7eb1838ddc4290e49186e61bdbedb847\ d19c5d8c4bf88c62.b624adce6b0a3564827e04608c1aec0c8b10390491e15df75402c1788241935e791ebd5f4\ 25d73042c03e3bad5f0d11257d8bcdab6c8bae677785865be19fa4f42690ddb02174b09bb2c1c9ce6cf3dc2d80\ 9f0b0b79c42ae70f14ec682ac3850e91ee3b6ef02555e18758417024bf2e8801a759e710b3ac91f28b15277ff4\ f6380b7ba380aa56c032ce8db2107bfd99a9c789098467f2b27a7b3e1bb6a9e7804ef8a26a3baea51e9a8da4d5\ 02af09995fd6ced97b00#1859", Nearest, "1.002246345847779005201453959044909523251487705121768272318254782834562788571992915761065\ 827618366102604676901058851697875789517863827988808181377939460972322574747531876040609995\ 972589309563651666694269954573404860608746408716939006674422401722850836821062009150256011\ 720454011696660779666788543360159960577274185817743487975811370456064842946971427355525804\ 257690941749159301402957505054859414089331855848531064209977516186532202351442372831975270\ 870077932986581025601789533966442159881772178301189187013534424007199259091978932352502557\ 2202453587766889671779e-123", "0xa.99c4846d5eeedd01292b3ecbfdcde3e23e86f2c0de91a7853e3f16d01225356463802a0309555fe6a982a\ b689ccb12d932eab55b6ffd61c4fdd7cd737afd36bd5acda69948c10851f5fd1a254537be41d4c013aa43aaa09\ 93fccd821acb36881a3a14540999fa35a76a34b052ec4c6e62c85b8890330ad74145c3af385378890639293f97\ 87eeb51c942fb1b0480f7e5dcadd2da6f8bbf05ac6e562e773bff36faf231658530929fef9e7c5b84843c5674a\ 883eede0deef889addd0d20f57f1eaeb61dfb8dd23ed0ba6dfc00929192924d8b397f3d5d4913b580d5176e47b\ 5900b7857bdc095ca14E-103#1859", Greater, ); // - r_0 == 0 && yy != 0 in reciprocal_float_2_approx test( "206158430208.00000000558794", "0x3000000000.000000180000#83", Nearest, "4.850638409455617268748732e-12", "0x5.5555555555555552aaabE-10#83", Greater, ); } #[test] fn reciprocal_round_fail() { const THREE: Float = Float::const_from_unsigned(3); assert_panic!(THREE.reciprocal_round(Exact)); assert_panic!(THREE.reciprocal_round_ref(Exact)); assert_panic!({ let mut x = THREE; x.reciprocal_round_assign(Exact); }); } #[test] fn test_reciprocal_prec_round() { let test = |s, s_hex, prec: u64, rm, out: &str, out_hex: &str, o_out: Ordering| { let x = parse_hex_string(s_hex); assert_eq!(x.to_string(), s); let (reciprocal, o) = x.clone().reciprocal_prec_round(prec, rm); assert!(reciprocal.is_valid()); assert_eq!(reciprocal.to_string(), out); assert_eq!(to_hex_string(&reciprocal), out_hex); assert_eq!(o, o_out); let (reciprocal_alt, o_alt) = x.reciprocal_prec_round_ref(prec, rm); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal), ComparableFloatRef(&reciprocal_alt) ); assert_eq!(o_alt, o_out); let mut reciprocal_alt = x.clone(); let o_alt = reciprocal_alt.reciprocal_prec_round_assign(prec, rm); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal), ComparableFloatRef(&reciprocal_alt) ); assert_eq!(o_alt, o_out); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_1(x.clone(), prec, rm); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_2(x.clone(), prec, rm); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); if let Ok(rm) = rug_round_try_from_rounding_mode(rm) { let (rug_reciprocal, rug_o) = rug_reciprocal_prec_round(&rug::Float::exact_from(&x), prec, rm); assert_eq!( ComparableFloatRef(&Float::from(&rug_reciprocal)), ComparableFloatRef(&reciprocal), ); assert_eq!(rug_o, o); } }; test("NaN", "NaN", 1, Floor, "NaN", "NaN", Equal); test("NaN", "NaN", 1, Ceiling, "NaN", "NaN", Equal); test("NaN", "NaN", 1, Down, "NaN", "NaN", Equal); test("NaN", "NaN", 1, Up, "NaN", "NaN", Equal); test("NaN", "NaN", 1, Nearest, "NaN", "NaN", Equal); test("NaN", "NaN", 1, Exact, "NaN", "NaN", Equal); test("Infinity", "Infinity", 1, Floor, "0.0", "0x0.0", Equal); test("Infinity", "Infinity", 1, Ceiling, "0.0", "0x0.0", Equal); test("Infinity", "Infinity", 1, Down, "0.0", "0x0.0", Equal); test("Infinity", "Infinity", 1, Up, "0.0", "0x0.0", Equal); test("Infinity", "Infinity", 1, Nearest, "0.0", "0x0.0", Equal); test("Infinity", "Infinity", 1, Exact, "0.0", "0x0.0", Equal); test("-Infinity", "-Infinity", 1, Floor, "-0.0", "-0x0.0", Equal); test( "-Infinity", "-Infinity", 1, Ceiling, "-0.0", "-0x0.0", Equal, ); test("-Infinity", "-Infinity", 1, Down, "-0.0", "-0x0.0", Equal); test("-Infinity", "-Infinity", 1, Up, "-0.0", "-0x0.0", Equal); test( "-Infinity", "-Infinity", 1, Nearest, "-0.0", "-0x0.0", Equal, ); test("-Infinity", "-Infinity", 1, Exact, "-0.0", "-0x0.0", Equal); test("0.0", "0x0.0", 1, Floor, "Infinity", "Infinity", Equal); test("0.0", "0x0.0", 1, Ceiling, "Infinity", "Infinity", Equal); test("0.0", "0x0.0", 1, Down, "Infinity", "Infinity", Equal); test("0.0", "0x0.0", 1, Up, "Infinity", "Infinity", Equal); test("0.0", "0x0.0", 1, Nearest, "Infinity", "Infinity", Equal); test("0.0", "0x0.0", 1, Exact, "Infinity", "Infinity", Equal); test("-0.0", "-0x0.0", 1, Floor, "-Infinity", "-Infinity", Equal); test( "-0.0", "-0x0.0", 1, Ceiling, "-Infinity", "-Infinity", Equal, ); test("-0.0", "-0x0.0", 1, Down, "-Infinity", "-Infinity", Equal); test("-0.0", "-0x0.0", 1, Up, "-Infinity", "-Infinity", Equal); test( "-0.0", "-0x0.0", 1, Nearest, "-Infinity", "-Infinity", Equal, ); test("-0.0", "-0x0.0", 1, Exact, "-Infinity", "-Infinity", Equal); test("1.0", "0x1.0#1", 1, Floor, "1.0", "0x1.0#1", Equal); test("1.0", "0x1.0#1", 1, Ceiling, "1.0", "0x1.0#1", Equal); test("1.0", "0x1.0#1", 1, Down, "1.0", "0x1.0#1", Equal); test("1.0", "0x1.0#1", 1, Up, "1.0", "0x1.0#1", Equal); test("1.0", "0x1.0#1", 1, Nearest, "1.0", "0x1.0#1", Equal); test("1.0", "0x1.0#1", 1, Exact, "1.0", "0x1.0#1", Equal); test("-1.0", "-0x1.0#1", 1, Floor, "-1.0", "-0x1.0#1", Equal); test("-1.0", "-0x1.0#1", 1, Ceiling, "-1.0", "-0x1.0#1", Equal); test("-1.0", "-0x1.0#1", 1, Down, "-1.0", "-0x1.0#1", Equal); test("-1.0", "-0x1.0#1", 1, Up, "-1.0", "-0x1.0#1", Equal); test("-1.0", "-0x1.0#1", 1, Nearest, "-1.0", "-0x1.0#1", Equal); test("-1.0", "-0x1.0#1", 1, Exact, "-1.0", "-0x1.0#1", Equal); test("1.0", "0x1.0#1", 10, Floor, "1.0", "0x1.000#10", Equal); test("1.0", "0x1.0#1", 10, Ceiling, "1.0", "0x1.000#10", Equal); test("1.0", "0x1.0#1", 10, Down, "1.0", "0x1.000#10", Equal); test("1.0", "0x1.0#1", 10, Up, "1.0", "0x1.000#10", Equal); test("1.0", "0x1.0#1", 10, Nearest, "1.0", "0x1.000#10", Equal); test("1.0", "0x1.0#1", 10, Exact, "1.0", "0x1.000#10", Equal); test("-1.0", "-0x1.0#1", 10, Floor, "-1.0", "-0x1.000#10", Equal); test( "-1.0", "-0x1.0#1", 10, Ceiling, "-1.0", "-0x1.000#10", Equal, ); test("-1.0", "-0x1.0#1", 10, Down, "-1.0", "-0x1.000#10", Equal); test("-1.0", "-0x1.0#1", 10, Up, "-1.0", "-0x1.000#10", Equal); test( "-1.0", "-0x1.0#1", 10, Nearest, "-1.0", "-0x1.000#10", Equal, ); test("-1.0", "-0x1.0#1", 10, Exact, "-1.0", "-0x1.000#10", Equal); test("123.0", "0x7b.0#7", 1, Floor, "0.008", "0x0.02#1", Less); test("123.0", "0x7b.0#7", 1, Ceiling, "0.02", "0x0.04#1", Greater); test("123.0", "0x7b.0#7", 1, Down, "0.008", "0x0.02#1", Less); test("123.0", "0x7b.0#7", 1, Up, "0.02", "0x0.04#1", Greater); test("123.0", "0x7b.0#7", 1, Nearest, "0.008", "0x0.02#1", Less); test("-123.0", "-0x7b.0#7", 1, Floor, "-0.02", "-0x0.04#1", Less); test( "-123.0", "-0x7b.0#7", 1, Ceiling, "-0.008", "-0x0.02#1", Greater, ); test( "-123.0", "-0x7b.0#7", 1, Down, "-0.008", "-0x0.02#1", Greater, ); test("-123.0", "-0x7b.0#7", 1, Up, "-0.02", "-0x0.04#1", Less); test( "-123.0", "-0x7b.0#7", 1, Nearest, "-0.008", "-0x0.02#1", Greater, ); test( "123.0", "0x7b.0#7", 10, Floor, "0.00812", "0x0.0214#10", Less, ); test( "123.0", "0x7b.0#7", 10, Ceiling, "0.00813", "0x0.0215#10", Greater, ); test( "123.0", "0x7b.0#7", 10, Down, "0.00812", "0x0.0214#10", Less, ); test( "123.0", "0x7b.0#7", 10, Up, "0.00813", "0x0.0215#10", Greater, ); test( "123.0", "0x7b.0#7", 10, Nearest, "0.00813", "0x0.0215#10", Greater, ); test( "-123.0", "-0x7b.0#7", 10, Floor, "-0.00813", "-0x0.0215#10", Less, ); test( "-123.0", "-0x7b.0#7", 10, Ceiling, "-0.00812", "-0x0.0214#10", Greater, ); test( "-123.0", "-0x7b.0#7", 10, Down, "-0.00812", "-0x0.0214#10", Greater, ); test( "-123.0", "-0x7b.0#7", 10, Up, "-0.00813", "-0x0.0215#10", Less, ); test( "-123.0", "-0x7b.0#7", 10, Nearest, "-0.00813", "-0x0.0215#10", Less, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 1, Floor, "0.5", "0x0.8#1", Less, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 1, Ceiling, "1.0", "0x1.0#1", Greater, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 1, Down, "0.5", "0x0.8#1", Less, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 1, Up, "1.0", "0x1.0#1", Greater, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 1, Nearest, "0.5", "0x0.8#1", Less, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 1, Floor, "-1.0", "-0x1.0#1", Less, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 1, Ceiling, "-0.5", "-0x0.8#1", Greater, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 1, Down, "-0.5", "-0x0.8#1", Greater, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 1, Up, "-1.0", "-0x1.0#1", Less, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 1, Nearest, "-0.5", "-0x0.8#1", Greater, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 10, Floor, "0.707", "0x0.b50#10", Less, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 10, Ceiling, "0.708", "0x0.b54#10", Greater, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 10, Down, "0.707", "0x0.b50#10", Less, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 10, Up, "0.708", "0x0.b54#10", Greater, ); test( "1.4142135623730951", "0x1.6a09e667f3bcd#53", 10, Nearest, "0.707", "0x0.b50#10", Less, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 10, Floor, "-0.708", "-0x0.b54#10", Less, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 10, Ceiling, "-0.707", "-0x0.b50#10", Greater, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 10, Down, "-0.707", "-0x0.b50#10", Greater, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 10, Up, "-0.708", "-0x0.b54#10", Less, ); test( "-1.4142135623730951", "-0x1.6a09e667f3bcd#53", 10, Nearest, "-0.707", "-0x0.b50#10", Greater, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 1, Floor, "0.2", "0x0.4#1", Less, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 1, Ceiling, "0.5", "0x0.8#1", Greater, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 1, Down, "0.2", "0x0.4#1", Less, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 1, Up, "0.5", "0x0.8#1", Greater, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 1, Nearest, "0.2", "0x0.4#1", Less, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 1, Floor, "-0.5", "-0x0.8#1", Less, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 1, Ceiling, "-0.2", "-0x0.4#1", Greater, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 1, Down, "-0.2", "-0x0.4#1", Greater, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 1, Up, "-0.5", "-0x0.8#1", Less, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 1, Nearest, "-0.2", "-0x0.4#1", Greater, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 10, Floor, "0.3179", "0x0.516#10", Less, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 10, Ceiling, "0.3184", "0x0.518#10", Greater, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 10, Down, "0.3179", "0x0.516#10", Less, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 10, Up, "0.3184", "0x0.518#10", Greater, ); test( "3.1415926535897931", "0x3.243f6a8885a30#53", 10, Nearest, "0.3184", "0x0.518#10", Greater, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 10, Floor, "-0.3184", "-0x0.518#10", Less, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 10, Ceiling, "-0.3179", "-0x0.516#10", Greater, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 10, Down, "-0.3179", "-0x0.516#10", Greater, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 10, Up, "-0.3184", "-0x0.518#10", Less, ); test( "-3.1415926535897931", "-0x3.243f6a8885a30#53", 10, Nearest, "-0.3184", "-0x0.518#10", Less, ); // yyy // - rm == Floor || rm == Down in reciprocal_float_significand_short test("1.5", "0x1.8#2", 1, Down, "0.5", "0x0.8#1", Less); // - rm == Ceiling || rm == Up in reciprocal_float_significand_short test("1.5", "0x1.8#2", 1, Up, "1.0", "0x1.0#1", Greater); // - ds_len > qs_2_len && rm != Nearest in reciprocal_float_significand_general test( "2.4914040842493675536005152793625253098043524808533216867315977e-8", "0x6.b014710df6d8d0fb1901206ed24e1e002b4411ac77d2348fd2E-7#202", 15, Up, "4.0139e7", "0x2.6478E+6#15", Greater, ); // - rm != Nearest && (rm != Ceiling && rm != Up || inex == Equal) && (rm != Exact || inex != // Equal) in reciprocal_float_significand_general // - cleanup == Sub1Ulp in reciprocal_float_significand_general test( "1164607425.036820041559", "0x456a7fc1.096d09ca55#71", 64, Down, "8.586584444697183348e-10", "0x3.b01add9bdcc8ca28E-8#64", Less, ); // - cmp_s_r > Equal && (rm == Ceiling || rm == Up) in reciprocal_float_significand_general // - cmp_s_r > Equal && (rm == Ceiling || rm == Up) && shift != 0 in // reciprocal_float_significand_general test( "18686733767405.50192797818236099916512095073138146049740456616", "0x10fed820d2ed.807e5a1b3d9ab71287cc373ef7f3521609fa72f#201", 63, Up, "5.3513899884647508956e-14", "0xf.1015372ed29c6dcE-12#63", Greater, ); // - cmp_s_r > Equal && (rm == Floor || rm == Down) in reciprocal_float_significand_general // - cmp_s_r > Equal && (rm == Floor || rm == Down) && shift != 0 in // reciprocal_float_significand_general test( "18686733767405.50192797818236099916512095073138146049740456616", "0x10fed820d2ed.807e5a1b3d9ab71287cc373ef7f3521609fa72f#201", 63, Down, "5.351389988464750895e-14", "0xf.1015372ed29c6daE-12#63", Less, ); // - cmp_s_r > Equal && (rm == Ceiling || rm == Up) && shift == 0 in // reciprocal_float_significand_general test( "1.063382396643406948814112e37", "0x8.000000007ffffffffff8E+30#81", 64, Up, "9.4039548064414545111e-38", "0x1.ffffffffe0000002E-31#64", Greater, ); // - cmp_s_r > Equal && (rm == Floor || rm == Down) && shift == 0 in // reciprocal_float_significand_general test( "1.063382396643406948814112e37", "0x8.000000007ffffffffff8E+30#81", 64, Down, "9.4039548064414545106e-38", "0x1.ffffffffe0000000E-31#64", Less, ); } #[test] fn reciprocal_prec_round_fail() { const THREE: Float = Float::const_from_unsigned(3); assert_panic!(Float::one_prec(1).reciprocal_prec_round(0, Floor)); assert_panic!(Float::one_prec(1).reciprocal_prec_round_ref(0, Floor)); assert_panic!({ let mut x = Float::one_prec(1); x.reciprocal_prec_round_assign(0, Floor) }); assert_panic!(THREE.reciprocal_prec_round(1, Exact)); assert_panic!(THREE.reciprocal_prec_round_ref(1, Exact)); assert_panic!({ let mut x = THREE; x.reciprocal_prec_round_assign(1, Exact) }); } #[allow(clippy::needless_pass_by_value)] fn reciprocal_prec_round_properties_helper(x: Float, prec: u64, rm: RoundingMode) { let (reciprocal, o) = x.clone().reciprocal_prec_round(prec, rm); assert!(reciprocal.is_valid()); let (reciprocal_alt, o_alt) = x.reciprocal_prec_round_ref(prec, rm); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let mut x_alt = x.clone(); let o_alt = x_alt.reciprocal_prec_round_assign(prec, rm); assert!(x_alt.is_valid()); assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&reciprocal)); assert_eq!(o_alt, o); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_1(x.clone(), prec, rm); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_2(x.clone(), prec, rm); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); if let Ok(rm) = rug_round_try_from_rounding_mode(rm) { let (rug_reciprocal, rug_o) = rug_reciprocal_prec_round(&rug::Float::exact_from(&x), prec, rm); assert_eq!( ComparableFloatRef(&Float::from(&rug_reciprocal)), ComparableFloatRef(&reciprocal), ); assert_eq!(rug_o, o); } if o == Equal && reciprocal.is_finite() && reciprocal != 0 { assert_eq!( ComparableFloatRef( &reciprocal .reciprocal_prec_round_ref(x.significant_bits(), Exact) .0 ), ComparableFloatRef(&x) ); } let (reciprocal_alt, o_alt) = Float::ONE.div_prec_round(x.clone(), prec, rm); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let r_reciprocal = if reciprocal.is_finite() && x.is_finite() { if reciprocal.is_normal() { assert_eq!(reciprocal.get_prec(), Some(prec)); } let r_reciprocal = Rational::exact_from(&x).reciprocal(); assert_eq!(reciprocal.partial_cmp(&r_reciprocal), Some(o)); if o == Less { let mut next = reciprocal.clone(); next.increment(); assert!(next > r_reciprocal); } else if o == Greater { let mut next = reciprocal.clone(); next.decrement(); assert!(next < r_reciprocal); } Some(r_reciprocal) } else { assert_eq!(o, Equal); None }; match ( r_reciprocal.is_some() && *r_reciprocal.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 reciprocal_alt, mut o_alt) = (-&x).reciprocal_prec_round(prec, -rm); reciprocal_alt.neg_assign(); o_alt = o_alt.reverse(); assert_eq!( ComparableFloat(reciprocal_alt.abs_negative_zero()), ComparableFloat(reciprocal.abs_negative_zero_ref()) ); assert_eq!(o_alt, o); if o == Equal { for rm in exhaustive_rounding_modes() { let (s, oo) = x.reciprocal_prec_round_ref(prec, rm); assert_eq!( ComparableFloat(s.abs_negative_zero_ref()), ComparableFloat(reciprocal.abs_negative_zero_ref()) ); assert_eq!(oo, Equal); } } else { assert_panic!(x.reciprocal_prec_round_ref(prec, Exact)); } } #[test] fn reciprocal_prec_round_properties() { float_unsigned_rounding_mode_triple_gen_var_3().test_properties(|(x, prec, rm)| { reciprocal_prec_round_properties_helper(x, prec, rm); }); let mut config = GenConfig::new(); config.insert("mean_precision_n", 2048); config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH); float_unsigned_rounding_mode_triple_gen_var_3().test_properties_with_config( &config, |(x, prec, rm)| { reciprocal_prec_round_properties_helper(x, prec, rm); }, ); let mut config = GenConfig::new(); config.insert("mean_precision_n", 2048); config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH); config.insert("mean_small_n", 2048); float_unsigned_rounding_mode_triple_gen_var_3().test_properties_with_config( &config, |(x, prec, rm)| { reciprocal_prec_round_properties_helper(x, prec, rm); }, ); unsigned_rounding_mode_pair_gen_var_3().test_properties(|(prec, rm)| { let (reciprocal, o) = Float::NAN.reciprocal_prec_round(prec, rm); assert!(reciprocal.is_nan()); assert_eq!(o, Equal); assert_eq!( Float::INFINITY.reciprocal_prec_round(prec, rm), (Float::ZERO, Equal) ); assert_eq!( Float::NEGATIVE_INFINITY.reciprocal_prec_round(prec, rm), (Float::NEGATIVE_ZERO, Equal) ); assert_eq!( Float::ZERO.reciprocal_prec_round(prec, rm), (Float::INFINITY, Equal) ); assert_eq!( Float::NEGATIVE_ZERO.reciprocal_prec_round(prec, rm), (Float::NEGATIVE_INFINITY, Equal) ); assert_eq!( Float::ONE.reciprocal_prec_round(prec, rm), (Float::one_prec(prec), Equal) ); assert_eq!( Float::NEGATIVE_ONE.reciprocal_prec_round(prec, rm), (Float::negative_one_prec(prec), Equal) ); }); } #[allow(clippy::needless_pass_by_value)] fn reciprocal_prec_properties_helper(x: Float, prec: u64) { let (reciprocal, o) = x.clone().reciprocal_prec(prec); assert!(reciprocal.is_valid()); let (reciprocal_alt, o_alt) = x.reciprocal_prec_ref(prec); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let mut x_alt = x.clone(); let o_alt = x_alt.reciprocal_prec_assign(prec); assert!(x_alt.is_valid()); assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&reciprocal)); assert_eq!(o_alt, o); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_1(x.clone(), prec, Nearest); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_2(x.clone(), prec, Nearest); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let (rug_reciprocal, rug_o) = rug_reciprocal_prec(&rug::Float::exact_from(&x), prec); assert_eq!( ComparableFloatRef(&Float::from(&rug_reciprocal)), ComparableFloatRef(&reciprocal), ); assert_eq!(rug_o, o); let (reciprocal_alt, o_alt) = Float::ONE.div_prec(x.clone(), prec); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); if reciprocal.is_finite() && x.is_finite() { if reciprocal.is_normal() { assert_eq!(reciprocal.get_prec(), Some(prec)); } let r_reciprocal = Rational::exact_from(&x).reciprocal(); assert_eq!(reciprocal.partial_cmp(&r_reciprocal), Some(o)); if o == Less { let mut next = reciprocal.clone(); next.increment(); assert!(next > r_reciprocal); } else if o == Greater { let mut next = reciprocal.clone(); next.decrement(); assert!(next < r_reciprocal); } } else { assert_eq!(o, Equal); }; let (mut reciprocal_alt, mut o_alt) = (-&x).reciprocal_prec(prec); reciprocal_alt.neg_assign(); o_alt = o_alt.reverse(); assert_eq!( ComparableFloat(reciprocal_alt.abs_negative_zero()), ComparableFloat(reciprocal.abs_negative_zero_ref()) ); assert_eq!(o_alt, o); } #[test] fn reciprocal_prec_properties() { float_unsigned_pair_gen_var_1().test_properties(|(x, prec)| { reciprocal_prec_properties_helper(x, prec); }); let mut config = GenConfig::new(); config.insert("mean_precision_n", 2048); config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH); float_unsigned_pair_gen_var_1().test_properties_with_config(&config, |(x, prec)| { reciprocal_prec_properties_helper(x, prec); }); let mut config = GenConfig::new(); config.insert("mean_precision_n", 2048); config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH); config.insert("mean_small_n", 2048); float_unsigned_pair_gen_var_1().test_properties_with_config(&config, |(x, prec)| { reciprocal_prec_properties_helper(x, prec); }); unsigned_gen_var_11().test_properties(|prec| { let (reciprocal, o) = Float::NAN.reciprocal_prec(prec); assert!(reciprocal.is_nan()); assert_eq!(o, Equal); assert_eq!(Float::INFINITY.reciprocal_prec(prec), (Float::ZERO, Equal)); assert_eq!( Float::NEGATIVE_INFINITY.reciprocal_prec(prec), (Float::NEGATIVE_ZERO, Equal) ); assert_eq!(Float::ZERO.reciprocal_prec(prec), (Float::INFINITY, Equal)); assert_eq!( Float::NEGATIVE_ZERO.reciprocal_prec(prec), (Float::NEGATIVE_INFINITY, Equal) ); assert_eq!( Float::ONE.reciprocal_prec(prec), (Float::one_prec(prec), Equal) ); assert_eq!( Float::NEGATIVE_ONE.reciprocal_prec(prec), (Float::negative_one_prec(prec), Equal) ); }); } #[allow(clippy::needless_pass_by_value)] fn reciprocal_round_properties_helper(x: Float, rm: RoundingMode) { let (reciprocal, o) = x.clone().reciprocal_round(rm); assert!(reciprocal.is_valid()); let (reciprocal_alt, o_alt) = x.reciprocal_round_ref(rm); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let mut x_alt = x.clone(); let o_alt = x_alt.reciprocal_round_assign(rm); assert!(x_alt.is_valid()); assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&reciprocal)); assert_eq!(o_alt, o); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_1(x.clone(), x.significant_bits(), rm); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let (reciprocal_alt, o_alt) = reciprocal_prec_round_naive_2(x.clone(), x.significant_bits(), rm); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); if let Ok(rm) = rug_round_try_from_rounding_mode(rm) { let (rug_reciprocal, rug_o) = rug_reciprocal_round(&rug::Float::exact_from(&x), rm); assert_eq!( ComparableFloatRef(&Float::from(&rug_reciprocal)), ComparableFloatRef(&reciprocal), ); assert_eq!(rug_o, o); } let (reciprocal_alt, o_alt) = Float::ONE.div_round(x.clone(), rm); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); assert_eq!(o_alt, o); let r_reciprocal = if reciprocal.is_finite() && x.is_finite() { if reciprocal.is_normal() { assert_eq!(reciprocal.get_prec(), Some(x.significant_bits())); } let r_reciprocal = Rational::exact_from(&x).reciprocal(); assert_eq!(reciprocal.partial_cmp(&r_reciprocal), Some(o)); if o == Less { let mut next = reciprocal.clone(); next.increment(); assert!(next > r_reciprocal); } else if o == Greater { let mut next = reciprocal.clone(); next.decrement(); assert!(next < r_reciprocal); } Some(r_reciprocal) } else { assert_eq!(o, Equal); None }; match ( r_reciprocal.is_some() && *r_reciprocal.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 reciprocal_alt, mut o_alt) = (-&x).reciprocal_round(-rm); reciprocal_alt.neg_assign(); o_alt = o_alt.reverse(); assert_eq!( ComparableFloat(reciprocal_alt.abs_negative_zero()), ComparableFloat(reciprocal.abs_negative_zero_ref()) ); assert_eq!(o_alt, o); if o == Equal { for rm in exhaustive_rounding_modes() { let (s, oo) = x.reciprocal_round_ref(rm); assert_eq!( ComparableFloat(s.abs_negative_zero_ref()), ComparableFloat(reciprocal.abs_negative_zero_ref()) ); assert_eq!(oo, Equal); } } else { assert_panic!(x.reciprocal_round_ref(Exact)); } } #[test] fn reciprocal_round_properties() { float_rounding_mode_pair_gen_var_13().test_properties(|(x, rm)| { reciprocal_round_properties_helper(x, rm); }); let mut config = GenConfig::new(); config.insert("mean_precision_n", 2048); config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH); float_rounding_mode_pair_gen_var_13().test_properties_with_config(&config, |(x, rm)| { reciprocal_round_properties_helper(x, rm); }); float_rounding_mode_pair_gen_var_14().test_properties(|(x, rm)| { reciprocal_round_properties_helper(x, rm); }); float_rounding_mode_pair_gen_var_15().test_properties(|(x, rm)| { reciprocal_round_properties_helper(x, rm); }); float_rounding_mode_pair_gen_var_16().test_properties(|(x, rm)| { reciprocal_round_properties_helper(x, rm); }); float_rounding_mode_pair_gen_var_17().test_properties(|(x, rm)| { reciprocal_round_properties_helper(x, rm); }); rounding_mode_gen().test_properties(|rm| { let (reciprocal, o) = Float::NAN.reciprocal_round(rm); assert!(reciprocal.is_nan()); assert_eq!(o, Equal); assert_eq!(Float::INFINITY.reciprocal_round(rm), (Float::ZERO, Equal)); assert_eq!( Float::NEGATIVE_INFINITY.reciprocal_round(rm), (Float::NEGATIVE_ZERO, Equal) ); assert_eq!(Float::ZERO.reciprocal_round(rm), (Float::INFINITY, Equal)); assert_eq!( Float::NEGATIVE_ZERO.reciprocal_round(rm), (Float::NEGATIVE_INFINITY, Equal) ); assert_eq!(Float::ONE.reciprocal_round(rm), (Float::ONE, Equal)); assert_eq!( Float::NEGATIVE_ONE.reciprocal_round(rm), (Float::NEGATIVE_ONE, Equal) ); }); } #[allow(clippy::type_repetition_in_bounds)] fn reciprocal_properties_helper_2() where Float: From + PartialOrd, for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>, { primitive_float_gen::().test_properties(|x| { let reciprocal_1 = x.reciprocal(); let reciprocal_2 = emulate_primitive_float_fn(|x, prec| x.reciprocal_prec(prec).0, x); assert_eq!(NiceFloat(reciprocal_1), NiceFloat(reciprocal_2)); }); } #[allow(clippy::needless_pass_by_value)] fn reciprocal_properties_helper(x: Float) { let reciprocal = x.clone().reciprocal(); assert!(reciprocal.is_valid()); let reciprocal_alt = (&x).reciprocal(); assert!(reciprocal_alt.is_valid()); assert_eq!( ComparableFloatRef(&reciprocal_alt), ComparableFloatRef(&reciprocal) ); let mut x_alt = x.clone(); x_alt.reciprocal_assign(); assert!(x_alt.is_valid()); assert_eq!(ComparableFloatRef(&x_alt), ComparableFloatRef(&reciprocal)); assert_eq!( ComparableFloatRef( &reciprocal_prec_round_naive_1(x.clone(), x.significant_bits(), Nearest).0 ), ComparableFloatRef(&reciprocal) ); assert_eq!( ComparableFloatRef( &reciprocal_prec_round_naive_2(x.clone(), x.significant_bits(), Nearest).0 ), ComparableFloatRef(&reciprocal) ); let rug_reciprocal = rug_reciprocal(&rug::Float::exact_from(&x)); assert_eq!( ComparableFloatRef(&Float::from(&rug_reciprocal)), ComparableFloatRef(&reciprocal), ); assert_eq!( ComparableFloatRef(&(Float::ONE / x.clone())), ComparableFloatRef(&reciprocal) ); if reciprocal.is_normal() && x.is_finite() { assert_eq!(reciprocal.get_prec(), Some(x.significant_bits())); } let mut reciprocal_alt = (-&x).reciprocal(); reciprocal_alt.neg_assign(); assert_eq!( ComparableFloat(reciprocal_alt.abs_negative_zero()), ComparableFloat(reciprocal.abs_negative_zero_ref()) ); } #[test] fn reciprocal_properties() { float_gen().test_properties(|x| { reciprocal_properties_helper(x); }); let mut config = GenConfig::new(); config.insert("mean_precision_n", 2048); config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH); float_gen().test_properties_with_config(&config, |x| { reciprocal_properties_helper(x); }); float_gen_var_6().test_properties(|x| { reciprocal_properties_helper(x); }); float_gen_var_7().test_properties(|x| { reciprocal_properties_helper(x); }); float_gen_var_8().test_properties(|x| { reciprocal_properties_helper(x); }); float_gen_var_11().test_properties(|x| { reciprocal_properties_helper(x); }); apply_fn_to_primitive_floats!(reciprocal_properties_helper_2); }