Forth Floating point package. \ Implements the Forth Vendors Group proposed Forth Floating Point Standard. \ Runs only under Unix, using the C floating point library to do most of \ the work. \ Has a separate floating point stack. \ All floating point numbers are IEEE double-precision format. \ Requires a C support library, which is usually kept in \ /usr/local/lib/forth/float.{c,o} \ \ Problems: \ Floating point numeric input is not integrated into the forth interpreter. \ Slower than it has to be, due to the overhead of calling the C library \ routines. If you want to use this for heavy numerical work, it needs \ some performance work. \ Numeric output does not strictly follow the Forth Floating Point Standard. \ In particular the PLACES variable isn't implemented. Glossary: f+ fp1 fp2 -- fp3 FVG Floating-point addition. fp3 is the sum of fp1 and fp2. f- fp1 fp2 -- fp3 FVG Floating-point subtraction. fp3 is the difference fp1 minus fp2. f* fp1 fp2 -- fp3 FVG Floating-point multiplication. fp3 is the product of fp1 and fp2. f/ fp1 fp2 -- fp3 FVG Floating-point division. fp3 is the quotient of fp1 divided by fp2. f** fp1 fp2 -- fp3 FVG Floating-point exponentiation. fp3 is the value of fp1 raised to the power fp2. fcos fp1 -- fp2 FVG fp2 is the cosine of fp1. Input argument is in radians. fsin fp1 -- fp2 FVG fp2 is the sine of fp1. Input argument is in radians. ftan fp1 -- fp2 FVG fp2 is the tangent of r1. The tangent of pi/2 or 3pi/2 radians returns the largest real number representable in the implementation's binary format. (IEEE Infinity). faln fp1 -- fp2 FVG The exponential function. fp2 is the value of e raised to the power of fp1. fln fp1 -- fp2 FVG fp2 is the natural logarithm of fp1. fsqrt fp1 -- fp2 FVG fp2 is the square root of fp1. flog fp1 -- fp2 FVG fp2 is the base 10 logarithm of fp1. fatan fp1 -- fp2 FVG fp2 is the arctangent of fp1. This operator is valid for all real fp1. The result is in the range -pi/2 to pi/2 radians. fasin fp1 -- fp2 FVG fp2 is the arcsine of fp1. Valid for -1 <= fp1 <= 1. The result is in the range -pi/2 to pi/2 radians. facos fp1 -- fp2 FVG fp2 is the arccosine of fp1. Valid for -1 <= fp1 <= 1. The result is in the range -pi/2 to pi/2 radians. fsinh fp1 -- fp2 FVG fp2 is the hyperbolic sine of fp1. fcosh fp1 -- fp2 FVG fp2 is the hyperbolic cosine of fp1. ftanh fp1 -- fp2 FVG fp2 is the hyperbolic tangent of fp1. fvariable -- (compilation) FVG -- addr (execution) A defining word used in the form: FVARIABLE cccc When FVARIABLE executes, it creates the definition cccc with its parameter field uninitialized. When cccc is later executed, the address of the parameter field is left on the stack, so that a F@ or F! operation may access this location. fconstant fp -- (compilation) FVG -- fp (execution) A defining word used in the form: fp FCONSTANT When FCONSTANT executes, it creates the definition so that when is later executed, the floating point number fp is left on the stack. falog fp1 -- fp2 FVG fp2 is the result of raising 10 to the fp1 power. >f l -- fscaled Convert the integer on the parameter stack to its floating-point equivalent, using the value in dpl as a negative exponent. For example, 5.2 >f leaves the floating point number "five and two-tenths" on the floating point stack. This is a kludge. E l -- fscaled I Exponent entry for scientific notation. Used in the form: l E xxxx where xxxx is a number to be applied to the exponent after l is converted to floating point. For example, 5.2 E -10 results in the number "five point two times ten to the minus ten" being left on the floating point stack. The number before the E MUST include a decimal point. The E must be in UPPER case. This may be used either inside or outside a colon definition. If used inside a definition, the floating point number will be compiled into the definition so that when the definition later executes, the floating point number will be left on the floating point stack. This is a kludge too. There should be some reasonable syntax for floating point numbers that is built into the interpreter. f. fp -- FVG Display fp on the currently selected output device in fixed-point form; i.e., the location of the decimal point is adjusted as necessary so that no exponent need be displayed. The number of digits specified by the most recent execution of the word PLACES are printed to the right of the decimal point. A trailing blank follows. For example, 4 PLACES 1.2345E02 F. will display as 123.4500b (where the character "b" denotes an ASCII blank). Implementation Note: PLACES isn't implemented yet. f.s -- Print the contents of the floating point stack without affecting its contents. The number on the top of the stack appears on the right-hand side of the line. e. fp -- FVG Display fp in exponential form. The significand contains the maximum number of significant digits allowed by the floating-point data format, and the exponent is explicitly displayed even if it is zero. A trailing blank follows. If the current system base is not decimal, an error condition exists. float l -- fp FVG Convert a signed long integer into its floating-point equivalent, removing the long integer from the Forth parameter stack and leaving the result on the floating-point stack. int fp -- l FVG Truncate a floating-point number to a signed long integer (round it toward zero), removing the fp number from the floating-point stack and leaving the result on the Forth parameter stack. Underflow gives a zero result, overflow is an error condition. fabs fp1 --fp2 FVG fp2 is the absolute value of the floating-point number fp1 . fnegate fp1 -- fp2 FVG fp2 is the negative of the floating-point number fp1 . f! f addr -- FVG Store a floating-point number from the floating-point stack into the address that is on top of the Forth parameter stack. f@ addr -- f FVG Fetch a floating-point number to the top of the floating-point stack from the address that is on top of the Forth parameter stack. fdrop fp -- FVG Discard floating-point number on top of the stack. fswap fp1 fp2 -- fp2 fp1 FVG Interchange the two floating-point numbers on top of the stack. fover fp1 fp2 -- fp1 fp2 fp1 FVG Copy the second floating-point number on the stack to the top of the stack. fdup fp -- fp fp FVG Duplicate the floating-point number on top of the stack. frot fp1 fp2 fp3 -- fp2 fp3 fp1 FVG Rotate the third floating-point number to the top of the stack. fpop f -- l l Move the fp number on top of the floating-point stack to the top two cells of the parameter stack, without converting it to an integer. fpop just moves the bits, without any sort of format conversion. fpush l l -- f Push the top two numbers on the parameter stack to the top cell of the floating-point stack, without converting them to fp. fpop just moves the bits, without any sort of format conversion. f0= fp -- f FVG True if the floating-point number on top of the stack is equal to zero. The fp number is removed from the floating-point stack, and the flag is left on top of the Forth parameter stack. f0< fp -- f FVG True if the floating-point number on top of the fp stack is less than zero. The fp number is removed from the floating-point stack, and the flag is left on top of the Forth parameter stack. fp! n -- Store the integer on the parameter stack into the floating-point stack pointer. Used for initialization. fp@ -- addr Fetch the current contents of the floating-point stack pointer to the parameter stack. fdepth -- n n is the number of floating point numbers currently on the floating point stack. fstack -- addr Leaves the base address (low-memory end) of the floating-point stack. Since this stack builds towards low memory, this address is the low-memory limit for stack growth. fp0 -- addr addr is the address of a USER variable which contains the 32-bit address of the of the top of the floating point stack area. The stack grows towards low memory from there. FP0 L@ FP! would empty the floating point stack, but see INITF . initf -- Initialize the floating point stack to empty. This word word must be invoked before using any of the floating-point operators, including conversions to floating point from integers on the parameter stack. fstrbuf -- addr Leaves the address of the floating-point string buffer, used for floating-point i/o. /f -- n Leaves the size, in bytes, of a floating point number in storage format. In this system, the value is 8. f#bytes -- n A synonym for /f /fstack -- n Leaves the size, in bytes, of the space allocated for the floating-point stack. floating -- The Forth floating-point vocabulary. (flit -- fp A run-time work which is compiled by fliteral. It takes a floating point number from the executing code stream and leaves it on the floating point stack. fliteral fp -- C,I The floating point number is removed from the floating point stack and compiled into the current definition so that when the definition is later executed, that floating point number will be left on the floating point stack. Floating point example: This example prints a table of the values of the sine function at 1/10 radian intervals between 0 and two-pi. 3.14159265 E 0 fconstant pi pi 2. E 0 f* fconstant 2pi : sine-table ( -- ) 0.0 E 0 begin fdup 2pi f< while fdup f. fdup fsin f. cr .1 E 0 f+ repeat ;