Num::HexFloat
NAME
Num::HexFloat - Rudimentary C99 Hexadecimal Floating Point Support in Perl6
STATUS: MOSTLY OBSOLETE
Rakudo has grown native C99 hexadecimal floating point support. It is
not in the 2026.07 release, but it is in main as of 2026-08-07 and
is expected to ship in 2026.08:
0860b287c ā hexadecimal float literals (
0x1.8p+1), in both the legacy and the RakuAST grammars.999492263 / Raku/nqp#859 ā
%a/%Adirectives insprintf,printfand.fmt.669ad276d ā the same
%a/%Adirectives in the RakuASTFormatterthat becomes thesprintfengine under6.e.
So on a recent enough Rakudo you no longer need this module for the common cases:
say 0x1.921fb54442d18p+1 === pi; # True -- was from-hexfloat(...)
say pi.fmt("%a"); # 0x1.921fb54442d18p+1
# -- was to-hexfloat(pi)
say sprintf("%.3a", pi); # 0x1.922p+1What is still not native
Rakudo parses hexadecimal floats at compile time only. There is no
runtime Str ā Num conversion ā p+1 still looks like trailing
garbage to the numeric grammar, so "0x1.8p+1".Num and +"0x1.8p+1"
throw X::Str::Numeric ("trailing characters after number"), and
val("0x1.8p+1") declines to numify and hands back a plain Str.
That leaves exactly one job for this module ā digging hexadecimal floats out of text you did not write yourself:
my $src = "e=0x1.5bf0a8b145769p+1, pi=0x1.921fb54442d18p+1";
say $src.subst($RE_HEXFLOAT, &from-hexfloat, :g);If your hexfloats are literals in your source, or you only need to print them, drop the dependency and use the built-ins.
Differences from the built-ins
to-hexfloat and %a agree byte-for-byte on every finite value,
including subnormals and the extremes (0x1p-1074,
0x1.fffffffffffffp+1023). They differ only on the non-finite ones:
this module follows C and prints inf / -inf / nan, while %a
follows Raku and prints Inf / -Inf / NaN, as %e, %f and %g
already do.
The built-in %a also supports the C flags this module never had:
precision (%.3a), uppercase (%A), width and zero padding (%016a,
which pads between the 0x and the mantissa), and # to keep the radix
point.
SYNOPSIS
use v6;
use Num::HexFloat;
say to-hexfloat(pi);
# '0x1.921fb54442d18p+1'
say from-hexfloat('0x1.921fb54442d18p+1') == pi;
# True
my $src = "e=0x1.5bf0a8b145769p+1, pi=0x1.921fb54442d18p+1";
say $src.subst($RE_HEXFLOAT, &from-hexfloat, :g);
# e=2.71828182845905, pi=3.14159265358979DESCRIPTION
Num::HexFloat exports the following:
$RE_HEXFLOAT
A regex that matches hexadecimal floating point notation.
from-hexfloat($arg) returns Num
Parses $arg as a C99 hexadecimal floating point notation and returns
Num, or NaN if it fails.
$arg can be either Str or Match so you can go like:
$src.subst($RE_HEXFLOAT, &from-hexfloat, :g);to-hexfloat(Numeric $num) returns Str
Stringifies $num in C99 hexadecimal floating point notation.