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 ).