22
22
23
23
#include " mpfr_inc.h"
24
24
25
+ #ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
26
+ extern " C" {
27
+ int mpfr_set_float128 (mpfr_ptr, float128, mpfr_rnd_t );
28
+ float128 mpfr_get_float128 (mpfr_srcptr, mpfr_rnd_t );
29
+ }
30
+ #endif
31
+
25
32
template <typename T> using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
26
33
27
34
namespace LIBC_NAMESPACE_DECL {
@@ -47,8 +54,18 @@ template <> struct ExtraPrecision<double> {
47
54
};
48
55
49
56
template <> struct ExtraPrecision <long double > {
57
+ #ifdef LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128
58
+ static constexpr unsigned int VALUE = 512 ;
59
+ #else
50
60
static constexpr unsigned int VALUE = 256 ;
61
+ #endif
62
+ };
63
+
64
+ #if defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE)
65
+ template <> struct ExtraPrecision <float128> {
66
+ static constexpr unsigned int VALUE = 512 ;
51
67
};
68
+ #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
52
69
53
70
// If the ulp tolerance is less than or equal to 0.5, we would check that the
54
71
// result is rounded correctly with respect to the rounding mode by using the
@@ -134,6 +151,19 @@ class MPFRNumber {
134
151
mpfr_set_ld (value, x, mpfr_rounding);
135
152
}
136
153
154
+ #ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
155
+ template <typename XType,
156
+ cpp::enable_if_t <cpp::is_same_v<float128, XType>, int > = 0 >
157
+ explicit MPFRNumber (XType x,
158
+ unsigned int precision = ExtraPrecision<XType>::VALUE,
159
+ RoundingMode rounding = RoundingMode::Nearest)
160
+ : mpfr_precision(precision),
161
+ mpfr_rounding(get_mpfr_rounding_mode(rounding)) {
162
+ mpfr_init2 (value, mpfr_precision);
163
+ mpfr_set_float128 (value, x, mpfr_rounding);
164
+ }
165
+ #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
166
+
137
167
template <typename XType,
138
168
cpp::enable_if_t <cpp::is_integral_v<XType>, int > = 0 >
139
169
explicit MPFRNumber (XType x,
@@ -647,7 +677,7 @@ class MPFRNumber {
647
677
// These functions are useful for debugging.
648
678
template <typename T> T as () const ;
649
679
650
- void dump (const char *msg) const { mpfr_printf (" %s%.128Rf \n " , msg, value); }
680
+ void dump (const char *msg) const { mpfr_printf (" %s%.128g \n " , msg, value); }
651
681
652
682
// Return the ULP (units-in-the-last-place) difference between the
653
683
// stored MPFR and a floating point number.
@@ -770,6 +800,13 @@ template <> float16 MPFRNumber::as<float16>() const {
770
800
}
771
801
#endif
772
802
803
+ #ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
804
+ template <> float128 MPFRNumber::as<float128>() const {
805
+ return mpfr_get_float128 (value, mpfr_rounding);
806
+ }
807
+
808
+ #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
809
+
773
810
namespace internal {
774
811
775
812
template <typename InputType>
@@ -997,7 +1034,27 @@ template void explain_unary_operation_single_output_error(Operation op, double,
997
1034
template void explain_unary_operation_single_output_error (Operation op,
998
1035
long double , float16,
999
1036
double , RoundingMode);
1000
- #endif
1037
+ #ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1038
+ template void explain_unary_operation_single_output_error (Operation op,
1039
+ float128, float16,
1040
+ double , RoundingMode);
1041
+ #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1042
+ #endif // LIBC_TYPES_HAS_FLOAT16
1043
+
1044
+ #ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1045
+ template void explain_unary_operation_single_output_error (Operation op,
1046
+ float128, float128,
1047
+ double , RoundingMode);
1048
+ template void explain_unary_operation_single_output_error (Operation op,
1049
+ float128, float ,
1050
+ double , RoundingMode);
1051
+ template void explain_unary_operation_single_output_error (Operation op,
1052
+ float128, double ,
1053
+ double , RoundingMode);
1054
+ template void explain_unary_operation_single_output_error (Operation op,
1055
+ float128, long double ,
1056
+ double , RoundingMode);
1057
+ #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1001
1058
1002
1059
template <typename T>
1003
1060
void explain_unary_operation_two_outputs_error (
@@ -1228,7 +1285,25 @@ template bool compare_unary_operation_single_output(Operation, double, float16,
1228
1285
template bool compare_unary_operation_single_output (Operation, long double ,
1229
1286
float16, double ,
1230
1287
RoundingMode);
1231
- #endif
1288
+ #ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1289
+ template bool compare_unary_operation_single_output (Operation, float128,
1290
+ float16, double ,
1291
+ RoundingMode);
1292
+ #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1293
+ #endif // LIBC_TYPES_HAS_FLOAT16
1294
+
1295
+ #ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1296
+ template bool compare_unary_operation_single_output (Operation, float128,
1297
+ float128, double ,
1298
+ RoundingMode);
1299
+ template bool compare_unary_operation_single_output (Operation, float128, float ,
1300
+ double , RoundingMode);
1301
+ template bool compare_unary_operation_single_output (Operation, float128, double ,
1302
+ double , RoundingMode);
1303
+ template bool compare_unary_operation_single_output (Operation, float128,
1304
+ long double , double ,
1305
+ RoundingMode);
1306
+ #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1232
1307
1233
1308
template <typename T>
1234
1309
bool compare_unary_operation_two_outputs (Operation op, T input,
@@ -1398,9 +1473,14 @@ template <typename T> bool round_to_long(T x, long &result) {
1398
1473
template bool round_to_long<float >(float , long &);
1399
1474
template bool round_to_long<double >(double , long &);
1400
1475
template bool round_to_long<long double >(long double , long &);
1476
+
1401
1477
#ifdef LIBC_TYPES_HAS_FLOAT16
1402
1478
template bool round_to_long<float16>(float16, long &);
1403
- #endif
1479
+ #endif // LIBC_TYPES_HAS_FLOAT16
1480
+
1481
+ #ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1482
+ template bool round_to_long<float128>(float128, long &);
1483
+ #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1404
1484
1405
1485
template <typename T> bool round_to_long (T x, RoundingMode mode, long &result) {
1406
1486
MPFRNumber mpfr (x);
@@ -1410,9 +1490,14 @@ template <typename T> bool round_to_long(T x, RoundingMode mode, long &result) {
1410
1490
template bool round_to_long<float >(float , RoundingMode, long &);
1411
1491
template bool round_to_long<double >(double , RoundingMode, long &);
1412
1492
template bool round_to_long<long double >(long double , RoundingMode, long &);
1493
+
1413
1494
#ifdef LIBC_TYPES_HAS_FLOAT16
1414
1495
template bool round_to_long<float16>(float16, RoundingMode, long &);
1415
- #endif
1496
+ #endif // LIBC_TYPES_HAS_FLOAT16
1497
+
1498
+ #ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1499
+ template bool round_to_long<float128>(float128, RoundingMode, long &);
1500
+ #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1416
1501
1417
1502
template <typename T> T round (T x, RoundingMode mode) {
1418
1503
MPFRNumber mpfr (x);
@@ -1423,9 +1508,14 @@ template <typename T> T round(T x, RoundingMode mode) {
1423
1508
template float round<float >(float , RoundingMode);
1424
1509
template double round<double >(double , RoundingMode);
1425
1510
template long double round<long double >(long double , RoundingMode);
1511
+
1426
1512
#ifdef LIBC_TYPES_HAS_FLOAT16
1427
1513
template float16 round<float16>(float16, RoundingMode);
1428
- #endif
1514
+ #endif // LIBC_TYPES_HAS_FLOAT16
1515
+
1516
+ #ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1517
+ template float128 round<float128>(float128, RoundingMode);
1518
+ #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
1429
1519
1430
1520
} // namespace mpfr
1431
1521
} // namespace testing
0 commit comments