fixed

Fixed point number package



{ ====================================================================
  fixed.f

  Fixed point number package for SwiftForth
  Copyright (c) Dr. Heinrich Hohl, Munich, Germany

  Originally written using LMI PC/FORTH 3.2 (April 1992)
  Published in: Forth-Magazin 'Vierte Dimension' Nr. 2/1992, p.7

  Rewritten for SwiftForth 3.5.6 (December 2014)

  --------------------------------------------------------------------

  A fixed point number (f) is a single length number
  with an implied decimal point at a specified position.

  PLACES is used to specify the position of the implied
  decimal point.

  FIXED can be used immediately after a numeric conversion
  to generate a fixed point number (based on DPL).

  This package is for 32-bit systems. In this case, a fixed
  point number is represented by a single-length number.

  Use standard operators (+, -, *, /, @, !, etc.) with
  fixed point numbers.
  ==================================================================== }

FORTH DEFINITIONS  DECIMAL

PACKAGE PRIVATE-FIXED

{ --------------------------------------------------------------------
  Implied decimal point
  -------------------------------------------------------------------- }

PRIVATE

  VARIABLE f#places
\ number of digits to the right of the implied decimal point

PUBLIC

: PLACES ( n -- )  0 MAX  f#places ! ;
\ specify the number of digits behind the decimal point

  5 PLACES
\ default setting gives a total resolution of 6 digits

{ --------------------------------------------------------------------
  Number conversion
  -------------------------------------------------------------------- }

PRIVATE

: SHIFT ( n1 n -- n2)
  DUP 0<
  IF    NEGATE
        0  DO  10 /  LOOP
  ELSE  0 ?DO  10 *  LOOP  THEN ;
\ perform decimal right shift (n<0) or left shift (n>0)

PUBLIC

: FIXED ( n|d -- f)
  DPL @  1+ 0>  IF D>S THEN
  f#places @  DPL @ 0 MAX  -  SHIFT ;
\ convert single or double length number to fixed point number

{ --------------------------------------------------------------------
  Numeric output words
  -------------------------------------------------------------------- }

: (F.) ( f -- addr len)
  DUP  ABS 0
  <#  f#places @ 0 ?DO # LOOP  [CHAR] . HOLD  #S  ROT SIGN  #> ;
\ convert a fixed point number to a formatted string

: F. ( f -- )  (F.) TYPE  SPACE ;
\ display a fixed point number

: F.R ( f width -- )  >R  (F.)  R> OVER - SPACES  TYPE ;
\ display a fixed point number right justified in a field of specified width

{ ==================================================================== }

END-PACKAGE