Skip to content

Commit

Permalink
[omg] Make signaling NAN a template for float and double
Browse files Browse the repository at this point in the history
  • Loading branch information
PiaNumworks authored and GabrielNumworks committed Apr 3, 2023
1 parent f13e608 commit a7ba636
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 5 deletions.
2 changes: 1 addition & 1 deletion apps/shared/continuous_function_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void ContinuousFunctionCache::ComputeNonCartesianSteps(float *tStep,
// private
void ContinuousFunctionCache::invalidateBetween(int iInf, int iSup) {
for (int i = iInf; i < iSup; i++) {
m_cache[i] = OMG::SignalingNan();
m_cache[i] = OMG::SignalingNan<float>();
}
}

Expand Down
1 change: 1 addition & 0 deletions omg/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ SFLAGS += -Iomg/include
omg_src += $(addprefix omg/src/,\
print.cpp \
directions.cpp \
signaling_nan.cpp\
)

tests_src += $(addprefix omg/test/,\
Expand Down
19 changes: 16 additions & 3 deletions omg/include/omg/signaling_nan.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,32 @@ union IntFloat {
float f;
};

union IntDouble {
uint64_t i;
double d;
};

#if __EMSCRIPTEN__
/* Emscripten cannot represent a NaN literal with custom bit pattern in
* NaN-canonicalizing JS engines. We use a magic number instead. */
constexpr static IntFloat k_sNanFloat = IntFloat{.f = -1.7014118346e+38};
constexpr static IntDouble k_sNanDouble = IntDouble{.d = -1.7014118346e+38};
#else
/* 0x7fa00000 corresponds to std::numeric_limits<float>::signaling_NaN() */
/* 0x7fa00000 corresponds to std::numeric_limits<float>::signaling_NaN()
* 0x7ff4000000000000 corresponds to
* std::numeric_limits<double>::signaling_NaN() */
constexpr static IntFloat k_sNanFloat = IntFloat{.i = 0x7fa00000};
constexpr static IntDouble k_sNanDouble = IntDouble{.i = 0x7ff4000000000000};
#endif

static bool IsSignalingNan(float f) {
constexpr static bool IsSignalingNan(float f) {
return IntFloat{.f = f}.i == k_sNanFloat.i;
}
static float SignalingNan() { return k_sNanFloat.f; }
constexpr static bool IsSignalingNan(double d) {
return IntDouble{.d = d}.i == k_sNanDouble.i;
}
template <typename T>
T SignalingNan();

} // namespace OMG

Expand Down
14 changes: 14 additions & 0 deletions omg/src/signaling_nan.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <omg/signaling_nan.h>

namespace OMG {

template <typename T>
T SignalingNan() {
return sizeof(T) == sizeof(float) ? static_cast<T>(k_sNanFloat.f)
: static_cast<T>(k_sNanDouble.d);
}

template float SignalingNan<float>();
template double SignalingNan<double>();

} // namespace OMG
4 changes: 3 additions & 1 deletion omg/test/signaling_nan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using namespace OMG;

QUIZ_CASE(omg_signaling_nan) {
quiz_assert(OMG::IsSignalingNan(OMG::SignalingNan()));
quiz_assert(OMG::IsSignalingNan(OMG::SignalingNan<float>()));
quiz_assert(OMG::IsSignalingNan(OMG::SignalingNan<double>()));
quiz_assert(!OMG::IsSignalingNan(static_cast<float>(NAN)));
quiz_assert(!OMG::IsSignalingNan(static_cast<double>(NAN)));
}

0 comments on commit a7ba636

Please sign in to comment.