Skip to content

fix: detect NaN and infinity from the bits of the double - #207

Merged
brenocq merged 1 commit into
mainfrom
fix/nan-bit-check
Oct 25, 2026
Merged

brenocq merged 1 commit into
mainfrom
fix/nan-bit-check

Conversation

@brenocq

@brenocq brenocq commented Oct 25, 2026

Copy link
Copy Markdown
Owner

ImNan() calls the unqualified isnan, which only compiles if the right math header wins. When <cmath> is included before ImPlot3D and the C library's <math.h> is found ahead of the C++ one, isnan is not declared at all. That happens, for example, when a sysroot include directory is passed with -I. std::isnan doesn't fix it either: it breaks in other setups, such as libc++ without <cmath>. There is also a runtime problem. With -ffast-math, the compiler may assume NaN never exists and delete the check, so NaN points get drawn instead of skipped.

ImNan() and ImNanOrInf() now read the bits of the double and check the IEEE-754 pattern directly. NaN means all exponent bits are set and the mantissa is nonzero, and infinity or NaN means all exponent bits are set. This needs no math header, and it keeps working under -ffast-math and /fp:fast. In finite-math builds, an empty asm statement keeps clang from folding the test away. Mirrors the same fix in ImPlot (epezent/implot#565).

ImNan called the unqualified isnan, which fails to build when <cmath>
is included before ImPlot3D and the C library's <math.h> is found ahead
of the C++ one (a sysroot or system include directory passed with -I):
isnan is then neither a macro nor a global function. Switching to
std::isnan only moves the failure to other setups, such as libc++
without <cmath>.

ImNan and ImNanOrInf now copy the double into an ImU64 and test the
IEEE-754 exponent and mantissa, so they need no math header, and unlike
isnan or val != val they keep detecting NaN under -ffast-math and
/fp:fast, where the compiler may delete floating-point NaN checks.
Under -ffinite-math-only an empty asm statement hides the bits from
the optimizer, since clang otherwise folds the exponent test to false.
Mirrors the same fix in ImPlot (epezent/implot#565).
@brenocq brenocq added type:fix Something isn't working prio:medium Medium priority status:review The task is under review labels Oct 25, 2026
@brenocq brenocq self-assigned this Oct 25, 2026
@brenocq
brenocq merged commit b997e35 into main Oct 25, 2026
10 checks passed
@brenocq
brenocq deleted the fix/nan-bit-check branch October 25, 2026 14:58
@github-actions github-actions Bot added status:done Task completed successfully and removed status:review The task is under review labels Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

prio:medium Medium priority status:done Task completed successfully type:fix Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant