by Peter McGoron
This SRFI is currently in draft status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to srfi-270@nospamsrfi.schemers.org. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.
Floating-point numbers are generally in radix 2, but are written by users in radix 10. This SRFI introduces Scheme syntax for hexadecimal floating point constants based on C99's syntax.
Computers generally use binary floating point to store numbers, while humans like decimals. To express binary floating point exactly, one can use hexadecimal floating point constants, which are written in base 16 instead of base 10. They represent binary floating point numbers of any mantissa and exponent size precisely.
Prior art: MIT Scheme supports a version of this syntax. C99 introduced a hexadecimal floating point syntax that was then adopted in IEEE 754-2008.
Non-normative text is in small text.
The following is written in Scheme's BNF, extended with the following: ⟨thing⟩? means zero or one of ⟨thing⟩.
The formal syntax of Scheme is modified to have the following new productions:
. ⟨digit 16⟩+. ⟨digit 16⟩*p ⟨sign⟩? ⟨digit 10⟩+
Without an exactness prefix, a hex float is read as an inexact
number. Like all numbers, hex floats can be read as exact numbers
by prefixing them with #e.
The exponential separator is p because it is ambiguous
whether e would be a decimal separator or a hex digit.
A hexadecimal floating point number is interpreted such that
xnxn−1…x0.x−1x−2…x−mpd
where each x is a hexadecimal digit and d is a base 10 number, is equal to
(Xn×16n + Xn−1×16n−1 + … + X0 + X−1×16−1 + X−2×16−2 + … + X−m×16−m)×2d
where Xi is the numerical value of the digit xi.
On R6RS systems, the above grammar is modified to be:
pPThe R6RS considerations for numbers with ⟨exponent marker⟩ and ⟨mantissa width⟩ apply here.
This grammar is a superset of the previous grammar.
The procedure string->number must understand hexadecimal
floats.
(write-hexadecimal-float x [port])Write an inexact real as a floating point number. If the number is represented by an IEEE 754 binary floating point number, then the number must be represented in a canonical form. If the number is a real, then:
If the number is complex, then each component must be printed with the above rules.
This section is non-normative.
| Expression | Number |
|---|---|
#x9p9 |
9×29 = 4608 |
#x1.2p3 |
(1 + 2×16−1)×23 = 9 |
#xFE.FFp1 |
(15×161 + 14 + 15×16−1 + 15×16−2)×21 = 1044465/2048 ≈ 509.992… |
#x-0.Ap-2 |
(10×16−1)×2−2 = −5/32 = −.15625 |
#x1.2p3+10p1i |
9+256i |
A portable implementation is impossible, as it depends on both modifying the reader and knowing the specific representation of inexact reals.
An implementation-specific version will be written.
Taylor Campbell suggested it to me on #scheme.
© 2026 Peter McGoron.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.