Skip to content

Commit d64a701

Browse files
committed
bug fix on the incorrectly modified ulp() function on native ieee754 floating-point numbers
1 parent 147704b commit d64a701

File tree

5 files changed

+18
-16
lines changed

5 files changed

+18
-16
lines changed

include/universal/native/ieee754_numeric.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ namespace sw { namespace universal {
1616
typename = typename ::std::enable_if< ::std::is_floating_point<Real>::value, Real >::type
1717
>
1818
inline Real ulp(const Real& a) {
19-
return std::nextafter(a, Real(INFINITY)) - a;
19+
Real next = ((a < 0) ? std::nextafter(a, Real(-INFINITY)) : std::nextafter(a, Real(+INFINITY)));
20+
return next - a;
2021
}
2122

2223
// check if the floating-point number is zero

include/universal/number/cfloat/cfloat.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ using fp8e5m2 = cfloat<8, 5, std::uint8_t, true, true, false>;
121121
// ShowRepresentations prints the different output formats for the Scalar type
122122
// TODO: guard with cfloat trait
123123
template<typename Scalar>
124-
void ShowRepresentations(std::ostream& ostr, float f) {
124+
void ShowRepresentations(std::ostream& ostr, Scalar f) {
125125
auto oldprec = ostr.precision(); // save stream state
126126

127127
constexpr int max_digits10 = std::numeric_limits<Scalar>::max_digits10; // floating-point attribute for printing scientific format

include/universal/number/qd/math/pow.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ namespace sw { namespace universal {
2828
// NOTE: 0^0 causes an error.
2929
qd npwr(const qd& a, int n) {
3030
if (n == 0) {
31-
#if DOUBLEDOUBLE_THROW_ARITHMETIC_EXCEPTION
31+
#if QUADDOUBLE_THROW_ARITHMETIC_EXCEPTION
3232
if (a.iszero()) throw qd_invalid_argument();
33-
#else // ! DOUBLEDOUBLE_THROW_ARITHMETIC_EXCEPTION
33+
#else // ! QUADDOUBLE_THROW_ARITHMETIC_EXCEPTION
3434
if (a.iszero()) {
3535
std::cerr << "(npwr): Invalid argument\n";
3636
return qd(SpecificValue::snan);
3737
}
38-
#endif // ! DOUBLEDOUBLE_THROW_ARITHMETIC_EXCEPTION
38+
#endif // ! QUADDOUBLE_THROW_ARITHMETIC_EXCEPTION
3939
return 1.0;
4040
}
4141

static/cfloat/conversion/float_conversion.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include <universal/verification/cfloat_test_suite.hpp>
2020
//#include <universal/number/cfloat/table.hpp> // only used for value table generation
2121

22-
#if BIT_CAST_IS_CONSEXPR
22+
#if BIT_CAST_IS_CONSTEXPR
2323
void ToNativeBug() { // now resolved... exponentiation was incorrect
2424
using namespace sw::universal;
2525
constexpr size_t nbits = 32;
@@ -44,12 +44,12 @@ void ToNativeBug() { // now resolved... exponentiation was incorrect
4444
// bit cast
4545
uint32_t bc = std::bit_cast<uint32_t, float>(f);
4646
std::cout << "float : " << to_binary(f) << '\n';
47-
std::cout << "smask : " << to_binary(ieee754_parameter<float>::smask, 32, false) << '\n';
48-
std::cout << "emask : " << to_binary(ieee754_parameter<float>::emask, 32, false) << '\n';
49-
std::cout << "fmask : " << to_binary(ieee754_parameter<float>::fmask, 32, false) << '\n';
50-
std::cout << "smask+bc : " << to_binary((ieee754_parameter<float>::smask & bc), 32, false) << '\n';
51-
std::cout << "emask+bc : " << to_binary((ieee754_parameter<float>::emask & bc), 32, false) << '\n';
52-
std::cout << "fmask+bc : " << to_binary((ieee754_parameter<float>::fmask & bc), 32, false) << '\n';
47+
std::cout << "smask : " << to_binary(ieee754_parameter<float>::smask, false, 32) << '\n';
48+
std::cout << "emask : " << to_binary(ieee754_parameter<float>::emask, false, 32) << '\n';
49+
std::cout << "fmask : " << to_binary(ieee754_parameter<float>::fmask, false, 32) << '\n';
50+
std::cout << "smask+bc : " << to_binary((ieee754_parameter<float>::smask & bc), false, 32) << '\n';
51+
std::cout << "emask+bc : " << to_binary((ieee754_parameter<float>::emask & bc), false, 32) << '\n';
52+
std::cout << "fmask+bc : " << to_binary((ieee754_parameter<float>::fmask & bc), false, 32) << '\n';
5353
// uint32_t rawSignbits = (ieee754_parameter<float>::smask & bc);
5454
uint32_t rawExponentBits = (ieee754_parameter<float>::emask & bc) >> ieee754_parameter<float>::fbits;
5555
uint32_t rawFractionBits = (ieee754_parameter<float>::fmask & bc);

static/native/float/nextafter.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <cmath>
99
#include <concepts>
1010
#include <cfenv>
11+
#include <cfloat>
1112
#include <universal/verification/test_suite.hpp>
1213

1314
// Regression testing guards: typically set by the cmake configuration, but MANUAL_TESTING is an override
@@ -73,11 +74,11 @@ try {
7374
{
7475
// #pragma STDC FENV_ACCESS ON
7576
std::feclearexcept(FE_ALL_EXCEPT);
76-
double from4 = DBL_MAX, to4 = std::nextafter(from4, INFINITY);
77+
double from = DBL_MAX, to = std::nextafter(from, INFINITY);
7778
std::cout << "The next representable double after " << std::setprecision(6)
78-
<< from4 << std::hexfloat << " (" << from4 << ')'
79-
<< std::defaultfloat << " is " << to4
80-
<< std::hexfloat << " (" << to4 << ")\n" << std::defaultfloat;
79+
<< from << std::hexfloat << " (" << from << ')'
80+
<< std::defaultfloat << " is " << to
81+
<< std::hexfloat << " (" << to << ")\n" << std::defaultfloat;
8182

8283
if (std::fetestexcept(FE_OVERFLOW))
8384
std::cout << " raised FE_OVERFLOW\n";

0 commit comments

Comments
 (0)