Organization: Institut fuer Medizinische Computerwissenschaften
Newsgroups: bit.listserv.sas-l
Date:         Fri, 11 Sep 1992 15:00:00 CDT
Reply-To:     Christian.J.Reichetzeder@AWIIMC12.IMC.UNIVIE.AC.AT
From:         Christian.J.Reichetzeder@AWIIMC12.IMC.UNIVIE.AC.AT
Subject:      Precision (was Re: numeric variables)

On Thu, 10 Sep 1992 15:36:29 EDT Philip Tejera said:
>                   [....]                                  What I
>think is missing is a discussion of what precision means, and how it
>varies from platform to platform. Christian Reichetzeder (spelling?)
>posted an excellent discussion of this which went far beyond what
>the SAS manuals say, [....]

Spelling correct,  and thanks  for the  flowers. Found it  in the  archives at
MARIST and I  re-post it with a few  comments. It is a follow up  on a similar
discussion and I also quote the parts of the message I replied to:
           *****-----------------------------*****
*Date:         Mon, 25 Jul 88 11:48:42 SET
*In-Reply-To:  Message of Fri, 22 Jul 88 14:21:32 EDT from <RESBB@CUNYVM>

>Before we get too bored with repeating what the manuals say [...] let's think
>a  minute  :-) !  [...]  IBM  mainframes do  floating  point  math on  single
>(4-byte),  double (8-byte),  or extended  (16-byte) precision  variables. SAS
>doesn't seem to use the extended precision, [...]
>But wait..what about those other possible  lengths 2,3,5,6,7 that we are only
>supposed to use for  integers up to various sizes? HOW CAN  THEY BE STORED AS
>FLOATING POINT? Or are  they? [...] I can't find anything  about how it [SAS]
>stores the values. Does  it even store Length 4 or  values as floating point,
>or does it use some other IBM or its own way of storing them? [...]

Yes, IBM /370 has short(4), long(8)  and extended (16) floating point. I don't
know if  SAS internally  uses extended floating  point for  some calculations,
maybe.
To answer the question "how does SAS the LENGTH-trick" let's look:
a) at  the SAS  Basics (Vers 5),  page 157 (dealing  with LENGTH  and "Largest
   Integer Represented Exactly" [I take only 2-4, the table is up to 8])..
           Length    Largest Int
             2               255
             3            65,535
             4        16,777,215 .....
   Now if I'd use an INTEGER  (!) 2 bytes would hold -32768..+32767. Obviously
   SAS does NOT and NEVER use integer format.
b) at the representation of a /370 floating point(long form):
           +-+--------------+------/-------+
           |S|Characteristic|   Fraction   |
           +-+--------------|------/-------+
    Bits:  0 1              8             63
    "S"  is the  sign-bit.  Characteristic is  the exponent  [Base  16 !!]  in
    Excess-64 notation (i.e. exponents -64...+63  are mapped to 0..127 resp.).
    The [fractional]  point is  assumed immediately to  the left  of fraction.
    Furthermore the number  is "normalized" so that the leftmost  hex digit is
    non-zero to maintain maximum precision (i.e. at least one of the bits 8-11
    is ^=  0 except for a  "true zero" - where  also the Sign and  Charac. are
    zero).
Therefore you end with
          number = (-1*(S=1))*Fraction*(16**(Characteristic-64))
Note that  the difference between short,  long and extended floating  point is
only  precision, NOT  MAGNITUDE. When  storing a  number SAS  simply cuts  the
string  to length  LENGTH  -  losing some  precision  but  nothing else.  When
fetching the numbers they are padded on the right.
Now we also  can see the correspondence between LENGTH  and "Largest Integer".
You can exactly represent a (LENGTH-1)-Byte integer.
[....]
P.S.: the  maximum number with  LENGTH 8 is  approx. 7.237E+75, with  LENGTH 2
      it's 7.209E+75,  you don't really  lose much  in magnitude :-).  And the
      smallest value is something like 5.3976E-79 for all formats.
Remark: oh yes, SAS uses  "it's  own way"   for storing  missing values:  Zero
        Fraction and non-zero Sign/Characteristic.
               *-----------------------------*
So  much  for this  ancient  piece  of art  which  I  never thought  would  be
remembered :-).
A little bit more on PRECISION:
 At a LENGTH of  2 the largest integer represented exactly  is 255 which means
that the characteristic can hold 255 different values. This gives no more than
2 (TWO) significant decimal digits. At LENGTH 4 it's 7 digits and a maximum of
16 at LENGTH 8. Note that the least  significant digit can be 1 off the actual
value !!!

A note to Andy Norton's dream:
An  option to  set a  default precision  or default  round-off position  would
indeed be quite useful.
The implementation of a fixed (decimal)  type though is not so straightforward
because it's  always a trade-off.  The infinite set  of numbers just  can't be
represented in a  fixed number of digits (btw: addition  needs max(m,n)+1). If
you want to see the effects any medium sized pocket calculator can be used for
exercises).
IBM's PL/I  compiler does many tricks  with fixed datatypes -  the main object
being preserving as many significant digits  as possible. The side effect is -
and it is stated  in the manuals - that under  certain circumstances even with
simple expressions  you either run  into over/under-flows or get  pretty wrong
results (i.e you lose  at least the most significant digit).  The only way out
is pushing the internal/intermediate precision near infinity - and that costs.

Christian
Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU