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 – rfloat “d-to-f”

`f>d`

r – dfloat “f-to-d”

`f+`

r1 r2 – r3float “f-plus”

`f-`

r1 r2 – r3float “f-minus”

`f*`

r1 r2 – r3float “f-star”

`f/`

r1 r2 – r3float “f-slash”

`fnegate`

r1 – r2float “f-negate”

`fabs`

r1 – r2float-ext “f-abs”

`fmax`

r1 r2 – r3float “f-max”

`fmin`

r1 r2 – r3float “f-min”

`floor`

r1 – r2float “floor”

Round towards the next smaller integral value, i.e., round toward negative infinity.

`fround`

r1 – r2float “f-round”

Round to the nearest integral value.

`f**`

r1 r2 – r3float-ext “f-star-star”

*r3* is *r1* raised to the *r2*th power.

`fsqrt`

r1 – r2float-ext “f-square-root”

`fexp`

r1 – r2float-ext “f-e-x-p”

`fexpm1`

r1 – r2float-ext “f-e-x-p-m-one”

*r2*=*e****r1*−1

`fln`

r1 – r2float-ext “f-l-n”

`flnp1`

r1 – r2float-ext “f-l-n-p-one”

*r2*=ln(*r1*+1)

`flog`

r1 – r2float-ext “f-log”

The decimal logarithm.

`falog`

r1 – r2float-ext “f-a-log”

*r2*=10***r1*

`f2*`

r1 – r2gforth “f2*”

Multiply *r1* by 2.0e0

`f2/`

r1 – r2gforth “f2/”

Multiply *r1* by 0.5e0

`1/f`

r1 – r2gforth “1/f”

Divide 1.0e0 by *r1*.

`precision`

– ufloat-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 – r2float-ext “f-sine”

`fcos`

r1 – r2float-ext “f-cos”

`fsincos`

r1 – r2 r3float-ext “f-sine-cos”

*r2*=sin(*r1*), *r3*=cos(*r1*)

`ftan`

r1 – r2float-ext “f-tan”

`fasin`

r1 – r2float-ext “f-a-sine”

`facos`

r1 – r2float-ext “f-a-cos”

`fatan`

r1 – r2float-ext “f-a-tan”

`fatan2`

r1 r2 – r3float-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 – r2float-ext “f-cinch”

`fcosh`

r1 – r2float-ext “f-cosh”

`ftanh`

r1 – r2float-ext “f-tan-h”

`fasinh`

r1 – r2float-ext “f-a-cinch”

`facosh`

r1 – r2float-ext “f-a-cosh”

`fatanh`

r1 – r2float-ext “f-a-tan-h”

`pi`

– rgforth “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 – flaggforth “f~rel”

Approximate equality with relative error: |r1-r2|<r3*|r1+r2|.

`f~abs`

r1 r2 r3 – flaggforth “f~abs”

Approximate equality with absolute error: |r1-r2|<r3.

`f~`

r1 r2 r3 – flagfloat-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 – fgforth “f-equals”

`f<>`

r1 r2 – fgforth “f-not-equals”

`f<`

r1 r2 – ffloat “f-less-than”

`f<=`

r1 r2 – fgforth “f-less-or-equal”

`f>`

r1 r2 – fgforth “f-greater-than”

`f>=`

r1 r2 – fgforth “f-greater-or-equal”

`f0<`

r – ffloat “f-zero-less-than”

`f0<=`

r – fgforth “f-zero-less-or-equal”

`f0<>`

r – fgforth “f-zero-not-equals”

`f0=`

r – ffloat “f-zero-equals”

`f0>`

r – fgforth “f-zero-greater-than”

`f0>=`

r – fgforth “f-zero-greater-or-equal”

[1] 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 )
```

.