Gforth now has three new words:
E. ( r -- ) prints an FP number r in a format that is understood by
Gforth's text interpreter and produces the same number. Tries to
produce short outputs.
E.EXACT ( r -- ) prints an FP number, showing all (possibly hundreds)
of the mantissa digits.
E.P ( r u -- ) prints an FP number with at most u (or, if that saves
printing an exponent, u+1) mantissa digits.
Example usage and output (as comment):
: s-as-f {: w^ n :} n f@ ;
0e e. \ 0e ok
1e e. \ 1e ok
0.1e e. \ .1e ok
0.00005e e. \ .00005e ok
0.000005e e. \ 5e-6 ok
2000e e. \ 2e3 ok
20000e e. \ 2e4 ok
1 s-as-f e. \ 5e-324 ok
Note that the latter number takes more than 700 digits when printed
with e.exact; only one mantissa digit is necessary to distinguish it
from other numbers, because the next FP number has a value close to
1e-323.
0e e.exact \ 0e ok
1e e.exact \ 1e ok
0.1e e.exact \ .1000000000000000055511151231257827021181583404541015625e ok
0.00005e e.exact \ .0000500000000000000023960868011929647991564706899225711822509765625e ok
0.000005e e.exact \ 5.0000000000000004090152695701565477293115691281855106353759765625e-6 ok
2000e e.exact \ 2000e ok
20000e e.exact \ 20000e ok
2e23 e.exact \ 199999999999999983222784e ok
Note that the difference between the input and the output in these
cases comes from the input side (>FLOAT): 0.1e, 0.00005e, 0.000005e
and 2e23 cannot be represented exactly in binary64 (IEEE
double-precision) FP, do >FLOAT produces the FP number closest to the
decimal representation. E.EXACT then prints all the digits of this
number, while E. prints a number that is close and consumes as few
digits as possible.
0e 6 e.p \ 0e ok
1e 6 e.p \ 1e ok
0.1e 6 e.p \ .1e ok
0.00005e 6 e.p \ .00005e ok
0.000005e 6 e.p \ 5e-6 ok
2000e 6 e.p \ 2000e ok
20000e 6 e.p \ 20000e ok
1234567e 6 e.p \ 1234567e ok
On 8/5/26 13:02, Anton Ertl wrote:
Gforth now has three new words:
E. ( r -- ) prints an FP number r in a format that is understood by
Gforth's text interpreter and produces the same number. Tries to
produce short outputs.
E.EXACT ( r -- ) prints an FP number, showing all (possibly hundreds)
of the mantissa digits.
E.P ( r u -- ) prints an FP number with at most u (or, if that saves
printing an exponent, u+1) mantissa digits.
Example usage and output (as comment):
: s-as-f {: w^ n :} n f@ ;
0e e. \ 0e ok
1e e. \ 1e ok
0.1e e. \ .1e ok
0.00005e e. \ .00005e ok
0.000005e e. \ 5e-6 ok
2000e e. \ 2e3 ok
20000e e. \ 2e4 ok
1 s-as-f e. \ 5e-324 ok
Note that the latter number takes more than 700 digits when printed
with e.exact; only one mantissa digit is necessary to distinguish it
from other numbers, because the next FP number has a value close to
1e-323.
0e e.exact \ 0e ok
1e e.exact \ 1e ok
0.1e e.exact \ .1000000000000000055511151231257827021181583404541015625e ok
0.00005e e.exact \ .0000500000000000000023960868011929647991564706899225711822509765625e ok
0.000005e e.exact \ 5.0000000000000004090152695701565477293115691281855106353759765625e-6 ok
2000e e.exact \ 2000e ok
20000e e.exact \ 20000e ok
2e23 e.exact \ 199999999999999983222784e ok
Note that the difference between the input and the output in these
cases comes from the input side (>FLOAT): 0.1e, 0.00005e, 0.000005e
and 2e23 cannot be represented exactly in binary64 (IEEE
double-precision) FP, do >FLOAT produces the FP number closest to the
decimal representation. E.EXACT then prints all the digits of this
number, while E. prints a number that is close and consumes as few
digits as possible.
0e 6 e.p \ 0e ok
1e 6 e.p \ 1e ok
0.1e 6 e.p \ .1e ok
0.00005e 6 e.p \ .00005e ok
0.000005e 6 e.p \ 5e-6 ok
2000e 6 e.p \ 2000e ok
20000e 6 e.p \ 20000e ok
1234567e 6 e.p \ 1234567e ok
I would use FS.EXACT (instead of E.EXACT) and keep the output in
scientific notation.
Less to remember that way.
Similarly, E.P is unneeded if you format the output in scientific
notation and use FS. in combination with SET-PRECISION to specify the
number of digits after the decimal point.
How does "E." work for an inexactly representable binary64 floating
point number?
Krishna Myneni <krishna.myneni@ccreweb.org> writes:...
I would use FS.EXACT (instead of E.EXACT) and keep the output in
scientific notation.
Go ahead. I find the non-scientific notation helpful when it does not introduce too many zeros.
Less to remember that way.
?
Similarly, E.P is unneeded if you format the output in scientific
notation and use FS. in combination with SET-PRECISION to specify the
number of digits after the decimal point.
10 set-precision 20e fs. \ 2.000000000E1 ok
20e 10 e.p \ 20e ok
How does "E." work for an inexactly representable binary64 floating
point number?
For printing r, it first tries
r 1 e.p
and looks if applying >FLOAT on the result produces r. If not it tries
r 2 e.p
and so on. In the end you have the string with the shortest mantissa
that converts back to r.
Yes, this approach is expensive (~9us per e. for random normal numbers
on a Ryzen 8700G (~5GHz Zen4)).
In the meantime I found, that for normal (not subnormal) numbers, it's probably enough to test
r 15 e.p
r 16 e.p
and if that's not enough
r 17 e.p
can be used without checking (that's for binary64 numbers, other
formats need other precisions). The benefit would be that e. now only
takes about 1.6us. One would need a mathematical proof to be sure,
though.
E. is useful for finding the shortest decimal input which will convert
to the internal representation for a given decimal floating point input.
I wonder if there is a more direct way to arrive at that, rather than
the iterative procedure.
There sure is, and that's what the papers are about, and the best
approach is probably at least 50 times faster than my current
E. implementation.
On 8/6/26 09:00, Anton Ertl wrote:[..]
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
E. is useful for finding the shortest decimal input which will convert
to the internal representation for a given decimal floating point input.
I wonder if there is a more direct way to arrive at that, rather than
the iterative procedure.[..]
On 8/6/2026 5:45 PM, Krishna Myneni wrote:
On 8/6/26 09:00, Anton Ertl wrote:[..]
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
E. is useful for finding the shortest decimal input which will convert
to the internal representation for a given decimal floating point input.
I wonder if there is a more direct way to arrive at that, rather than
the iterative procedure.[..]
HEX string input and output when the provider and consumer can not >communicate in binary, or when the binary formats are not standard IEEE.
On 8/6/2026 5:45 PM, Krishna Myneni wrote:
On 8/6/26 09:00, Anton Ertl wrote:[..]
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
E. is useful for finding the shortest decimal input which will convert
to the internal representation for a given decimal floating point
input. I wonder if there is a more direct way to arrive at that,
rather than the iterative procedure.[..]
HEX string input and output when the provider and consumer can not communicate in binary, or when the binary formats are not standard IEEE.
As FE. and friends are currently 'ambiguous' when BASE is not DECIMAL,
it could be done without adding new words. However, >FLOAT might be a problem.
On 8/6/2026 5:45 PM, Krishna Myneni wrote:
On 8/6/26 09:00, Anton Ertl wrote:[..]
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
E. is useful for finding the shortest decimal input which will convert to the internal representation for a given decimal floating point input. I wonder if there is a more direct way to arrive at that, rather than the iterative procedure.[..]
HEX string input and output when the provider and consumer can not communicate in binary, or when the binary formats are not standard IEEE.
As FE. and friends are currently 'ambiguous' when BASE is not DECIMAL, it could be done without adding new words. However, >FLOAT might be a problem.
AFAICS E.EXACT E. are for academics only.
E.P just tells me the minimal
and ambiguous functions ANS suggested were never going to be enough.
On 7/08/2026 5:05 am, marcel hendrix wrote:
On 8/6/2026 5:45 PM, Krishna Myneni wrote:
On 8/6/26 09:00, Anton Ertl wrote:[..]
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
E. is useful for finding the shortest decimal input which will convert to the internal representation for a given decimal floating point input. I wonder if there is a more direct way to arrive at that, rather than the iterative procedure.[..]
HEX string input and output when the provider and consumer can not communicate in binary, or when the binary formats are not standard IEEE.
As FE. and friends are currently 'ambiguous' when BASE is not DECIMAL, it could be done without adding new words. However, >FLOAT might be a problem.
AFAICS E.EXACT E. are for academics only. E.P just tells me the minimal
and ambiguous functions ANS suggested were never going to be enough. If
the user can specify a level of precision then 'exact' was never the goal.
On 8/6/26 20:03, dxf wrote:
On 7/08/2026 5:05 am, marcel hendrix wrote:Your statement suggests that engineers never need to do numerical analysis -- nothing could be further from the truth.
On 8/6/2026 5:45 PM, Krishna Myneni wrote:
On 8/6/26 09:00, Anton Ertl wrote:[..]
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
E. is useful for finding the shortest decimal input which will convert to the internal representation for a given decimal floating point input. I wonder if there is a more direct way to arrive at that, rather than the iterative procedure.[..]
HEX string input and output when the provider and consumer can not communicate in binary, or when the binary formats are not standard IEEE.
As FE. and friends are currently 'ambiguous' when BASE is not DECIMAL, it could be done without adding new words. However, >FLOAT might be a problem.
AFAICS E.EXACT E. are for academics only.-a E.P just tells me the minimal
and ambiguous functions ANS suggested were never going to be enough.-a If
the user can specify a level of precision then 'exact' was never the goal. >>
dxf <dxforth@gmail.com> writes:
AFAICS E.EXACT E. are for academics only.
What makes you think so?
E. is intended to be the go-to way to print FP numbers if there are no formatting constraints. In particular, E. produces an output that you
can copy-and-paste again as input for the Forth text interpreter.
E.P just tells me the minimal
and ambiguous functions ANS suggested were never going to be enough.
The standard FP-printing words all have shortcomings:
F. produces output that cannot be cut and pasted into the text
interpreter.
Moreover, if implemented as specified in the standard,
you get really long outputs when printing numbers like 1e300 or 1e-300.
The output of FS. and FE. is not what I want when printing numbers
with absolute values between 0.001e and 1000000e.
E.P is there for cases when you want shorter output than E. gives, at
the cost of a loss of precision.
- anton
On 7/08/2026 8:11 pm, Anton Ertl wrote:
F. produces output that cannot be cut and pasted into the text
interpreter.
That may be but has nothing to do with F. which outputs classic fixed-
point notation.
If F. has an issue it's ambiguity in what precisely is printed.
Programmers need that detail to plan applications.
Moreover, if implemented as specified in the standard,
you get really long outputs when printing numbers like 1e300 or 1e-300.
Good. That's exactly what fixed-point notation predicts.
The output of FS. and FE. is not what I want when printing numbers
with absolute values between 0.001e and 1000000e.
I agree that's useful and ANS doesn't preclude making such a function
from existing ones.
E.P is there for cases when you want shorter output than E. gives, at
the cost of a loss of precision.
So for all practical purposes E.P differs from Gforth's F. only in
respect of its switching to scientific mode?
F. output from various forths as mentioned:
\ Show F. output
8 set-precision
2e 3e f/ f.
2e4 3e f/ f.
2e-4 3e f/ f.
1e f.
1e4 f.
1e-4 f.
\\
SwiftForth:
2e 3e f/ f. 0.66666667 ok
2e4 3e f/ f. 6666.66666667 ok
2e-4 3e f/ f. 0.00006667 ok
VFX:
2e 3e f/ f. 0.66666667 ok
2e4 3e f/ f. 6666.6667 ok
2e-4 3e f/ f. 0.000066666667 ok
1e f. 1. ok
1e4 f. 10000. ok
1e-4 f. 0.0001 ok
Gforth:
2e 3e f/ f. 0.66666667 ok
2e4 3e f/ f. 6666.6667 ok
2e-4 3e f/ f. 0.000066666667 ok
1e f. 1. ok
1e4 f. 10000. ok
1e-4 f. 0.0001 ok
Win32Forth:
2e 3e f/ f. .66666667 ok
2e4 3e f/ f. 6666.6667 ok
2e-4 3e f/ f. .00006667 ok
1e f. 1.0000000 ok
1e4 f. 10000.000 ok
1e-4 f. .00010000 ok
NT/Forth:
2e 3e f/ f. 0.66666667 ok
2e4 3e f/ f. 6666.6667 ok
2e-4 3e f/ f. 0.000066666667 ok
1e f. 1.0000000 ok
1e4 f. 10000.000 ok
1e-4 f. 0.00010000000 ok
K-Forth: (CR not shown)
2e 3e f/ f. 0.666667 ok
2e4 3e f/ f. 6666.67 ok
2e-4 3e f/ f. 6.66667e-05 ok
1e f. 1 ok
1e4 f. 10000 ok
MinForth:
2e 3e f/ f. 0.66666667 ok
2e4 3e f/ f. 6666.6667 ok
2e-4 3e f/ f. 0.00006667 ok
1e f. 1. ok
1e4 f. 10000. ok
1e-4 f. 0.0001 ok
8 set-precision
2e 3e f/ f.
2e4 3e f/ f.
2e-4 3e f/ f.
1e f.
1e4 f.
1e-4 f.
On 8/8/2026 6:39 AM, dxf wrote:
8 set-precision
2e 3e f/ f.
2e4 3e f/ f.
2e-4 3e f/ f.
1e f.
1e4 f.
1e-4 f.
iForth version 6.9.109, generated 18:39:31, September 27, 2021.
8 set-precision
2e 3e f/ f. 0.66666667
2e4 3e f/ f. 6666.66666667
2e-4 3e f/ f. 0.00006667
2 set-precision
2e 3e f/ f. 0.67
2e4 3e f/ f. 6666.67
2e-4 3e f/ f. 0.00
1e f. 1.00
1e4 f. 10000.00
1e-4 f. 0.00
5001e-4 f. 0.50
200 set-precision
2e 3e f/ f. 0.6666666666666666667
2e4 3e f/ f. 6666.6666666666666665186
2e-4 3e f/ f. 0.0000666666666666667
1e f. 1.0000000000000000000
1e4 f. 10000.0000000000000000000
1e-4 f. 0.0001000000000000000
5001e-4 f. 0.5001000000000000000
What I miss: right-alignment in fixed field, adding +/-/space,
suppressing trailing zeros, sane behavior when field too small,
engineering/SPICE units
unit arithmetic
My FP programs almost always define a new variant of FP output.
marcel hendrix <mhx@iae.nl> writes:
On 8/8/2026 6:39 AM, dxf wrote:
8 set-precision
2e 3e f/ f.
2e4 3e f/ f.
2e-4 3e f/ f.
1e f.
1e4 f.
1e-4 f.
iForth version 6.9.109, generated 18:39:31, September 27, 2021.
8 set-precision
2e 3e f/ f. 0.66666667
2e4 3e f/ f. 6666.66666667
12 significant digits here.
All show much less than 200 significant digits.
What I miss: right-alignment in fixed field, adding +/-/space,
suppressing trailing zeros, sane behavior when field too small,
Gforth has f.rdp, which gives you much of that:
You may consider the behaviour of printing "****" for some numbers to
be insane, but note the following sentence from the documentation: "We recommend using nr>=7 to avoid the risk of numbers not fitting at
all."
engineering/SPICE units
Gforth currently supports scale letters for FP numbers on input (see <https://net2o.de/gforth/Floating_002dpoint-number-and-complex-literals.html>),
but not yet for printing; e.g.
1G5 e. \ prints 1500000000e
I considered letting E. output that, but have not (yet?) done so.
Maybe a different word would be more appropriate. Likewise for F.RDP.
unit arithmetic
What do you have in mind?
No, and I have looked many times (but maybe not hard enough) ...My FP programs almost always define a new variant of FP output.
You have not found enough commonalities between uses to define a few
words and use them everywhere?
dxf <dxforth@gmail.com> writes:
On 7/08/2026 8:11 pm, Anton Ertl wrote:
F. produces output that cannot be cut and pasted into the text
interpreter.
That may be but has nothing to do with F. which outputs classic fixed-
point notation.
Given that it is a statement about F., it obviously has to do with F.
If F. has an issue it's ambiguity in what precisely is printed.
Programmers need that detail to plan applications.
That's doubtful. The problem is that the width of the output of
F. depends on the printed number. Given that variability, a
predictable output for a specific number and SET-PRECISION setting has
very little practical value.
...
Moreover, if implemented as specified in the standard,
you get really long outputs when printing numbers like 1e300 or 1e-300.
Good. That's exactly what fixed-point notation predicts.
But it's not practical. Also, I reread the specification again:
|An ambiguous condition exists if [...] the character string
|representation exceeds the size of the pictured numeric output string |buffer.
So F. working for 1e300 or 1e-300 is not guaranteed.
...
E.P is there for cases when you want shorter output than E. gives, at
the cost of a loss of precision.
So for all practical purposes E.P differs from Gforth's F. only in
respect of its switching to scientific mode?
It also differs by
1) showing a number that can be copied and pasted into the Forth text interpreter (which F. output cannot).
2) passing the precision on the data stack rather than through
SET-PRECISION.
So it differs in pretty much every respect.
F. output from various forths as mentioned:
\ Show F. output
8 set-precision
2e 3e f/ f.
2e4 3e f/ f.
2e-4 3e f/ f.
1e f.
1e4 f.
1e-4 f.
\\
SwiftForth:
2e 3e f/ f. 0.66666667 ok
2e4 3e f/ f. 6666.66666667 ok
2e-4 3e f/ f. 0.00006667 ok
SET-PRECISION specifies the number of significant digits as 8, but the previous two lines show 12 or 4 significant digits. That's a bug.
VFX:
2e 3e f/ f. 0.66666667 ok
2e4 3e f/ f. 6666.6667 ok
2e-4 3e f/ f. 0.000066666667 ok
1e f. 1. ok
1e4 f. 10000. ok
1e-4 f. 0.0001 ok
Gforth:
2e 3e f/ f. 0.66666667 ok
2e4 3e f/ f. 6666.6667 ok
2e-4 3e f/ f. 0.000066666667 ok
1e f. 1. ok
1e4 f. 10000. ok
1e-4 f. 0.0001 ok
Both use 8 significant digits and don't show trailing zeros. See
below about whether trailing zeros should be shown.
Win32Forth:
2e 3e f/ f. .66666667 ok
2e4 3e f/ f. 6666.6667 ok
2e-4 3e f/ f. .00006667 ok
1e f. 1.0000000 ok
1e4 f. 10000.000 ok
1e-4 f. .00010000 ok
This one apparently wants to show a fixed number of digits (probably influenced by SET-PRECISION), but does not show the required 8
signficant digits in the third line. A bug.
NT/Forth:
2e 3e f/ f. 0.66666667 ok
2e4 3e f/ f. 6666.6667 ok
2e-4 3e f/ f. 0.000066666667 ok
1e f. 1.0000000 ok
1e4 f. 10000.000 ok
1e-4 f. 0.00010000000 ok
This one shows trailing zeros, apparently as many as are significant
digits.
K-Forth: (CR not shown)
2e 3e f/ f. 0.666667 ok
2e4 3e f/ f. 6666.67 ok
2e-4 3e f/ f. 6.66667e-05 ok
Only 6 significant digits instead of the 8 that were asked for.
1e f. 1 ok
1e4 f. 10000 ok
F. specifies a required ".", but that's missing here.
MinForth:
2e 3e f/ f. 0.66666667 ok
2e4 3e f/ f. 6666.6667 ok
2e-4 3e f/ f. 0.00006667 ok
1e f. 1. ok
1e4 f. 10000. ok
1e-4 f. 0.0001 ok
Only 4 significant digits in the third line. A bug.
Concerning the differences that are not bugs, the specification of
F. does not say anything about trailing zeros. The rationale
indicates that not showing trailing zeros is intended:
|For example, 1E3 F. displays 1000.
But given that that's not normative, showing trailing zeros is not a
bug.
On 8/8/2026 6:39 AM, dxf wrote:
8 set-precision
2e-a-a 3e f/ f.
2e4-a 3e f/ f.
2e-4 3e f/ f.
1e-a-a-a-a-a-a-a-a f.
1e4-a-a-a-a-a-a-a f.
1e-4-a-a-a-a-a-a f.
iForth version 6.9.109, generated 18:39:31, September 27, 2021.
8 set-precision
2e-a-a 3e f/ f. 0.66666667
2e4-a 3e f/ f. 6666.66666667
2e-4 3e f/ f. 0.00006667
1e-a-a-a-a-a-a-a-a f. 1.00000000
1e4-a-a-a-a-a-a-a f. 10000.00000000
1e-4-a-a-a-a-a-a f. 0.00010000
2 set-precision
2e-a-a 3e f/ f. 0.67
2e4-a 3e f/ f. 6666.67
2e-4 3e f/ f. 0.00
1e-a-a-a-a-a-a-a-a f. 1.00
1e4-a-a-a-a-a-a-a f. 10000.00
1e-4-a-a-a-a-a-a f. 0.00
5001e-4-a-a-a f. 0.50
200 set-precision
2e-a-a 3e f/ f. 0.6666666666666666667
2e4-a 3e f/ f. 6666.6666666666666665186
2e-4 3e f/ f. 0.0000666666666666667
1e-a-a-a-a-a-a-a-a f. 1.0000000000000000000
1e4-a-a-a-a-a-a-a f. 10000.0000000000000000000
1e-4-a-a-a-a-a-a f. 0.0001000000000000000
5001e-4-a-a-a f. 0.5001000000000000000
...
Under VFX and DX-Forth 'decimal places' requires F.R ( F. only does 'significant digits' with trailing zeros truncated). If one asks for
200 decimal places it obeys - up to the limit of the HOLD buffer.
On 8/9/2026 5:43 AM, dxf wrote:
[..]
Under VFX and DX-Forth 'decimal places' requires F.R ( F. only does
'significant digits' with trailing zeros truncated).-a If one asks for
200 decimal places it obeys - up to the limit of the HOLD buffer.
Is there a use case for that behavior or is it just a feature?
I would expect F.R to print the number with more than what PLACES
is set to, in order to prevent saving and restoring a user variable.
On 8/08/2026 4:32 pm, Anton Ertl wrote:
...
Concerning the differences that are not bugs, the specification of
F. does not say anything about trailing zeros. The rationale
indicates that not showing trailing zeros is intended:
|For example, 1E3 F. displays 1000.
But given that that's not normative, showing trailing zeros is not a
bug.
I don't think there's enough detail in ANS to say something is a bug.
What I'm seeing are varying interpretations.
On 9/08/2026 3:19 pm, marcel hendrix wrote:[..]
On 8/9/2026 5:43 AM, dxf wrote:
[..]
Under VFX and DX-Forth 'decimal places' requires F.R ( F. only does
'significant digits' with trailing zeros truncated).-a If one asks for
200 decimal places it obeys - up to the limit of the HOLD buffer.
Is there a use case for that behavior or is it just a feature?
Isn't that behaviour what other langs do? I'd be surprised if FORTRAN
or C couldn't print more than 20 decimal places.
On 8/10/2026 11:15 AM, dxf wrote:
On 9/08/2026 3:19 pm, marcel hendrix wrote:[..]
On 8/9/2026 5:43 AM, dxf wrote:
[..]
Under VFX and DX-Forth 'decimal places' requires F.R ( F. only does
'significant digits' with trailing zeros truncated).-a If one asks for >>>> 200 decimal places it obeys - up to the limit of the HOLD buffer.
Is there a use case for that behavior or is it just a feature?
Isn't that behaviour what other langs do?-a I'd be surprised if FORTRAN
or C couldn't print more than 20 decimal places.
You mean, in case somebody wants to print 1e4932 with 4932 decimal places?
On 10/08/2026 9:17 pm, marcel hendrix wrote:
On 8/10/2026 11:15 AM, dxf wrote:
On 9/08/2026 3:19 pm, marcel hendrix wrote:[..]
On 8/9/2026 5:43 AM, dxf wrote:
[..]
Under VFX and DX-Forth 'decimal places' requires F.R ( F. only does
'significant digits' with trailing zeros truncated).-a If one asks for >>>>> 200 decimal places it obeys - up to the limit of the HOLD buffer.
Is there a use case for that behavior or is it just a feature?
Isn't that behaviour what other langs do?-a I'd be surprised if FORTRAN
or C couldn't print more than 20 decimal places.
You mean, in case somebody wants to print 1e4932 with 4932 decimal places?
ANS requires you provide a buffer sufficient to print a double in binary:
"The size of the pictured numeric output string buffer shall be at least
(2*n) + 2 characters, where n is the number of bits in a cell."
That should be more than enough to print 1e4932 to 4932 decimal places.
If a lowly 16-bit forth can do it by dynamically changing the buffer size, surely a 64-bit forth can scrape it in :)
On 8/8/2026 11:40 AM, Anton Ertl wrote:[...]
marcel hendrix <mhx@iae.nl> writes:
It is extremely frustrating to receive '****' as a result for a 20
minute simulation :--) This always happens when I am sure the
results will be in a certain range and have reserved just enough
space for that guess. I now let numbers print in as short a format
as possible in such a case (it is supposed to happen only when debugging).
Gforth currently supports scale letters for FP numbers on input (see
<https://net2o.de/gforth/Floating_002dpoint-number-and-complex-literals.html>),
but not yet for printing; e.g.
1G5 e. \ prints 1500000000e
Really useful! A format like '1.5G' is also common
and allows niceties
like '1.5GHz' and such.
I considered letting E. output that, but have not (yet?) done so.
Maybe a different word would be more appropriate. Likewise for F.RDP.
Yes, like >FLOAT .
FLOAT is the reverse direction from FP output words like E. andF.RDP.
unit arithmetic
What do you have in mind?
It is not high on my list, but it would allow automatic label generation
for typed data. Like if a{ has type Voltage and b{ has type Current then
the legend for a{ is 'V', for b{ it is 'A', and for a{ b{ f/ it is
{\Ohm}.
On 8/08/2026 4:32 pm, Anton Ertl wrote:
dxf <dxforth@gmail.com> writes:
On 7/08/2026 8:11 pm, Anton Ertl wrote:
F. produces output that cannot be cut and pasted into the text
interpreter.
That may be but has nothing to do with F. which outputs classic fixed-
point notation.
Given that it is a statement about F., it obviously has to do with F.
Only if F. had a responsibility to the text interpreter. It doesn't.
I know what my F. prints. I don't know what another's F. prints.
That's what a standard is meant to sort out.
|An ambiguous condition exists if [...] the character string
|representation exceeds the size of the pictured numeric output string
|buffer.
So F. working for 1e300 or 1e-300 is not guaranteed.
If printing 1e300 with F. was in any way the norm, I imagine ANS would
have guaranteed it.
From the examples you've shown,
E.P has used precision values well short of the 800 used by E.EXACT.
It appears E.P's target is the same as G.R in VFX i.e. numbers
printed at a precision no greater than the nominal precision of the
floats involved.
I don't think there's enough detail in ANS to say something is a bug.
As mentioned some time ago ANS-TC began with a very different scheme
to what was eventually released. Originally fp output was specified in
terms of 'decimal places' - the industry standard.
After the switch
to 'significant digits' all references to PLACES were replaced with >PRECISION. But they missed some. Here's what F. currently states:
12.6.2.1427 F.
f-dot FLOATING EXT
( -- ) ( F: r -- ) or ( r -- )
Display, with a trailing space, the top number on the floating-point
stack using fixed-point notation:
"fixed-point notation" means *decimal places*.
Unfortunately for implementers
there are no 'decimal PLACES' to be found in the document.
It didn't help that
there was no explanation as to how to apply PRECISION either.
They went from
proven technology to something that was speculative and untried.
"The size of the pictured numeric output string buffer shall be at least
(2*n) + 2 characters, where n is the number of bits in a cell."
K-Forth: (CR not shown)
2e 3e f/ f. 0.666667 ok
2e4 3e f/ f. 6666.67 ok
2e-4 3e f/ f. 6.66667e-05 ok
Only 6 significant digits instead of the 8 that were asked for.
1e f. 1 ok
1e4 f. 10000 ok
F. specifies a required ".", but that's missing here.
dxf <dxforth@gmail.com> writes:
On 8/08/2026 4:32 pm, Anton Ertl wrote:...
dxf <dxforth@gmail.com> writes:
I know what my F. prints. I don't know what another's F. prints.
That's what a standard is meant to sort out.
Given that well-reputed Forth systems deviate even from what the
standard specifies, that seems to be the position of an insignificant minority. The rest just does not care about the format and precision
of the F. output, or at least not for what the standard specifies for
it.
...
If printing 1e300 with F. was in any way the norm, I imagine ANS would
have guaranteed it.
Maybe they had that in mind as escape hatch: With 32-bit cells
(considered large when Forth-94 was designed) the pictured numeric
output buffer shall be at least 66 chars, so printing any FP number
that requires more chars would be ambigous (for 16-bit cells already
at 34 chars). And in that case, the Forth system can do something
more practical, such as outputting the number in scientific notation.
With 64-bit cells and a PNO buffer >=130 chars, the practicality of
this escape hatch is doubtful, however.
On 8/8/26 01:32, Anton Ertl wrote:
F. specifies a required ".", but that's missing here.The only indication in the standard that a trailing "." appears is the >example in the appendix; otherwise, my reading of the standard is
ambiguous on the trailing decimal point.
It should be explicitly stated
if the trailing decimal point was the intent.
On 8/10/2026 2:59 PM, dxf wrote:
"The size of the pictured numeric output string buffer shall be at least
-a (2*n) + 2 characters, where n is the number of bits in a cell."
CELL ? I guess that should be 'size of numbers on the floating-point stack' ? Anyway, that would be only 162 characters, not 4932.
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
On 8/8/26 01:32, Anton Ertl wrote:
F. specifies a required ".", but that's missing here.The only indication in the standard that a trailing "." appears is the
example in the appendix; otherwise, my reading of the standard is
ambiguous on the trailing decimal point.
The standard specifies:
| 12.6.2.1427 F.
| [...]
| [-] <digits>.<digits0>
If they intended the "." to be optional, they would have specified that as
[-] <digits>[.<digits0>]
It should be explicitly stated
if the trailing decimal point was the intent.
It is.
On 11/08/2026 4:42 am, marcel hendrix wrote:
On 8/10/2026 2:59 PM, dxf wrote:
"The size of the pictured numeric output string buffer shall be at least >>> -a (2*n) + 2 characters, where n is the number of bits in a cell."
CELL ? I guess that should be 'size of numbers on the floating-point stack' ?
Anyway, that would be only 162 characters, not 4932.
My bad. Even so, 20 dec. places is small relative to the HOLD buffer that you
likely do have. It suggests your implementation has a bottleneck somewhere - that you have accepted as 'good enough'.
FS. can print an arbitrary number of digits.
Example:
pad 8 erase
-aok
1 pad !
-aok
800 set-precision
-aok
pad f@ fs.-a \ ignore spaces and line breaks in output below
-a 4.
-a 940 656 458 412 465 441 765 687 928 682
-a 213 723 650 598 026 143 247 644 255 856
-a 825 006 755 072 702 087 518 652 998 363
-a 616 359 923 797 965 646 954 457 177 309
-a 266 567 103 559 397 963 987 747 960 107
-a 818 781 263 007 131 903 114 045 278 458
-a 171 678 489 821 036 887 186 360 569 987
-a 307 230 500 063 874 091 535 649 843 873
-a 124 733 972 731 696 151 400 317 153 853
-a 980 741 262 385 655 911 710 266 585 566
-a 867 681 870 395 603 106 249 319 452 715
-a 914 924 553 293 054 565 444 011 274 801
-a 297 099 995 419 319 894 090 804 165 633
-a 245 247 571 478 690 147 267 801 593 552
-a 386 115 501 348 035 264 934 720 193 790
-a 268 107 107 491 703 332 226 844 753 335
-a 720 832 431 936 092 382 893 458 368 060
-a 106 011 506 169 809 753 078 342 277 318
-a 329 247 904 982 524 730 776 375 927 247
-a 874 656 084 778 203 734 469 699 533 647
-a 017 972 677 717 585 125 660 551 199 131
-a 504 891 101 451 037 862 738 167 250 955
-a 837 389 733 598 993 664 809 941 164 205
-a 702 637 090 279 242 767 544 565 229 087
-a 538 682 506 419 718 265 533 447 265 625
-a 000 000 000 000 000 000 000 000 000 000
-a 000 000 000 000 000 000 0
e-324-a ok
There are 751 significant digits, representing 2^-1074. The bit pattern
is an IEEE double precision *subnormal* number interpreted as 2^-52*(2^emin), where emin = -1022 is the minimum power of 2 exponent.
2^-52 is the significand, which is the 1 stored in the lsb of the
binary64 floating point number.
Wolfram alpha can be used to verify all of the digits printed above.
We should be able to do this arithmetic with the big arithmetic package,
but I get a segfault because the output buffer is too small, I think. It should be fixable.
On 8/10/26 23:56, Anton Ertl wrote:
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
On 8/8/26 01:32, Anton Ertl wrote:
F. specifies a required ".", but that's missing here.The only indication in the standard that a trailing "." appears is the
example in the appendix; otherwise, my reading of the standard is
ambiguous on the trailing decimal point.
The standard specifies:
| 12.6.2.1427 F.
| [...]
| [-] <digits>.<digits0>
If they intended the "." to be optional, they would have specified that as
[-] <digits>[.<digits0>]
It should be explicitly stated
if the trailing decimal point was the intent.
It is.
Actually, F. in its present functionality in kForth works for me,
despite it being non-standard. It provides 6 significant digits of
output and switches between fixed point and scientific notation to
produce the shortest output with 6 significant digits. This output is
useful to me most of the time. The trailing decimal point seems like a
good idea when it's output is in fixed point format.
When I need control over the number of significant digits displayed, I
use SET-PRECISION and FS. and when I need fixed point output with a
fixed number of decimal places, right-justified within a field of
specified width, I use F.RD (defined in source in strings.4th). These
three words, "F." "FS." and "F.RD", in their present functionality, have
met all of my needs up to now.
FS. can print an arbitrary number of digits.
Example:
pad 8 erase
ok
1 pad !
ok
800 set-precision
ok
pad f@ fs. \ ignore spaces and line breaks in output below
4.
940 656 458 412 465 441 765 687 928 682
213 723 650 598 026 143 247 644 255 856
825 006 755 072 702 087 518 652 998 363
616 359 923 797 965 646 954 457 177 309
266 567 103 559 397 963 987 747 960 107
818 781 263 007 131 903 114 045 278 458
171 678 489 821 036 887 186 360 569 987
307 230 500 063 874 091 535 649 843 873
124 733 972 731 696 151 400 317 153 853
980 741 262 385 655 911 710 266 585 566
867 681 870 395 603 106 249 319 452 715
914 924 553 293 054 565 444 011 274 801
297 099 995 419 319 894 090 804 165 633
245 247 571 478 690 147 267 801 593 552
386 115 501 348 035 264 934 720 193 790
268 107 107 491 703 332 226 844 753 335
720 832 431 936 092 382 893 458 368 060
106 011 506 169 809 753 078 342 277 318
329 247 904 982 524 730 776 375 927 247
874 656 084 778 203 734 469 699 533 647
017 972 677 717 585 125 660 551 199 131
504 891 101 451 037 862 738 167 250 955
837 389 733 598 993 664 809 941 164 205
702 637 090 279 242 767 544 565 229 087
538 682 506 419 718 265 533 447 265 625
000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 0
e-324 ok
There are 751 significant digits, representing 2^-1074. The bit pattern
is an IEEE double precision *subnormal* number interpreted as 2^-52*(2^emin), where emin = -1022 is the minimum power of 2 exponent.
2^-52 is the significand, which is the 1 stored in the lsb of the
binary64 floating point number.
Wolfram alpha can be used to verify all of the digits printed above.
We should be able to do this arithmetic with the big arithmetic package,
but I get a segfault because the output buffer is too small, I think. It should be fixable.
--
Krishna
On Tue, 11 Aug 2026 22:16:56 -0500...
Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
Actually, F. in its present functionality in kForth works for me,
despite it being non-standard. It provides 6 significant digits of
output and switches between fixed point and scientific notation to
produce the shortest output with 6 significant digits. This output is
useful to me most of the time. The trailing decimal point seems like a
good idea when it's output is in fixed point format.
This is how I just implemented Anton's E. in my system. Precision fixed
at 6 digits, print both F. and FS. to memory and take the shortest
to print out. I found that to be a useful tool to use interactively.
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 74 |
| Nodes: | 6 (1 / 5) |
| Uptime: | 51:10:42 |
| Calls: | 1,101 |
| Calls today: | 1 |
| Files: | 1,339 |
| Messages: | 276,012 |