1*7f37b34dSShourya Goel //===-- Utils which wrap MPC ----------------------------------------------===// 2*7f37b34dSShourya Goel // 3*7f37b34dSShourya Goel // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*7f37b34dSShourya Goel // See https://llvm.org/LICENSE.txt for license information. 5*7f37b34dSShourya Goel // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*7f37b34dSShourya Goel // 7*7f37b34dSShourya Goel //===----------------------------------------------------------------------===// 8*7f37b34dSShourya Goel 9*7f37b34dSShourya Goel #include "MPCUtils.h" 10*7f37b34dSShourya Goel 11*7f37b34dSShourya Goel #include "src/__support/CPP/array.h" 12*7f37b34dSShourya Goel #include "src/__support/CPP/stringstream.h" 13*7f37b34dSShourya Goel #include "utils/MPFRWrapper/MPCommon.h" 14*7f37b34dSShourya Goel 15*7f37b34dSShourya Goel #include <stdint.h> 16*7f37b34dSShourya Goel 17*7f37b34dSShourya Goel #include "mpc.h" 18*7f37b34dSShourya Goel 19*7f37b34dSShourya Goel template <typename T> using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; 20*7f37b34dSShourya Goel 21*7f37b34dSShourya Goel namespace LIBC_NAMESPACE_DECL { 22*7f37b34dSShourya Goel namespace testing { 23*7f37b34dSShourya Goel namespace mpc { 24*7f37b34dSShourya Goel 25*7f37b34dSShourya Goel static inline cpp::string str(RoundingMode mode) { 26*7f37b34dSShourya Goel switch (mode) { 27*7f37b34dSShourya Goel case RoundingMode::Upward: 28*7f37b34dSShourya Goel return "MPFR_RNDU"; 29*7f37b34dSShourya Goel case RoundingMode::Downward: 30*7f37b34dSShourya Goel return "MPFR_RNDD"; 31*7f37b34dSShourya Goel case RoundingMode::TowardZero: 32*7f37b34dSShourya Goel return "MPFR_RNDZ"; 33*7f37b34dSShourya Goel case RoundingMode::Nearest: 34*7f37b34dSShourya Goel return "MPFR_RNDN"; 35*7f37b34dSShourya Goel } 36*7f37b34dSShourya Goel } 37*7f37b34dSShourya Goel 38*7f37b34dSShourya Goel class MPCNumber { 39*7f37b34dSShourya Goel private: 40*7f37b34dSShourya Goel unsigned int precision; 41*7f37b34dSShourya Goel mpc_t value; 42*7f37b34dSShourya Goel mpc_rnd_t mpc_rounding; 43*7f37b34dSShourya Goel 44*7f37b34dSShourya Goel public: 45*7f37b34dSShourya Goel explicit MPCNumber(unsigned int p) : precision(p), mpc_rounding(MPC_RNDNN) { 46*7f37b34dSShourya Goel mpc_init2(value, precision); 47*7f37b34dSShourya Goel } 48*7f37b34dSShourya Goel 49*7f37b34dSShourya Goel MPCNumber() : precision(256), mpc_rounding(MPC_RNDNN) { 50*7f37b34dSShourya Goel mpc_init2(value, 256); 51*7f37b34dSShourya Goel } 52*7f37b34dSShourya Goel 53*7f37b34dSShourya Goel MPCNumber(unsigned int p, mpc_rnd_t rnd) : precision(p), mpc_rounding(rnd) { 54*7f37b34dSShourya Goel mpc_init2(value, precision); 55*7f37b34dSShourya Goel } 56*7f37b34dSShourya Goel 57*7f37b34dSShourya Goel template <typename XType, 58*7f37b34dSShourya Goel cpp::enable_if_t<cpp::is_same_v<_Complex float, XType>, bool> = 0> 59*7f37b34dSShourya Goel MPCNumber(XType x, 60*7f37b34dSShourya Goel unsigned int precision = mpfr::ExtraPrecision<float>::VALUE, 61*7f37b34dSShourya Goel RoundingMode rnd = RoundingMode::Nearest) 62*7f37b34dSShourya Goel : precision(precision), 63*7f37b34dSShourya Goel mpc_rounding(MPC_RND(mpfr::get_mpfr_rounding_mode(rnd), 64*7f37b34dSShourya Goel mpfr::get_mpfr_rounding_mode(rnd))) { 65*7f37b34dSShourya Goel mpc_init2(value, precision); 66*7f37b34dSShourya Goel Complex<float> x_c = cpp::bit_cast<Complex<float>>(x); 67*7f37b34dSShourya Goel mpfr_t real, imag; 68*7f37b34dSShourya Goel mpfr_init2(real, precision); 69*7f37b34dSShourya Goel mpfr_init2(imag, precision); 70*7f37b34dSShourya Goel mpfr_set_flt(real, x_c.real, mpfr::get_mpfr_rounding_mode(rnd)); 71*7f37b34dSShourya Goel mpfr_set_flt(imag, x_c.imag, mpfr::get_mpfr_rounding_mode(rnd)); 72*7f37b34dSShourya Goel mpc_set_fr_fr(value, real, imag, mpc_rounding); 73*7f37b34dSShourya Goel mpfr_clear(real); 74*7f37b34dSShourya Goel mpfr_clear(imag); 75*7f37b34dSShourya Goel } 76*7f37b34dSShourya Goel 77*7f37b34dSShourya Goel template <typename XType, 78*7f37b34dSShourya Goel cpp::enable_if_t<cpp::is_same_v<_Complex double, XType>, bool> = 0> 79*7f37b34dSShourya Goel MPCNumber(XType x, 80*7f37b34dSShourya Goel unsigned int precision = mpfr::ExtraPrecision<double>::VALUE, 81*7f37b34dSShourya Goel RoundingMode rnd = RoundingMode::Nearest) 82*7f37b34dSShourya Goel : precision(precision), 83*7f37b34dSShourya Goel mpc_rounding(MPC_RND(mpfr::get_mpfr_rounding_mode(rnd), 84*7f37b34dSShourya Goel mpfr::get_mpfr_rounding_mode(rnd))) { 85*7f37b34dSShourya Goel mpc_init2(value, precision); 86*7f37b34dSShourya Goel Complex<double> x_c = cpp::bit_cast<Complex<double>>(x); 87*7f37b34dSShourya Goel mpc_set_d_d(value, x_c.real, x_c.imag, mpc_rounding); 88*7f37b34dSShourya Goel } 89*7f37b34dSShourya Goel 90*7f37b34dSShourya Goel MPCNumber(const MPCNumber &other) 91*7f37b34dSShourya Goel : precision(other.precision), mpc_rounding(other.mpc_rounding) { 92*7f37b34dSShourya Goel mpc_init2(value, precision); 93*7f37b34dSShourya Goel mpc_set(value, other.value, mpc_rounding); 94*7f37b34dSShourya Goel } 95*7f37b34dSShourya Goel 96*7f37b34dSShourya Goel ~MPCNumber() { mpc_clear(value); } 97*7f37b34dSShourya Goel 98*7f37b34dSShourya Goel MPCNumber &operator=(const MPCNumber &rhs) { 99*7f37b34dSShourya Goel precision = rhs.precision; 100*7f37b34dSShourya Goel mpc_rounding = rhs.mpc_rounding; 101*7f37b34dSShourya Goel mpc_init2(value, precision); 102*7f37b34dSShourya Goel mpc_set(value, rhs.value, mpc_rounding); 103*7f37b34dSShourya Goel return *this; 104*7f37b34dSShourya Goel } 105*7f37b34dSShourya Goel 106*7f37b34dSShourya Goel void setValue(mpc_t val) const { mpc_set(val, value, mpc_rounding); } 107*7f37b34dSShourya Goel 108*7f37b34dSShourya Goel mpc_t &getValue() { return value; } 109*7f37b34dSShourya Goel 110*7f37b34dSShourya Goel MPCNumber carg() const { 111*7f37b34dSShourya Goel mpfr_t res; 112*7f37b34dSShourya Goel MPCNumber result(precision, mpc_rounding); 113*7f37b34dSShourya Goel 114*7f37b34dSShourya Goel mpfr_init2(res, precision); 115*7f37b34dSShourya Goel 116*7f37b34dSShourya Goel mpc_arg(res, value, MPC_RND_RE(mpc_rounding)); 117*7f37b34dSShourya Goel mpc_set_fr(result.value, res, mpc_rounding); 118*7f37b34dSShourya Goel 119*7f37b34dSShourya Goel mpfr_clear(res); 120*7f37b34dSShourya Goel 121*7f37b34dSShourya Goel return result; 122*7f37b34dSShourya Goel } 123*7f37b34dSShourya Goel 124*7f37b34dSShourya Goel MPCNumber cproj() const { 125*7f37b34dSShourya Goel MPCNumber result(precision, mpc_rounding); 126*7f37b34dSShourya Goel mpc_proj(result.value, value, mpc_rounding); 127*7f37b34dSShourya Goel return result; 128*7f37b34dSShourya Goel } 129*7f37b34dSShourya Goel }; 130*7f37b34dSShourya Goel 131*7f37b34dSShourya Goel namespace internal { 132*7f37b34dSShourya Goel 133*7f37b34dSShourya Goel template <typename InputType> 134*7f37b34dSShourya Goel cpp::enable_if_t<cpp::is_complex_v<InputType>, MPCNumber> 135*7f37b34dSShourya Goel unary_operation(Operation op, InputType input, unsigned int precision, 136*7f37b34dSShourya Goel RoundingMode rounding) { 137*7f37b34dSShourya Goel MPCNumber mpcInput(input, precision, rounding); 138*7f37b34dSShourya Goel switch (op) { 139*7f37b34dSShourya Goel case Operation::Carg: 140*7f37b34dSShourya Goel return mpcInput.carg(); 141*7f37b34dSShourya Goel case Operation::Cproj: 142*7f37b34dSShourya Goel return mpcInput.cproj(); 143*7f37b34dSShourya Goel default: 144*7f37b34dSShourya Goel __builtin_unreachable(); 145*7f37b34dSShourya Goel } 146*7f37b34dSShourya Goel } 147*7f37b34dSShourya Goel 148*7f37b34dSShourya Goel template <typename InputType, typename OutputType> 149*7f37b34dSShourya Goel bool compare_unary_operation_single_output_same_type(Operation op, 150*7f37b34dSShourya Goel InputType input, 151*7f37b34dSShourya Goel OutputType libc_result, 152*7f37b34dSShourya Goel double ulp_tolerance, 153*7f37b34dSShourya Goel RoundingMode rounding) { 154*7f37b34dSShourya Goel 155*7f37b34dSShourya Goel unsigned int precision = 156*7f37b34dSShourya Goel mpfr::get_precision<make_real_t<InputType>>(ulp_tolerance); 157*7f37b34dSShourya Goel 158*7f37b34dSShourya Goel MPCNumber mpc_result; 159*7f37b34dSShourya Goel mpc_result = unary_operation(op, input, precision, rounding); 160*7f37b34dSShourya Goel 161*7f37b34dSShourya Goel mpc_t mpc_result_val; 162*7f37b34dSShourya Goel mpc_init2(mpc_result_val, precision); 163*7f37b34dSShourya Goel mpc_result.setValue(mpc_result_val); 164*7f37b34dSShourya Goel 165*7f37b34dSShourya Goel mpfr_t real, imag; 166*7f37b34dSShourya Goel mpfr_init2(real, precision); 167*7f37b34dSShourya Goel mpfr_init2(imag, precision); 168*7f37b34dSShourya Goel mpc_real(real, mpc_result_val, mpfr::get_mpfr_rounding_mode(rounding)); 169*7f37b34dSShourya Goel mpc_imag(imag, mpc_result_val, mpfr::get_mpfr_rounding_mode(rounding)); 170*7f37b34dSShourya Goel 171*7f37b34dSShourya Goel mpfr::MPFRNumber mpfr_real(real, precision, rounding); 172*7f37b34dSShourya Goel mpfr::MPFRNumber mpfr_imag(imag, precision, rounding); 173*7f37b34dSShourya Goel 174*7f37b34dSShourya Goel double ulp_real = mpfr_real.ulp( 175*7f37b34dSShourya Goel (cpp::bit_cast<Complex<make_real_t<InputType>>>(libc_result)).real); 176*7f37b34dSShourya Goel double ulp_imag = mpfr_imag.ulp( 177*7f37b34dSShourya Goel (cpp::bit_cast<Complex<make_real_t<InputType>>>(libc_result)).imag); 178*7f37b34dSShourya Goel mpc_clear(mpc_result_val); 179*7f37b34dSShourya Goel mpfr_clear(real); 180*7f37b34dSShourya Goel mpfr_clear(imag); 181*7f37b34dSShourya Goel return (ulp_real <= ulp_tolerance) && (ulp_imag <= ulp_tolerance); 182*7f37b34dSShourya Goel } 183*7f37b34dSShourya Goel 184*7f37b34dSShourya Goel template bool compare_unary_operation_single_output_same_type( 185*7f37b34dSShourya Goel Operation, _Complex float, _Complex float, double, RoundingMode); 186*7f37b34dSShourya Goel template bool compare_unary_operation_single_output_same_type( 187*7f37b34dSShourya Goel Operation, _Complex double, _Complex double, double, RoundingMode); 188*7f37b34dSShourya Goel 189*7f37b34dSShourya Goel template <typename InputType, typename OutputType> 190*7f37b34dSShourya Goel bool compare_unary_operation_single_output_different_type( 191*7f37b34dSShourya Goel Operation op, InputType input, OutputType libc_result, double ulp_tolerance, 192*7f37b34dSShourya Goel RoundingMode rounding) { 193*7f37b34dSShourya Goel 194*7f37b34dSShourya Goel unsigned int precision = 195*7f37b34dSShourya Goel mpfr::get_precision<make_real_t<InputType>>(ulp_tolerance); 196*7f37b34dSShourya Goel 197*7f37b34dSShourya Goel MPCNumber mpc_result; 198*7f37b34dSShourya Goel mpc_result = unary_operation(op, input, precision, rounding); 199*7f37b34dSShourya Goel 200*7f37b34dSShourya Goel mpc_t mpc_result_val; 201*7f37b34dSShourya Goel mpc_init2(mpc_result_val, precision); 202*7f37b34dSShourya Goel mpc_result.setValue(mpc_result_val); 203*7f37b34dSShourya Goel 204*7f37b34dSShourya Goel mpfr_t real; 205*7f37b34dSShourya Goel mpfr_init2(real, precision); 206*7f37b34dSShourya Goel mpc_real(real, mpc_result_val, mpfr::get_mpfr_rounding_mode(rounding)); 207*7f37b34dSShourya Goel 208*7f37b34dSShourya Goel mpfr::MPFRNumber mpfr_real(real, precision, rounding); 209*7f37b34dSShourya Goel 210*7f37b34dSShourya Goel double ulp_real = mpfr_real.ulp(libc_result); 211*7f37b34dSShourya Goel mpc_clear(mpc_result_val); 212*7f37b34dSShourya Goel mpfr_clear(real); 213*7f37b34dSShourya Goel return (ulp_real <= ulp_tolerance); 214*7f37b34dSShourya Goel } 215*7f37b34dSShourya Goel 216*7f37b34dSShourya Goel template bool compare_unary_operation_single_output_different_type( 217*7f37b34dSShourya Goel Operation, _Complex float, float, double, RoundingMode); 218*7f37b34dSShourya Goel template bool compare_unary_operation_single_output_different_type( 219*7f37b34dSShourya Goel Operation, _Complex double, double, double, RoundingMode); 220*7f37b34dSShourya Goel 221*7f37b34dSShourya Goel template <typename InputType, typename OutputType> 222*7f37b34dSShourya Goel void explain_unary_operation_single_output_different_type_error( 223*7f37b34dSShourya Goel Operation op, InputType input, OutputType libc_result, double ulp_tolerance, 224*7f37b34dSShourya Goel RoundingMode rounding) { 225*7f37b34dSShourya Goel 226*7f37b34dSShourya Goel unsigned int precision = 227*7f37b34dSShourya Goel mpfr::get_precision<make_real_t<InputType>>(ulp_tolerance); 228*7f37b34dSShourya Goel 229*7f37b34dSShourya Goel MPCNumber mpc_result; 230*7f37b34dSShourya Goel mpc_result = unary_operation(op, input, precision, rounding); 231*7f37b34dSShourya Goel 232*7f37b34dSShourya Goel mpc_t mpc_result_val; 233*7f37b34dSShourya Goel mpc_init2(mpc_result_val, precision); 234*7f37b34dSShourya Goel mpc_result.setValue(mpc_result_val); 235*7f37b34dSShourya Goel 236*7f37b34dSShourya Goel mpfr_t real; 237*7f37b34dSShourya Goel mpfr_init2(real, precision); 238*7f37b34dSShourya Goel mpc_real(real, mpc_result_val, mpfr::get_mpfr_rounding_mode(rounding)); 239*7f37b34dSShourya Goel 240*7f37b34dSShourya Goel mpfr::MPFRNumber mpfr_result(real, precision, rounding); 241*7f37b34dSShourya Goel mpfr::MPFRNumber mpfrLibcResult(libc_result, precision, rounding); 242*7f37b34dSShourya Goel mpfr::MPFRNumber mpfrInputReal( 243*7f37b34dSShourya Goel cpp::bit_cast<Complex<make_real_t<InputType>>>(input).real, precision, 244*7f37b34dSShourya Goel rounding); 245*7f37b34dSShourya Goel mpfr::MPFRNumber mpfrInputImag( 246*7f37b34dSShourya Goel cpp::bit_cast<Complex<make_real_t<InputType>>>(input).imag, precision, 247*7f37b34dSShourya Goel rounding); 248*7f37b34dSShourya Goel 249*7f37b34dSShourya Goel cpp::array<char, 2048> msg_buf; 250*7f37b34dSShourya Goel cpp::StringStream msg(msg_buf); 251*7f37b34dSShourya Goel msg << "Match value not within tolerance value of MPFR result:\n" 252*7f37b34dSShourya Goel << " Input: " << mpfrInputReal.str() << " + " << mpfrInputImag.str() 253*7f37b34dSShourya Goel << "i\n" 254*7f37b34dSShourya Goel << " Rounding mode: " << str(rounding) << '\n' 255*7f37b34dSShourya Goel << " Libc: " << mpfrLibcResult.str() << '\n' 256*7f37b34dSShourya Goel << " MPC: " << mpfr_result.str() << '\n' 257*7f37b34dSShourya Goel << '\n' 258*7f37b34dSShourya Goel << " ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result).str() 259*7f37b34dSShourya Goel << '\n'; 260*7f37b34dSShourya Goel tlog << msg.str(); 261*7f37b34dSShourya Goel mpc_clear(mpc_result_val); 262*7f37b34dSShourya Goel mpfr_clear(real); 263*7f37b34dSShourya Goel } 264*7f37b34dSShourya Goel 265*7f37b34dSShourya Goel template void explain_unary_operation_single_output_different_type_error( 266*7f37b34dSShourya Goel Operation, _Complex float, float, double, RoundingMode); 267*7f37b34dSShourya Goel template void explain_unary_operation_single_output_different_type_error( 268*7f37b34dSShourya Goel Operation, _Complex double, double, double, RoundingMode); 269*7f37b34dSShourya Goel 270*7f37b34dSShourya Goel template <typename InputType, typename OutputType> 271*7f37b34dSShourya Goel void explain_unary_operation_single_output_same_type_error( 272*7f37b34dSShourya Goel Operation op, InputType input, OutputType libc_result, double ulp_tolerance, 273*7f37b34dSShourya Goel RoundingMode rounding) { 274*7f37b34dSShourya Goel 275*7f37b34dSShourya Goel unsigned int precision = 276*7f37b34dSShourya Goel mpfr::get_precision<make_real_t<InputType>>(ulp_tolerance); 277*7f37b34dSShourya Goel 278*7f37b34dSShourya Goel MPCNumber mpc_result; 279*7f37b34dSShourya Goel mpc_result = unary_operation(op, input, precision, rounding); 280*7f37b34dSShourya Goel 281*7f37b34dSShourya Goel mpc_t mpc_result_val; 282*7f37b34dSShourya Goel mpc_init2(mpc_result_val, precision); 283*7f37b34dSShourya Goel mpc_result.setValue(mpc_result_val); 284*7f37b34dSShourya Goel 285*7f37b34dSShourya Goel mpfr_t real, imag; 286*7f37b34dSShourya Goel mpfr_init2(real, precision); 287*7f37b34dSShourya Goel mpfr_init2(imag, precision); 288*7f37b34dSShourya Goel mpc_real(real, mpc_result_val, mpfr::get_mpfr_rounding_mode(rounding)); 289*7f37b34dSShourya Goel mpc_imag(imag, mpc_result_val, mpfr::get_mpfr_rounding_mode(rounding)); 290*7f37b34dSShourya Goel 291*7f37b34dSShourya Goel mpfr::MPFRNumber mpfr_real(real, precision, rounding); 292*7f37b34dSShourya Goel mpfr::MPFRNumber mpfr_imag(imag, precision, rounding); 293*7f37b34dSShourya Goel mpfr::MPFRNumber mpfrLibcResultReal( 294*7f37b34dSShourya Goel cpp::bit_cast<Complex<make_real_t<InputType>>>(libc_result).real, 295*7f37b34dSShourya Goel precision, rounding); 296*7f37b34dSShourya Goel mpfr::MPFRNumber mpfrLibcResultImag( 297*7f37b34dSShourya Goel cpp::bit_cast<Complex<make_real_t<InputType>>>(libc_result).imag, 298*7f37b34dSShourya Goel precision, rounding); 299*7f37b34dSShourya Goel mpfr::MPFRNumber mpfrInputReal( 300*7f37b34dSShourya Goel cpp::bit_cast<Complex<make_real_t<InputType>>>(input).real, precision, 301*7f37b34dSShourya Goel rounding); 302*7f37b34dSShourya Goel mpfr::MPFRNumber mpfrInputImag( 303*7f37b34dSShourya Goel cpp::bit_cast<Complex<make_real_t<InputType>>>(input).imag, precision, 304*7f37b34dSShourya Goel rounding); 305*7f37b34dSShourya Goel 306*7f37b34dSShourya Goel cpp::array<char, 2048> msg_buf; 307*7f37b34dSShourya Goel cpp::StringStream msg(msg_buf); 308*7f37b34dSShourya Goel msg << "Match value not within tolerance value of MPFR result:\n" 309*7f37b34dSShourya Goel << " Input: " << mpfrInputReal.str() << " + " << mpfrInputImag.str() 310*7f37b34dSShourya Goel << "i\n" 311*7f37b34dSShourya Goel << " Rounding mode: " << str(rounding) << " , " << str(rounding) << '\n' 312*7f37b34dSShourya Goel << " Libc: " << mpfrLibcResultReal.str() << " + " 313*7f37b34dSShourya Goel << mpfrLibcResultImag.str() << "i\n" 314*7f37b34dSShourya Goel << " MPC: " << mpfr_real.str() << " + " << mpfr_imag.str() << "i\n" 315*7f37b34dSShourya Goel << '\n' 316*7f37b34dSShourya Goel << " ULP error: " 317*7f37b34dSShourya Goel << mpfr_real 318*7f37b34dSShourya Goel .ulp_as_mpfr_number( 319*7f37b34dSShourya Goel cpp::bit_cast<Complex<make_real_t<InputType>>>(libc_result) 320*7f37b34dSShourya Goel .real) 321*7f37b34dSShourya Goel .str() 322*7f37b34dSShourya Goel << " , " 323*7f37b34dSShourya Goel << mpfr_imag 324*7f37b34dSShourya Goel .ulp_as_mpfr_number( 325*7f37b34dSShourya Goel cpp::bit_cast<Complex<make_real_t<InputType>>>(libc_result) 326*7f37b34dSShourya Goel .imag) 327*7f37b34dSShourya Goel .str() 328*7f37b34dSShourya Goel << '\n'; 329*7f37b34dSShourya Goel tlog << msg.str(); 330*7f37b34dSShourya Goel mpc_clear(mpc_result_val); 331*7f37b34dSShourya Goel mpfr_clear(real); 332*7f37b34dSShourya Goel mpfr_clear(imag); 333*7f37b34dSShourya Goel } 334*7f37b34dSShourya Goel 335*7f37b34dSShourya Goel template void explain_unary_operation_single_output_same_type_error( 336*7f37b34dSShourya Goel Operation, _Complex float, _Complex float, double, RoundingMode); 337*7f37b34dSShourya Goel template void explain_unary_operation_single_output_same_type_error( 338*7f37b34dSShourya Goel Operation, _Complex double, _Complex double, double, RoundingMode); 339*7f37b34dSShourya Goel 340*7f37b34dSShourya Goel } // namespace internal 341*7f37b34dSShourya Goel 342*7f37b34dSShourya Goel } // namespace mpc 343*7f37b34dSShourya Goel } // namespace testing 344*7f37b34dSShourya Goel } // namespace LIBC_NAMESPACE_DECL 345