From 82895ec866cf25f5f89070031cf5054ea5b6d177 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 23 Sep 2026 04:52:58 +0200 Subject: [PATCH] R-AI: pin render_f32's sign-bit extraction on a negative value Every existing render_f32 test (including the two added in the previous commit) used a positive value, so a mutant that shifts the sign-bit read the wrong direction (bits << 31 instead of bits >> 31, reading bit 0 instead of bit 31) went unnoticed: 1.0_f32 and 2.0_f32 both happen to have bit 0 equal to 0, same as their real (positive) sign bit, so the mutant computed the same "not negative" answer by coincidence. Co-Authored-By: Claude Sonnet 5 --- packages/cultnet-rs/src/selection.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/cultnet-rs/src/selection.rs b/packages/cultnet-rs/src/selection.rs index 0fb282f1..3df42a7b 100644 --- a/packages/cultnet-rs/src/selection.rs +++ b/packages/cultnet-rs/src/selection.rs @@ -469,6 +469,19 @@ pub mod canonical_number { assert_eq!(super::render_f32(2.0_f32).unwrap(), "2"); } + // R-AI: `(bits >> 31) & 1 == 1` reads the sign bit - but 1.0_f32 and 2.0_f32 (bit pattern + // 0x3F800000 / 0x40000000) both happen to have their *low* bit (bit 0) equal to 0, same as + // their real sign bit (bit 31, also 0 for a positive value) - so a mutant that shifts the + // wrong direction (`bits << 31` instead of `bits >> 31`, reading bit 0 instead of bit 31) + // computes the same "not negative" answer for both by coincidence, and every render test + // above only used positive values. A negative value whose bit 0 differs from its sign bit + // (any of them - the mantissa/exponent bits are unrelated to bit 0) exposes it. + #[test] + fn render_f32_negative_values_carry_the_sign() { + assert_eq!(super::render_f32(-1.0_f32).unwrap(), "-1"); + assert_eq!(super::render_f32(-2.0_f32).unwrap(), "-2"); + } + // R-AI/R-D: `is_canonical` is the Q-J door's grammar // (`^-?(0|[1-9][0-9]*)(\.[0-9]*[1-9])?$`, minus the literal "-0") and was, until this test, // never called directly by any test in this crate - only reachable through