etc.c: lossless rotation encoding for 32-bit float32 word boxing

replace lossy 2-bit truncation with rotation-based encoding for
32-bit + MRB_USE_FLOAT32, matching the technique used for 64-bit
float64. rotl32(bits - ADDEND, 3) maps biased exponents [95, 158]
(actual [-32, +31]) to properly tagged inline values with zero
precision loss. special values (0, Inf, NaN) use sentinel constants;
out-of-range floats fall back to heap-allocated RFloat.

also fix a pre-existing alignment issue: RVALUE was 20 bytes on
32-bit, causing 4-byte-aligned objects to be misidentified as
immediates by word boxing (WORDBOX_IMMEDIATE_MASK=0x07 requires
8-byte alignment). pad RVALUE to 24 bytes on 32-bit + float32.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-02-22 17:51:01 +09:00
parent 2031ae9f90
commit 14a5cfb87f
4 changed files with 145 additions and 31 deletions
+1 -1
View File
@@ -178,7 +178,7 @@ mrb_integer_func(mrb_value o) {
#ifndef MRB_NO_FLOAT
#ifdef MRB_WORDBOX_NO_FLOAT_TRUNCATE
#define mrb_float_p(o) WORDBOX_OBJ_TYPE_P(o, FLOAT)
#elif defined(MRB_USE_FLOAT32)
#elif defined(MRB_USE_FLOAT32) && defined(MRB_64BIT)
#define mrb_float_p(o) WORDBOX_SHIFT_VALUE_P(o, FLOAT)
#else
/* rotation encoding: most floats inline, edge cases on heap */