Skip to content

Commit dd51e8b

Browse files
committed
[libc][math][c23] Checkout MPFRUtils.cpp from branch libc-math-ceilf16-mpfr-tests
1 parent 7fe59bc commit dd51e8b

File tree

1 file changed

+35
-4
lines changed

1 file changed

+35
-4
lines changed

libc/utils/MPFRWrapper/MPFRUtils.cpp

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "src/__support/CPP/string_view.h"
1313
#include "src/__support/FPUtil/FPBits.h"
1414
#include "src/__support/FPUtil/fpbits_str.h"
15+
#include "src/__support/macros/properties/types.h"
1516
#include "test/UnitTest/FPMatcher.h"
1617

1718
#include "hdr/math_macros.h"
@@ -30,6 +31,12 @@ namespace mpfr {
3031
// precision compared to the floating point precision.
3132
template <typename T> struct ExtraPrecision;
3233

34+
#ifdef LIBC_TYPES_HAS_FLOAT16
35+
template <> struct ExtraPrecision<float16> {
36+
static constexpr unsigned int VALUE = 128;
37+
};
38+
#endif
39+
3340
template <> struct ExtraPrecision<float> {
3441
static constexpr unsigned int VALUE = 128;
3542
};
@@ -85,9 +92,16 @@ class MPFRNumber {
8592

8693
// We use explicit EnableIf specializations to disallow implicit
8794
// conversions. Implicit conversions can potentially lead to loss of
88-
// precision.
95+
// precision. We exceptionally allow implicit conversions from float16
96+
// to float, as the MPFR API does not support float16, thus requiring
97+
// conversion to a higher-precision format.
8998
template <typename XType,
90-
cpp::enable_if_t<cpp::is_same_v<float, XType>, int> = 0>
99+
cpp::enable_if_t<cpp::is_same_v<float, XType>
100+
#ifdef LIBC_TYPES_HAS_FLOAT16
101+
|| cpp::is_same_v<float16, XType>
102+
#endif
103+
,
104+
int> = 0>
91105
explicit MPFRNumber(XType x,
92106
unsigned int precision = ExtraPrecision<XType>::VALUE,
93107
RoundingMode rounding = RoundingMode::Nearest)
@@ -529,8 +543,8 @@ class MPFRNumber {
529543
// If the control reaches here, it means that this number and input are
530544
// of the same sign but different exponent. In such a case, ULP error is
531545
// calculated as sum of two parts.
532-
thisAsT = std::abs(thisAsT);
533-
input = std::abs(input);
546+
thisAsT = FPBits<T>(thisAsT).abs().get_val();
547+
input = FPBits<T>(input).abs().get_val();
534548
T min = thisAsT > input ? input : thisAsT;
535549
T max = thisAsT > input ? thisAsT : input;
536550
int minExponent = FPBits<T>(min).get_exponent();
@@ -585,6 +599,14 @@ template <> long double MPFRNumber::as<long double>() const {
585599
return mpfr_get_ld(value, mpfr_rounding);
586600
}
587601

602+
#ifdef LIBC_TYPES_HAS_FLOAT16
603+
template <> float16 MPFRNumber::as<float16>() const {
604+
// TODO: Either prove that this cast won't cause double-rounding errors, or
605+
// find a better way to get a float16.
606+
return static_cast<float16>(mpfr_get_d(value, mpfr_rounding));
607+
}
608+
#endif
609+
588610
namespace internal {
589611

590612
template <typename InputType>
@@ -763,6 +785,10 @@ template void explain_unary_operation_single_output_error<double>(
763785
Operation op, double, double, double, RoundingMode);
764786
template void explain_unary_operation_single_output_error<long double>(
765787
Operation op, long double, long double, double, RoundingMode);
788+
#ifdef LIBC_TYPES_HAS_FLOAT16
789+
template void explain_unary_operation_single_output_error<float16>(
790+
Operation op, float16, float16, double, RoundingMode);
791+
#endif
766792

767793
template <typename T>
768794
void explain_unary_operation_two_outputs_error(
@@ -942,6 +968,11 @@ template bool compare_unary_operation_single_output<double>(Operation, double,
942968
RoundingMode);
943969
template bool compare_unary_operation_single_output<long double>(
944970
Operation, long double, long double, double, RoundingMode);
971+
#ifdef LIBC_TYPES_HAS_FLOAT16
972+
template bool compare_unary_operation_single_output<float16>(Operation, float16,
973+
float16, double,
974+
RoundingMode);
975+
#endif
945976

946977
template <typename T>
947978
bool compare_unary_operation_two_outputs(Operation op, T input,

0 commit comments

Comments
 (0)