I would like to make two suggestions:
1) I think it makes sense to relax the syntax by making <hex float suffix>
optional. This would allow conforming implementations to read "fixed"
hexadecimal syntax used by some implementations, e.g. Chez Scheme. The dot
is still present to distinguish the output from an exact integer.
Examples (Chez Scheme):
#x42C1AC1.4858358 => 69999297.28259596
#x3.243F6A8885A3 => 3.141592653589793
2) while (write-hexadecimal-float z [port]) may guarantee that the output
format fully conforms to C99/IEEE 754 notation with leading 1 and explicit
exponent, (number->string z 16) may be allowed to produce any
mathematically correct representation, including ones that start with any
hex digit and have a dot but no exponent. This would make Chez Scheme's
number->string conforming to this SRFI:
> (number->string 69999297.282595962 16)
"42C1AC1.4858358"
Relaxing it this way would allow Scheme implementation to use hexadecimal
notations that feel more natural. I would suggest implementors to consider
a "hex-engineering" notation, where the first printed hex digit is chosen
in a way that makes the printed exponent a multiple of four (or suppressed
altogether if it makes the resulting output shorter). This has the
following benefits for us, humans:
- This aligns the binary point exactly with hexadecimal digit boundaries.
- If you multiply or divide a number by a power of 16, the hexadecimal
digits in the output remain identical. Only the dot moves or the exponent
changes, mimicking how decimal engineering notation behaves.
- It is more visually 'stable' in presence of relatively small value
changes
This 'engineering' format is non-rounding: every bit of the internal
floating-point mantissa is extracted and printed; the string represents the
exact value held in memory.
Note how the hexadecimal digits (the "shape" of the number) remain constant
as the value is scaled by 16. This makes patterns in raw binary data much
easier to recognize:
Value * 16^0: #x1.234p+0
Value * 16^1: #x12.34p+0
Value * 16^2: #x123.4p+0
Value * 16^3: #x1.234p+12 (Switch to exponent to save space)
Value * 16^4: #x12.34p+12 (Digits stay "1234")
Digits of the 'standard' notations tend to shift/jitter, hiding the actual
differences between numbers:
Value: 7.5 --> #x1.Ep+2
Value: 8.5 --> #x1.1p+3
Even though the values are close, the hex digits changed entirely (1E vs
11) because the binary point moved. This makes it hard to "eyeball" the
difference between values.
In the alternative notation, digits remain 'anchored', their positional
meaning is preserved:
Value: 7.5 --> 0x7.8
Value: 8.5 --> 0x8.8
-S