
Issue #20662 has been updated by nobu (Nobuyoshi Nakada). Description updated cabo (Carsten Bormann) wrote:
pack("G")/unpack("G") works great with NaN values. However,
First, Ruby provides only `Float::NAN`, and does not consider payloads of NaN values.
- `pack("g")` completely discards any actual NaN value and always packs the same bytes for a NaN ("bug as implemented" in `VALUE_to_float`)
Since `"G"` preserves the payload, it may be better to preserve it for `"g"` as well, IMO.
- `unpack("g")` always sets the quiet bit to 1 in the `Float` result (location of bug not obvious to me)
Ruby's `Float` uses `double` always. Although I don't remember about NaN and its conversion in IEEE-754 well, clang on macOS appears not to wrap around it at casts between `float` and `double`, for instance. ```C #include <float.h> #include <stdint.h> #include <stdio.h> int main(void) { union { uint32_t b; float f; } x; x.b = 0x7fbff000; printf("%x\n", x.b); double f = x.f; printf("%f\n", f); x.f = (float)f; printf("%x\n", x.b); return 0; } ``` ```shell-session $ clang -ggdb nan-dbl.c && ./a.out 7fbff000 nan 7ffff000 ```
pack("G")/unpack("G") works great with NaN values. However,
# - pack("g") completely discards any actual NaN value and always packs the same bytes for a NaN # ("bug as implemented" in VALUE_to_float)
Also:
# - unpack("g") always sets the quiet bit to 1 in the Float result # (location of bug not obvious to me)
---------------------------------------- Bug #20662: pack("g") completely discards any actual NaN value and always packs the same single-precision bytes for a NaN https://bugs.ruby-lang.org/issues/20662#change-109335 * Author: cabo (Carsten Bormann) * Status: Open * ruby -v: ruby 3.3.4 (2024-07-09 revision be1089c8ec) [arm64-darwin23] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- `pack("G")`/`unpack("G")` works great with NaN values. However, - `pack("g")` completely discards any actual NaN value and always packs the same bytes for a NaN ("bug as implemented" in `VALUE_to_float`) Also: - `unpack("g")` always sets the quiet bit to 1 in the `Float` result (location of bug not obvious to me) ---Files-------------------------------- showbug.rb (3.21 KB) showbug-arm.txt (5.48 KB) showbug-intel.txt (5.48 KB) -- https://bugs.ruby-lang.org/