Date:         Thu, 10 Sep 1992 16:16:16 PDT
Reply-To:     Melvin Klassen <KLASSEN@UVVM.BITNET>
Comments:     Warning -- original Sender: tag was NETNEWS@UVVM.UVIC.CA
From:         Melvin Klassen <KLASSEN@UVVM.BITNET>
Subject:      Re: numbers in SAS

"Dr. Paul A. Thompson" <pat@PO.CWRU.EDU> writes:
> There will be no noticable differences between an ANOVA using
> LENGTH = 8 variables and LENGTH = 7 variables.

This issue falls into the "statistician, know thy data" category.
If the raw data only contains 6 significant digits,
then there will be *no* reported differences even when using
LENGTH = 6 and LENGTH = 5 variables!  If the input data is known
to be integer-valued, then use of LENGTH = 4 or even LENGTH=3
will still produce identical summary tables.

>>    IF  (A-0.1) < 1.0E-5  THEN PUT 'Close enough for jazz!'
>IMHO, the need for these elaborate IF statements may be BECAUSE of the
>use of the LENGTH < 8.  That is, short-length variables necessitate
>more complex IF statements.

Yes, if one codes the IF statement sloppily, i.e., testing for equality,
then, by all means, feel free to never code a LENGTH statement,
and also feel free to use twice as much disk-space to store your data.
It's just one style of programming -- there are many!

My "elaborate" and "complex" IF statement is more likely
to produce the "right" answers, no matter what LENGTH value is used.
It's as simple as "proper coding yields proper results".

>Examine these results, run on PC SAS, Version 6.04:
>   data chk;  length val     vam 8;
>                     val=.3; vam=.3;
All that is proved by the above code is that the SAS compiler is not "flaky",
i.e., when it encounters multiple occurrences of a string ('.3'),
it will produce the identical floating-point number each time.

>   data chk; set chk;
>     if (val = .3)  then put "val = .3" ; else put "val^= .3" ;
>     if (vam = val) then put "val = vam"; else put "val^= vam";
>   run;
>val = .3
>val = vam
>   data chk; /* This step truncates both variables to LENGTH=7. */
>   length val vam 7; set chk;
>   data chk;
>     if (val = .3)  then put "val = .3" ; else put "val^= .3" ;
>     if (vam = val) then put "val = vam"; else put "val^= vam";
>   run;
>val^= .3
>val = vam
>
> The point is that the shorter lengths do lose something.
> SAS takes the variable VAL and compares it against the value ".3".

SAS decompresses the LENGTH=7 stored value into a LENGTH=8 data-step variable.
Now that this variable is at the same precision as the constant,
the comparison can be done.  Of course, the result is an inequality,
due to the loss of significant digits when the data-step variable
was originally written to the SAS dataset, and due to the fact
that **any** finite-precision representation of a fractional number
will be inexact.

> If you routinely use short lengths, you will probably find lots of
> these inconsistent results.
> So my conclusion is that consistent lengths produce consistent results.

I've shown that there is nothing "inconsistent" about these results.
SAS is doing exactly what the user has coded.
The problem is that the coding only weakly expresses the desires of the user,
i.e., the coding fails to compensate for any computer's weakness
in performing finite-precision binary-arithmetic.

>The real problem is differing levels of imperfect representation.
>If you use different lengths, your imperfect representations will be
>different.  If you use the same length all around, your imperfect
representations will be consistent, and USUALLY yield the correct result.

Why settle for the compromise of "usually" -- proper coding
in the IF statement will *always* solve this problem,
and, as a bonus, produce smaller files on your disk.
Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU