Skip to content

Commit 1d2fe2f

Browse files
committed
fix
1 parent 357833b commit 1d2fe2f

File tree

2 files changed

+65
-61
lines changed

2 files changed

+65
-61
lines changed

libc/src/__support/FPUtil/NearestIntegerOperations.h

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -346,12 +346,13 @@ fromfpx(T x, int rnd, unsigned int width) {
346346

347347
namespace internal {
348348

349-
template <typename F, typename I,
350-
cpp::enable_if_t<cpp::is_floating_point_v<F> && cpp::is_integral_v<I>,
351-
int> = 0>
352-
LIBC_INLINE I rounded_float_to_signed_integer(F x) {
353-
constexpr I INTEGER_MIN = (I(1) << (sizeof(I) * 8 - 1));
354-
constexpr I INTEGER_MAX = -(INTEGER_MIN + 1);
349+
template <
350+
typename F, typename InType,
351+
cpp::enable_if_t<cpp::is_floating_point_v<F> && cpp::is_integral_v<InType>,
352+
int> = 0>
353+
LIBC_INLINE InType rounded_float_to_signed_integer(F x) {
354+
constexpr InType INTEGER_MIN = (InType(1) << (sizeof(InType) * 8 - 1));
355+
constexpr InType INTEGER_MAX = -(INTEGER_MIN + 1);
355356
FPBits<F> bits(x);
356357
auto set_domain_error_and_raise_invalid = []() {
357358
set_errno_if_required(EDOM);
@@ -364,7 +365,7 @@ LIBC_INLINE I rounded_float_to_signed_integer(F x) {
364365
}
365366

366367
int exponent = bits.get_exponent();
367-
constexpr int EXPONENT_LIMIT = sizeof(I) * 8 - 1;
368+
constexpr int EXPONENT_LIMIT = sizeof(InType) * 8 - 1;
368369
if (exponent > EXPONENT_LIMIT) {
369370
set_domain_error_and_raise_invalid();
370371
return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX;
@@ -374,29 +375,31 @@ LIBC_INLINE I rounded_float_to_signed_integer(F x) {
374375
return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX;
375376
}
376377
// If the control reaches here, then it means that the rounded
377-
// value is the most negative number for the signed integer type I.
378+
// value is the most negative number for the signed integer type InType.
378379
}
379380

380-
// For all other cases, if `x` can fit in the integer type `I`,
381+
// For all other cases, if `x` can fit in the integer type `InType`,
381382
// we just return `x`. static_cast will convert the floating
382383
// point value to the exact integer value.
383-
return static_cast<I>(x);
384+
return static_cast<InType>(x);
384385
}
385386

386387
} // namespace internal
387388

388-
template <typename F, typename I,
389-
cpp::enable_if_t<cpp::is_floating_point_v<F> && cpp::is_integral_v<I>,
390-
int> = 0>
391-
LIBC_INLINE I round_to_signed_integer(F x) {
392-
return internal::rounded_float_to_signed_integer<F, I>(round(x));
389+
template <
390+
typename F, typename InType,
391+
cpp::enable_if_t<cpp::is_floating_point_v<F> && cpp::is_integral_v<InType>,
392+
int> = 0>
393+
LIBC_INLINE InType round_to_signed_integer(F x) {
394+
return internal::rounded_float_to_signed_integer<F, InType>(round(x));
393395
}
394396

395-
template <typename F, typename I,
396-
cpp::enable_if_t<cpp::is_floating_point_v<F> && cpp::is_integral_v<I>,
397-
int> = 0>
398-
LIBC_INLINE I round_to_signed_integer_using_current_rounding_mode(F x) {
399-
return internal::rounded_float_to_signed_integer<F, I>(
397+
template <
398+
typename F, typename InType,
399+
cpp::enable_if_t<cpp::is_floating_point_v<F> && cpp::is_integral_v<InType>,
400+
int> = 0>
401+
LIBC_INLINE InType round_to_signed_integer_using_current_rounding_mode(F x) {
402+
return internal::rounded_float_to_signed_integer<F, InType>(
400403
round_using_current_rounding_mode(x));
401404
}
402405

libc/test/src/math/RoundToIntegerTest.h

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ using LIBC_NAMESPACE::Sign;
2626
static constexpr int ROUNDING_MODES[4] = {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO,
2727
FE_TONEAREST};
2828

29-
template <typename F, typename I, bool TestModes = false>
29+
template <typename F, typename OutType, bool TestModes = false>
3030
class RoundToIntegerTestTemplate
3131
: public LIBC_NAMESPACE::testing::FEnvSafeTest {
3232
public:
33-
typedef I (*RoundToIntegerFunc)(F);
33+
typedef OutType (*RoundToIntegerFunc)(F);
3434

3535
private:
3636
using FPBits = LIBC_NAMESPACE::fputil::FPBits<F>;
@@ -49,10 +49,11 @@ class RoundToIntegerTestTemplate
4949
static constexpr StorageType MIN_SUBNORMAL =
5050
FPBits::min_subnormal().uintval();
5151

52-
static constexpr I INTEGER_MIN = I(1) << (sizeof(I) * 8 - 1);
53-
static constexpr I INTEGER_MAX = -(INTEGER_MIN + 1);
52+
static constexpr OutType INTEGER_MIN = OutType(1)
53+
<< (sizeof(OutType) * 8 - 1);
54+
static constexpr OutType INTEGER_MAX = -(INTEGER_MIN + 1);
5455

55-
void test_one_input(RoundToIntegerFunc func, F input, I expected,
56+
void test_one_input(RoundToIntegerFunc func, F input, OutType expected,
5657
bool expectError) {
5758
LIBC_NAMESPACE::libc_errno = 0;
5859
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
@@ -120,24 +121,24 @@ class RoundToIntegerTestTemplate
120121
}
121122

122123
void do_round_numbers_test(RoundToIntegerFunc func) {
123-
test_one_input(func, zero, I(0), false);
124-
test_one_input(func, neg_zero, I(0), false);
125-
test_one_input(func, F(1.0), I(1), false);
126-
test_one_input(func, F(-1.0), I(-1), false);
127-
test_one_input(func, F(10.0), I(10), false);
128-
test_one_input(func, F(-10.0), I(-10), false);
129-
test_one_input(func, F(1234.0), I(1234), false);
130-
test_one_input(func, F(-1234.0), I(-1234), false);
124+
test_one_input(func, zero, OutType(0), false);
125+
test_one_input(func, neg_zero, OutType(0), false);
126+
test_one_input(func, F(1.0), OutType(1), false);
127+
test_one_input(func, F(-1.0), OutType(-1), false);
128+
test_one_input(func, F(10.0), OutType(10), false);
129+
test_one_input(func, F(-10.0), OutType(-10), false);
130+
test_one_input(func, F(1234.0), OutType(1234), false);
131+
test_one_input(func, F(-1234.0), OutType(-1234), false);
131132

132133
// The rest of this function compares with an equivalent MPFR function
133134
// which rounds floating point numbers to long values. There is no MPFR
134135
// function to round to long long or wider integer values. So, we will
135-
// the remaining tests only if the width of I less than equal to that of
136-
// long.
137-
if (sizeof(I) > sizeof(long))
136+
// the remaining tests only if the width of OutType less than equal to that
137+
// of long.
138+
if (sizeof(OutType) > sizeof(long))
138139
return;
139140

140-
constexpr int EXPONENT_LIMIT = sizeof(I) * 8 - 1;
141+
constexpr int EXPONENT_LIMIT = sizeof(OutType) * 8 - 1;
141142
constexpr int BIASED_EXPONENT_LIMIT = EXPONENT_LIMIT + FPBits::EXP_BIAS;
142143
if (BIASED_EXPONENT_LIMIT > FPBits::MAX_BIASED_EXPONENT)
143144
return;
@@ -179,7 +180,7 @@ class RoundToIntegerTestTemplate
179180
else
180181
erangeflag = mpfr::round_to_long(x, mpfr_long_result);
181182
ASSERT_FALSE(erangeflag);
182-
I mpfr_result = mpfr_long_result;
183+
OutType mpfr_result = mpfr_long_result;
183184
test_one_input(func, x, mpfr_result, false);
184185
}
185186
}
@@ -201,12 +202,12 @@ class RoundToIntegerTestTemplate
201202
// This function compares with an equivalent MPFR function which rounds
202203
// floating point numbers to long values. There is no MPFR function to
203204
// round to long long or wider integer values. So, we will peform the
204-
// comparisons in this function only if the width of I less than equal to
205-
// that of long.
206-
if (sizeof(I) > sizeof(long))
205+
// comparisons in this function only if the width of OutType less than equal
206+
// to that of long.
207+
if (sizeof(OutType) > sizeof(long))
207208
return;
208209

209-
constexpr int EXPONENT_LIMIT = sizeof(I) * 8 - 1;
210+
constexpr int EXPONENT_LIMIT = sizeof(OutType) * 8 - 1;
210211
constexpr int BIASED_EXPONENT_LIMIT = EXPONENT_LIMIT + FPBits::EXP_BIAS;
211212
if (BIASED_EXPONENT_LIMIT > FPBits::MAX_BIASED_EXPONENT)
212213
return;
@@ -248,22 +249,22 @@ class RoundToIntegerTestTemplate
248249
if (TestModes) {
249250
if (x > 0) {
250251
LIBC_NAMESPACE::fputil::set_round(FE_UPWARD);
251-
test_one_input(func, x, I(1), false);
252+
test_one_input(func, x, OutType(1), false);
252253
LIBC_NAMESPACE::fputil::set_round(FE_DOWNWARD);
253-
test_one_input(func, x, I(0), false);
254+
test_one_input(func, x, OutType(0), false);
254255
LIBC_NAMESPACE::fputil::set_round(FE_TOWARDZERO);
255-
test_one_input(func, x, I(0), false);
256+
test_one_input(func, x, OutType(0), false);
256257
LIBC_NAMESPACE::fputil::set_round(FE_TONEAREST);
257-
test_one_input(func, x, I(0), false);
258+
test_one_input(func, x, OutType(0), false);
258259
} else {
259260
LIBC_NAMESPACE::fputil::set_round(FE_UPWARD);
260-
test_one_input(func, x, I(0), false);
261+
test_one_input(func, x, OutType(0), false);
261262
LIBC_NAMESPACE::fputil::set_round(FE_DOWNWARD);
262-
test_one_input(func, x, I(-1), false);
263+
test_one_input(func, x, OutType(-1), false);
263264
LIBC_NAMESPACE::fputil::set_round(FE_TOWARDZERO);
264-
test_one_input(func, x, I(0), false);
265+
test_one_input(func, x, OutType(0), false);
265266
LIBC_NAMESPACE::fputil::set_round(FE_TONEAREST);
266-
test_one_input(func, x, I(0), false);
267+
test_one_input(func, x, OutType(0), false);
267268
}
268269
} else {
269270
test_one_input(func, x, 0L, false);
@@ -275,9 +276,9 @@ class RoundToIntegerTestTemplate
275276
// This function compares with an equivalent MPFR function which rounds
276277
// floating point numbers to long values. There is no MPFR function to
277278
// round to long long or wider integer values. So, we will peform the
278-
// comparisons in this function only if the width of I less than equal to
279-
// that of long.
280-
if (sizeof(I) > sizeof(long))
279+
// comparisons in this function only if the width of OutType less than equal
280+
// to that of long.
281+
if (sizeof(OutType) > sizeof(long))
281282
return;
282283

283284
constexpr int COUNT = 1'000'001;
@@ -297,7 +298,7 @@ class RoundToIntegerTestTemplate
297298
long mpfr_long_result;
298299
bool erangeflag = mpfr::round_to_long(x, to_mpfr_rounding_mode(m),
299300
mpfr_long_result);
300-
I mpfr_result = mpfr_long_result;
301+
OutType mpfr_result = mpfr_long_result;
301302
LIBC_NAMESPACE::fputil::set_round(m);
302303
if (erangeflag)
303304
test_one_input(func, x, x > 0 ? INTEGER_MAX : INTEGER_MIN, true);
@@ -307,7 +308,7 @@ class RoundToIntegerTestTemplate
307308
} else {
308309
long mpfr_long_result;
309310
bool erangeflag = mpfr::round_to_long(x, mpfr_long_result);
310-
I mpfr_result = mpfr_long_result;
311+
OutType mpfr_result = mpfr_long_result;
311312
if (erangeflag)
312313
test_one_input(func, x, x > 0 ? INTEGER_MAX : INTEGER_MIN, true);
313314
else
@@ -317,9 +318,9 @@ class RoundToIntegerTestTemplate
317318
}
318319
};
319320

320-
#define LIST_ROUND_TO_INTEGER_TESTS_HELPER(F, I, func, TestModes) \
321+
#define LIST_ROUND_TO_INTEGER_TESTS_HELPER(F, OutType, func, TestModes) \
321322
using LlvmLibcRoundToIntegerTest = \
322-
RoundToIntegerTestTemplate<F, I, TestModes>; \
323+
RoundToIntegerTestTemplate<F, OutType, TestModes>; \
323324
TEST_F(LlvmLibcRoundToIntegerTest, InfinityAndNaN) { \
324325
testInfinityAndNaN(&func); \
325326
} \
@@ -335,10 +336,10 @@ class RoundToIntegerTestTemplate
335336
} \
336337
TEST_F(LlvmLibcRoundToIntegerTest, NormalRange) { testNormalRange(&func); }
337338

338-
#define LIST_ROUND_TO_INTEGER_TESTS(F, I, func) \
339-
LIST_ROUND_TO_INTEGER_TESTS_HELPER(F, I, func, false)
339+
#define LIST_ROUND_TO_INTEGER_TESTS(F, OutType, func) \
340+
LIST_ROUND_TO_INTEGER_TESTS_HELPER(F, OutType, func, false)
340341

341-
#define LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(F, I, func) \
342-
LIST_ROUND_TO_INTEGER_TESTS_HELPER(F, I, func, true)
342+
#define LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(F, OutType, func) \
343+
LIST_ROUND_TO_INTEGER_TESTS_HELPER(F, OutType, func, true)
343344

344345
#endif // LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H

0 commit comments

Comments
 (0)