From 5f7a606806a4ac7b939131ded9d7a30ebd02416e Mon Sep 17 00:00:00 2001 From: Mark Bolstad Date: Sun, 14 Jun 2026 16:41:58 -0700 Subject: [PATCH] Fix double-precision interval arithmetic in PBRT_FLOAT_AS_DOUBLE build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/pbrt/util/float.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pbrt/util/float.h b/src/pbrt/util/float.h index ab9e6447..32c50360 100644 --- a/src/pbrt/util/float.h +++ b/src/pbrt/util/float.h @@ -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