File:  [gforth] / gforth / float.fs
Revision 1.26: download - view: text, annotated - select for diffs
Thu May 6 21:33:32 1999 UTC (23 years, 10 months ago) by crook
Branches: MAIN
CVS tags: HEAD
Major re-write of manual sections concerning text interpreter and
defining words. Much fine-tuning of other sections. The manual is
``nearly finished'' -- at least, all the major pieces of work that
I envisaged for the first mods (which were only going to take a
couple of weeks...). The manual has grown from 127 pages to 192
which is good news in terms of content but bad news in terms of the
time it takes to print out on my HP550C DeskJet.

Other changes are just tweaks to glossary entries.

    1: \ High level floating point                            14jan94py
    2: 
    3: \ Copyright (C) 1995,1997 Free Software Foundation, Inc.
    4: 
    5: \ This file is part of Gforth.
    6: 
    7: \ Gforth is free software; you can redistribute it and/or
    8: \ modify it under the terms of the GNU General Public License
    9: \ as published by the Free Software Foundation; either version 2
   10: \ of the License, or (at your option) any later version.
   11: 
   12: \ This program is distributed in the hope that it will be useful,
   13: \ but WITHOUT ANY WARRANTY; without even the implied warranty of
   14: \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15: \ GNU General Public License for more details.
   16: 
   17: \ You should have received a copy of the GNU General Public License
   18: \ along with this program; if not, write to the Free Software
   19: \ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   20: 
   21: \ 1 cells 4 = [IF]
   22: \ ' cells   Alias sfloats
   23: \ ' cell+   Alias sfloat+
   24: \ ' align   Alias sfalign
   25: \ ' aligned Alias sfaligned
   26: \ [ELSE]
   27: \ : sfloats  2* 2* ;
   28: \ : sfloat+  4 + ;
   29: \ : sfaligned ( addr -- addr' )  3 + -4 and ;
   30: \ : sfalign ( -- )  here dup sfaligned swap ?DO  bl c,  LOOP ;
   31: \ [THEN]
   32: 
   33: \ 1 floats 8 = [IF]
   34: \ ' floats   Alias dfloats
   35: \ ' float+   Alias dfloat+
   36: \ ' falign   Alias dfalign
   37: \ ' faligned Alias dfaligned
   38: \ [ELSE]
   39: \ : dfloats  2* 2* 2* ;
   40: \ : dfloat+  8 + ;
   41: \ : dfaligned ( addr -- addr' )  7 + -8 and ;
   42: \ : dfalign ( -- )  here dup dfaligned swap ?DO  bl c,  LOOP ;
   43: \ [THEN]
   44: 
   45: : sfalign ( -- ) \ float-ext s-f-align
   46:     \G If the data-space pointer is not single-float-aligned, reserve
   47:     \G enough space to align it.
   48:     here dup sfaligned swap ?DO  bl c,  LOOP ;
   49: : dfalign ( -- ) \ float-ext d-f-align
   50:     \G If the data-space pointer is not double-float-aligned, reserve
   51:     \G enough space to align it.
   52:     here dup dfaligned swap ?DO  bl c,  LOOP ;
   53: 
   54: 1 sfloats constant sfloat+ ( sf-addr1 -- sf-addr2 ) \ float-ext s-float-plus
   55: \G Increment @i{sf-addr1} by the number of address units corresponding to the size of
   56: \G a single-precision IEEE floating-point number, to give @i{sf-addr2}.""
   57: dofield: lastxt code-address! \ change the constant into a field
   58: 
   59: 1 dfloats constant dfloat+ ( df-addr1 -- df-addr2 ) \ float-ext d-float-plus
   60: \G Increment @i{df-addr1} by the number of address units corresponding to the size of
   61: \G a double-precision IEEE floating-point number, to give @i{df-addr2}.""
   62: dofield: lastxt code-address! \ change the constant into a field
   63: 
   64: : f, ( f -- ) \ gforth
   65:     \G Reserve data space for one floating-point number and store
   66:     \G @i{f} in the space.
   67:     here 1 floats allot f! ;
   68: 
   69: : fconstant  ( r "name" -- ) \ float
   70:     Create f,
   71: DOES> ( -- r )
   72:     f@ ;
   73: 
   74: : fdepth ( -- +n ) \ floating f-depth
   75:     \G @var{+n} is the current number of (floating-point) values on the
   76:     \G floating-point stack.
   77:     fp0 @ fp@ - [ 1 floats ] Literal / ;
   78: 
   79: : FLit ( -- r )  r> dup f@ float+ >r ;
   80: : FLiteral ( compilation r -- ; run-time -- r ) \ float
   81:     \G Compile appropriate code such that, at run-time, @var{r} is placed
   82:     \G on the (floating-point) stack. Interpretation semantics are undefined.
   83:     BEGIN  here cell+ dup faligned <>  WHILE  postpone noop  REPEAT
   84:     postpone FLit  f, ;  immediate
   85: 
   86: &15 Value precision ( -- u ) \ floating-ext
   87: \G @var{u} is the number of significant digits currently used by
   88: \G @code{F.} @code{FE.} and @code{FS.} 
   89: : set-precision ( u -- ) \ floating-ext
   90:     \G Set the number of significant digits currently used by
   91:     \G @code{F.} @code{FE.} and @code{FS.} to @var{u}.
   92:     to precision ;
   93: 
   94: : scratch ( r -- addr len )
   95:   pad precision - precision ;
   96: 
   97: : zeros ( n -- )   0 max 0 ?DO  '0 emit  LOOP ;
   98: 
   99: : -zeros ( addr u -- addr' u' )
  100:   BEGIN  dup  WHILE  1- 2dup + c@ '0 <>  UNTIL  1+  THEN ;
  101: 
  102: : f$ ( f -- n )  scratch represent 0=
  103:   IF  2drop  scratch 3 min type  rdrop  EXIT  THEN
  104:   IF  '- emit  THEN ;
  105: 
  106: : f.  ( r -- ) \ floating-ext f-dot
  107: \G Display (the floating-point number) @var{r} using fixed-point notation,
  108: \G followed by a space.
  109:   f$ dup >r 0<
  110:   IF    '0 emit
  111:   ELSE  scratch r@ min type  r@ precision - zeros  THEN
  112:   '. emit r@ negate zeros
  113:   scratch r> 0 max /string 0 max -zeros type space ;
  114: \ I'm afraid this does not really implement ansi semantics wrt precision.
  115: \ Shouldn't precision indicate the number of places shown after the point?
  116: 
  117: : fe. ( r -- ) \ floating-ext f-e-dot
  118: \G Display @var{r} using engineering notation, followed by a space.
  119:   f$ 1- s>d 3 fm/mod 3 * >r 1+ >r
  120:   scratch r@ min type '. emit  scratch r> /string type
  121:   'E emit r> . ;
  122: 
  123: : fs. ( r -- ) \ floating-ext f-s-dot
  124: \G Display @var{r} using scientific notation, followed by a space.
  125:   f$ 1-
  126:   scratch over c@ emit '. emit 1 /string type
  127:   'E emit . ;
  128: 
  129: require debugs.fs
  130: 
  131: : sfnumber ( c-addr u -- r true | false )
  132:     2dup [CHAR] e scan ( c-addr u c-addr2 u2 )
  133:     dup 0=
  134:     IF
  135: 	2drop 2dup [CHAR] E scan ( c-addr u c-addr3 u3 )
  136:     THEN
  137:     nip
  138:     IF
  139: 	>float
  140:     ELSE
  141: 	2drop false
  142:     THEN ;
  143: 
  144: :noname ( c-addr u -- )
  145:     2dup sfnumber
  146:     IF
  147: 	2drop POSTPONE FLiteral
  148:     ELSE
  149: 	defers compiler-notfound
  150:     ENDIF ;
  151: IS compiler-notfound
  152: 
  153: :noname ( c-addr u -- r )
  154:     2dup sfnumber
  155:     IF
  156: 	2drop
  157:     ELSE
  158: 	defers interpreter-notfound
  159:     ENDIF ;
  160: IS interpreter-notfound
  161: 
  162: : fvariable ( "name" -- ) \ float
  163:     Create 0.0E0 f, ;
  164:     \ does> ( -- f-addr )
  165: 
  166: 1.0e0 fasin 2.0e0 f* fconstant pi ( -- r ) \ gforth
  167: \G FCONSTANT: @var{r} is the value pi; the ratio of a circle's area
  168: \G to its diameter.
  169: 
  170: : f2* ( r1 -- r2 ) \ gforth
  171:     \G Multiply @var{r1} by 2.0e0
  172:     2.0e0 f* ;
  173: 
  174: : f2/ ( r1 -- r2 ) \ gforth
  175:     \G Multiply @var{r1} by 0.5e0
  176:     0.5e0 f* ;
  177: 
  178: : 1/f ( r1 -- r2 ) \ gforth
  179:     \G Divide 1.0e0 by @var{r1}.
  180:     1.0e0 fswap f/ ;
  181: 
  182: 
  183: \ We now have primitives for these, so we need not define them
  184: 
  185: \ : falog ( f -- 10^f )  [ 10.0e0 fln ] FLiteral f* fexp ;
  186: 
  187: \ : fsinh    fexpm1 fdup fdup 1.0e0 f+ f/ f+ f2/ ;
  188: \ : fcosh    fexp fdup 1/f f+ f2/ ;
  189: \ : ftanh    f2* fexpm1 fdup 2.0e0 f+ f/ ;
  190: 
  191: \ : fatanh   fdup f0< >r fabs 1.0e0 fover f- f/  f2* flnp1 f2/
  192: \            r> IF  fnegate  THEN ;
  193: \ : facosh   fdup fdup f* 1.0e0 f- fsqrt f+ fln ;
  194: \ : fasinh   fdup fdup f* 1.0e0 f+ fsqrt f/ fatanh ;
  195: 
  196: \ !! factor out parts
  197: : f~ ( f1 f2 f3 -- flag ) \ float-ext
  198:     fdup f0=
  199:     IF
  200: 	fdrop f= EXIT
  201:     THEN
  202:     fdup f0>
  203:     IF
  204: 	frot frot f- fabs fswap
  205:     ELSE
  206: 	fnegate frot frot fover fabs fover fabs f+ frot frot
  207: 	f- fabs frot frot f*
  208:     THEN
  209:     f< ;
  210: 
  211: : f.s ( -- ) \ gforth f-dot-s
  212:     \G Display the number of items on the floating-point stack,
  213:     \G followed by a list of the items; TOS is the right-most item.
  214:     ." <" fdepth 0 .r ." > " fdepth 0 max maxdepth-.s @ min dup 0 
  215:     ?DO  dup i - 1- floats fp@ + f@ f.  LOOP  drop ; 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>