Fix double-precision interval arithmetic in PBRT_FLOAT_AS_DOUBLE build

NextFloatUp(double) and NextFloatDown(double) were defined at line 326/340
in float.h, after AddRoundUp/AddRoundDown at line 199. At those call sites
only NextFloatUp/Down(float) was visible, so double arguments silently
converted to float — giving float-scale intervals even with Float=double.

Add forward declarations of the double overloads before AddRound* so
overload resolution selects the correct 64-bit implementation. This fixes
the earth-sphere penetration bug: the camera at 0.5m altitude now produces
a tiny double-precision c interval (~6.4 km²) instead of [-16, 28], and
t0 (the near intersection at 0.5m) is correctly selected over t1 (the
far intersection through the earth at 12742 km).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mark Bolstad 2026-06-14 16:41:58 -07:00 • committed by Matt Pharr
parent 0fef7de38d
commit 5f7a606806

View file

@ -196,6 +196,11 @@ inline constexpr Float gamma(int n) {
return (n * MachineEpsilon) / (1 - n * MachineEpsilon);
}
// Forward declarations so AddRound*/SubRound* select the correct overload
// when Float=double (otherwise only NextFloat*Up/Down(float) is in scope).
PBRT_CPU_GPU inline double NextFloatUp(double v);
PBRT_CPU_GPU inline double NextFloatDown(double v);
inline PBRT_CPU_GPU Float AddRoundUp(Float a, Float b) {
#ifdef PBRT_IS_GPU_CODE
#ifdef PBRT_FLOAT_AS_DOUBLE