From be80106ba18446692fb9412cf4e5dc5b1300e93a Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 2 Oct 2026 20:52:57 +0000 Subject: [PATCH] Avoid ldexp call when converting random numbers to double prn() converted the 64-bit output of the generator to a double in [0, 1) with ldexp(result, -64), which compiles to an out-of-line library call on every random number. Multiplying by the exact power of two 0x1p-64 gives bit-for-bit identical results (the scaling is exact and cannot underflow) and compiles to a single instruction. Random numbers and simulation results are unchanged. Transport time is reduced by about 7% for a neutron source in a heavy water sphere with thermal scattering and by about 4% for a gamma shielding problem. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_014RN7JroEkrbkLKVHbMDap9 --- src/random_lcg.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/random_lcg.cpp b/src/random_lcg.cpp index 5bdedc59083..1faf8306026 100644 --- a/src/random_lcg.cpp +++ b/src/random_lcg.cpp @@ -1,7 +1,5 @@ #include "openmc/random_lcg.h" -#include - namespace openmc { // Starting seed @@ -78,8 +76,9 @@ double prn(uint64_t* seed) ((*seed >> ((*seed >> 59u) + 5u)) ^ *seed) * 12605985483714917081ull; uint64_t result = (word >> 43u) ^ word; - // Convert output from unsigned integer to double - return ldexp(result, -64); + // Convert output from unsigned integer to double. Multiplying by an exact + // power of two gives the same result as ldexp but avoids a library call. + return static_cast(result) * 0x1p-64; } //==============================================================================