Simplification of products and the number 0



 On 10/13/10 5:21 PM, Dieter Kaiser wrote:

[snip]
> This is a suggested table for the multiplication of zeros (all flags
> have their standard value):
>
> /* Table 2.1: Multiplication of zeros
>  *
>  * TIMES   | 0       0.0     0.0b0   [0]     [0.0]   [0.0b0]
>  * ---------------------------------------------------------
>  * 0       | 0       0.0     0.0b0   [0]     [0.0]   [0.0b0]    
>  * 0.0     | 0.0     0.0     0.0b0   [0.0]   [0.0]   [0.0b0]
>  * 0.0b0   | 0.0b0   0.0b0   0.0b0   [0.0b0] [0.0b0] [0.0b0]
>  * [0]     | [0]     [0.0]   [0.0b0] [0]     [0.0]   [0.0b0]
>  * [0.0]   | [0.0]   [0.0]   [0.0b0] [0.0]   [0.0]   [0.0b0]
>  * [0.0b0] | [0.0b0] [0.0b0] [0.0b0] [0.0b0] [0.0b0] [0.0b0]
>  */
>
>
[snip]
> The following table is interesting too.
>
> /* Table 2.2: Multiplication of zeros and the number one
>  *
>  * MUL     | 1       1.0     1.0b0   [1]     [1.0]   [1.0b0]
>  * ---------------------------------------------------------
>  * 0       | 0       0.0     0.0b0   [0]     [0.0]   [0.0b0]   
>  * 0.0     | 0.0     0.0     0.0b0   [0.0]   [0.0]   [0.0b0]
>  * 0.0b0   | 0.0b0   0.0b0   0.0b0   [0.0b0] [0.0b0] [0.0b0]
>  * [0]     | [0]     [0.0]   [0.0b0] [0]     [0.0]   [0.0b0]
>  * [0.0]   | [0.0]   [0.0]   [0.0b0] [0.0]   [0.0]   [0.0b0]
>  * [0.0b0] | [0.0b0] [0.0b0] [0.0b0] [0.0b0] [0.0b0] [0.0b0]
>  */
>
>
[snip]
> Again a table: The following table is constructed the same way as the
> tables from above. But now Maxima simplifies all multiplications as
> shown.
>
> /* Table 2.3: Multiplication of the number one
>  *
>  * TIMES   | 1       1.0     1.0b0   [1]     [1.0]   [1.0b0]
>  * ---------------------------------------------------------
>  * 1       | 1       1.0     1.0b0   [1]     [1.0]   [1.0b0]   
>  * 1.0     | 1.0     1.0     1.0b0   [1.0]   [1.0]   [1.0b0]
>  * 1.0b0   | 1.0b0   1.0b0   1.0b0   [1.0b0] [1.0b0] [1.0b0]
>  * [1]     | [1]     [1.0]   [1.0b0] [1]     [1.0]   [1.0b0]
>  * [1.0]   | [1.0]   [1.0]   [1.0b0] [1.0]   [1.0]   [1.0b0]
>  * [1.0b0] | [1.0b0] [1.0b0] [1.0b0] [1.0b0] [1.0b0] [1.0b0]
>  */
>
For people familiar with how floating-point contagion works in Lisp and
other languages (that allow contagion), these results are the expected
results.

However, I think clisp (in non-ANSI CL mode) supported the idea of
floating-contagion returning the *least* precise result so 1.0 * 1.0b0
would return 1.0 instead of 1b0.  But 1*1.0 is 1.0 because 1 is
"infinitely precise".   This has a certain appeal especially if you've
been careless with precision and were expecting a double-float result
but only got a single-float result. :-)  In other Lisps, you would just
get the double-float result, without knowing there was some potential
source of inaccuracy.
 
(This approach would have helped isolate an issue with some of maxima's
tests because cl:expt was returning double-float results but with
single-float accuracy.  Only by carefully comparing the computations
with another Lisp was it determined where the problem was.)

Ray