Node:Floating Point, Previous:Mixed precision, Up:Arithmetic
For the rules used by the text interpreter for recognising floating-point numbers see Number Conversion.
Gforth has a separate floating point stack, but the documentation uses the unified notation.^{1}
Floating point numbers have a number of unpleasant surprises for the
unwary (e.g., floating point addition is not associative) and even a few
for the wary. You should not use them unless you know what you are doing
or you don't care that the results you get are totally bogus. If you
want to learn about the problems of floating point numbers (and how to
avoid them), you might start with David Goldberg,
What Every Computer Scientist Should Know About Floating-Point Arithmetic, ACM Computing
Surveys 23(1):5-48, March 1991.
d>f
d -- r float ``d-to-f''
f>d
r -- d float ``f-to-d''
f+
r1 r2 -- r3 float ``f-plus''
f-
r1 r2 -- r3 float ``f-minus''
f*
r1 r2 -- r3 float ``f-star''
f/
r1 r2 -- r3 float ``f-slash''
fnegate
r1 -- r2 float ``f-negate''
fabs
r1 -- r2 float-ext ``f-abs''
fmax
r1 r2 -- r3 float ``f-max''
fmin
r1 r2 -- r3 float ``f-min''
floor
r1 -- r2 float ``floor''
Round towards the next smaller integral value, i.e., round toward negative infinity.
fround
r1 -- r2 gforth ``f-round''
Round to the nearest integral value.
f**
r1 r2 -- r3 float-ext ``f-star-star''
r3 is r1 raised to the r2th power.
fsqrt
r1 -- r2 float-ext ``f-square-root''
fexp
r1 -- r2 float-ext ``f-e-x-p''
fexpm1
r1 -- r2 float-ext ``f-e-x-p-m-one''
r2=e**r1-1
fln
r1 -- r2 float-ext ``f-l-n''
flnp1
r1 -- r2 float-ext ``f-l-n-p-one''
r2=ln(r1+1)
flog
r1 -- r2 float-ext ``f-log''
The decimal logarithm.
falog
r1 -- r2 float-ext ``f-a-log''
r2=10**r1
f2*
r1 -- r2 gforth ``f2*''
Multiply r1 by 2.0e0
f2/
r1 -- r2 gforth ``f2/''
Multiply r1 by 0.5e0
1/f
r1 -- r2 gforth ``1/f''
Divide 1.0e0 by r1.
precision
-- u float-ext ``precision''
u is the number of significant digits currently used by
F.
FE.
and FS.
set-precision
u -- float-ext ``set-precision''
Set the number of significant digits currently used by
F.
FE.
and FS.
to u.
Angles in floating point operations are given in radians (a full circle
has 2 pi radians).
fsin
r1 -- r2 float-ext ``f-sine''
fcos
r1 -- r2 float-ext ``f-cos''
fsincos
r1 -- r2 r3 float-ext ``f-sine-cos''
r2=sin(r1), r3=cos(r1)
ftan
r1 -- r2 float-ext ``f-tan''
fasin
r1 -- r2 float-ext ``f-a-sine''
facos
r1 -- r2 float-ext ``f-a-cos''
fatan
r1 -- r2 float-ext ``f-a-tan''
fatan2
r1 r2 -- r3 float-ext ``f-a-tan-two''
r1/r2=tan(r3). ANS Forth does not require, but probably
intends this to be the inverse of fsincos
. In gforth it is.
fsinh
r1 -- r2 float-ext ``f-cinch''
fcosh
r1 -- r2 float-ext ``f-cosh''
ftanh
r1 -- r2 float-ext ``f-tan-h''
fasinh
r1 -- r2 float-ext ``f-a-cinch''
facosh
r1 -- r2 float-ext ``f-a-cosh''
fatanh
r1 -- r2 float-ext ``f-a-tan-h''
pi
-- r gforth ``pi''
Fconstant
- r is the value pi; the ratio of a circle's area
to its diameter.
One particular problem with floating-point arithmetic is that comparison
for equality often fails when you would expect it to succeed. For this
reason approximate equality is often preferred (but you still have to
know what you are doing). Also note that IEEE NaNs may compare
differently from what you might expect. The comparison words are:
f~rel
r1 r2 r3 -- flag gforth ``f~rel''
Approximate equality with relative error: |r1-r2|<r3*|r1+r2|.
f~abs
r1 r2 r3 -- flag gforth ``f~abs''
Approximate equality with absolute error: |r1-r2|<r3.
f~
r1 r2 r3 -- flag float-ext ``f-proximate''
ANS Forth medley for comparing r1 and r2 for equality: r3>0:
f~abs
; r3=0: bitwise comparison; r3<0: fnegate f~rel
.
f=
r1 r2 -- f gforth ``f-equals''
f<>
r1 r2 -- f gforth ``f-not-equals''
f<
r1 r2 -- f float ``f-less-than''
f<=
r1 r2 -- f gforth ``f-less-or-equal''
f>
r1 r2 -- f gforth ``f-greater-than''
f>=
r1 r2 -- f gforth ``f-greater-or-equal''
f0<
r -- f float ``f-zero-less-than''
f0<=
r -- f gforth ``f-zero-less-or-equal''
f0<>
r -- f gforth ``f-zero-not-equals''
f0=
r -- f float ``f-zero-equals''
f0>
r -- f gforth ``f-zero-greater-than''
f0>=
r -- f gforth ``f-zero-greater-or-equal''
It's easy to generate the separate
notation from that by just separating the floating-point numbers out:
e.g. ( n r1 u r2 -- r3 )
becomes ( n u -- ) ( F: r1 r2 --
r3 )
.