print-float ( value -- string )
Ryū Float to String Conversion

Next:d2s ( value -- string )


Vocabulary
ryu

Inputs
valuea number


Outputs
stringa string


Word description
Convert the number into its shortest stable floating-point representation string using the Ryū algorithm.

Definition


:: print-float ( value -- string )
value >float unpack-bits
:> ( e2 m2 acceptBounds ieeeExponent<=1 sign output ) output
[
m2 4 * :> mv mantissaBits 2^ m2 = not ieeeExponent<=1 or
1 0 ?
:> mmShift f f 0 0 0
:> ( vmIsTrailingZeros! vrIsTrailingZeros! e10! vr! vm!
) e2 0 >= [
e2 DOUBLE_LOG10_2_NUMERATOR *
DOUBLE_LOG10_2_DENOMINATOR /i 0 max
:> q q e10! q double-pow-5-bits
DOUBLE_POW5_INV_BITCOUNT + 1 - :> k q k + e2 -
:> i mmShift m2 q DOUBLE_POW5_INV_SPLIT nth-unsafe
i mul-shift-all vr! swap vm! q 21 <= [
mv 5 divisor? [
q mv multiple-of-power-of-5
vrIsTrailingZeros!
] [
acceptBounds [
q mv mmShift - 1 -
multiple-of-power-of-5
vmIsTrailingZeros!
]
[ q mv 2 + multiple-of-power-of-5 1 0 ? - ]
if
] if
] when
] [
e2 neg DOUBLE_LOG10_5_NUMERATOR *
DOUBLE_LOG10_5_DENOMINATOR /i 1 [-] :> q q e2 +
e10! e2 neg q -
:> i i double-pow-5-bits DOUBLE_POW5_BITCOUNT -
:> k q k -
:> j mmShift m2 i DOUBLE_POW5_SPLIT nth-unsafe
j mul-shift-all vr! swap vm! q 1 <= [
mv 1 bitand bitnot q >=
vrIsTrailingZeros! acceptBounds [
mv 1 - mmShift - bitnot 1 bitand q >=
vmIsTrailingZeros!
] [ 1 - ] if
] [
q 63 < [
q 1 - on-bits mv bitand
zero? vrIsTrailingZeros!
] when
] if
] if [ decimal-length e10 + 1 - sign ] keep
acceptBounds vmIsTrailingZeros vrIsTrailingZeros vr vm
prepare-output produce-output
] unless* ;