@@ -31,9 +31,11 @@ namespace mpfr {
31
31
// precision compared to the floating point precision.
32
32
template <typename T> struct ExtraPrecision ;
33
33
34
+ #ifdef LIBC_TYPES_HAS_FLOAT16
34
35
template <> struct ExtraPrecision <float16> {
35
36
static constexpr unsigned int VALUE = 128 ;
36
37
};
38
+ #endif
37
39
38
40
template <> struct ExtraPrecision <float > {
39
41
static constexpr unsigned int VALUE = 128 ;
@@ -93,9 +95,13 @@ class MPFRNumber {
93
95
// precision. We exceptionally allow implicit conversions from float16
94
96
// to float, as the MPFR API does not support float16, thus requiring
95
97
// conversion to a higher-precision format.
96
- template <typename XType, cpp::enable_if_t <cpp::is_same_v<float , XType> ||
97
- cpp::is_same_v<float16, XType>,
98
- int > = 0 >
98
+ template <typename XType,
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 >
99
105
explicit MPFRNumber (XType x,
100
106
unsigned int precision = ExtraPrecision<XType>::VALUE,
101
107
RoundingMode rounding = RoundingMode::Nearest)
@@ -537,7 +543,12 @@ class MPFRNumber {
537
543
// If the control reaches here, it means that this number and input are
538
544
// of the same sign but different exponent. In such a case, ULP error is
539
545
// calculated as sum of two parts.
546
+ #ifdef LIBC_TYPES_HAS_FLOAT16
547
+ // TODO: This will no longer be needed once std::abs supports float16.
540
548
using U = cpp::conditional_t <cpp::is_same_v<T, float16>, float , T>;
549
+ #else
550
+ using U = T;
551
+ #endif
541
552
thisAsT = std::abs (static_cast <U>(thisAsT));
542
553
input = std::abs (static_cast <U>(input));
543
554
T min = thisAsT > input ? input : thisAsT;
@@ -594,9 +605,13 @@ template <> long double MPFRNumber::as<long double>() const {
594
605
return mpfr_get_ld (value, mpfr_rounding);
595
606
}
596
607
608
+ #ifdef LIBC_TYPES_HAS_FLOAT16
597
609
template <> float16 MPFRNumber::as<float16>() const {
598
- return static_cast <float16>(mpfr_get_flt (value, mpfr_rounding));
610
+ // TODO: Either prove that this cast won't cause double-rounding errors, or
611
+ // find a better way to get a float16.
612
+ return static_cast <float16>(mpfr_get_d (value, mpfr_rounding));
599
613
}
614
+ #endif
600
615
601
616
namespace internal {
602
617
@@ -776,8 +791,10 @@ template void explain_unary_operation_single_output_error<double>(
776
791
Operation op, double , double , double , RoundingMode);
777
792
template void explain_unary_operation_single_output_error<long double >(
778
793
Operation op, long double , long double , double , RoundingMode);
794
+ #ifdef LIBC_TYPES_HAS_FLOAT16
779
795
template void explain_unary_operation_single_output_error<float16>(
780
796
Operation op, float16, float16, double , RoundingMode);
797
+ #endif
781
798
782
799
template <typename T>
783
800
void explain_unary_operation_two_outputs_error (
@@ -957,9 +974,11 @@ template bool compare_unary_operation_single_output<double>(Operation, double,
957
974
RoundingMode);
958
975
template bool compare_unary_operation_single_output<long double >(
959
976
Operation, long double , long double , double , RoundingMode);
977
+ #ifdef LIBC_TYPES_HAS_FLOAT16
960
978
template bool compare_unary_operation_single_output<float16>(Operation, float16,
961
979
float16, double ,
962
980
RoundingMode);
981
+ #endif
963
982
964
983
template <typename T>
965
984
bool compare_unary_operation_two_outputs (Operation op, T input,
@@ -1091,7 +1110,6 @@ template <typename T> T round(T x, RoundingMode mode) {
1091
1110
template float round<float >(float , RoundingMode);
1092
1111
template double round<double >(double , RoundingMode);
1093
1112
template long double round<long double >(long double , RoundingMode);
1094
- template float16 round<float16>(float16, RoundingMode);
1095
1113
1096
1114
} // namespace mpfr
1097
1115
} // namespace testing
0 commit comments