SPUG: S.O.S: Sum-Of-Squares (nickname:Help)

Mathew D. Watson matw at eclipse-optics.com
Thu Oct 2 11:20:19 CDT 2003



> -----Original Message-----
> From: spug-list-bounces at mail.pm.org
> [mailto:spug-list-bounces at mail.pm.org]On Behalf Of Itay Furman
> Sent: Wednesday, October 01, 2003 4:05 PM
> To: Seattle Perl Users Group
> Subject: SPUG: S.O.S: Sum-Of-Squares (nickname:Help)
>
[snip]
>   $sos    += $_**2 foreach (@elem);
[snip]
>   1-$sos/($sos**0.5 * $sos**0.5), "\n";

vs.

>   1-$sos/($sos*$sos)**0.5, "\n";

I used to know this stuff cold, but here's the best I can do today.

The two expressions are equivalent using real numbers, but with C doubles,
order can be everything. Both Yitzchak and Fred have a pretty good handle on
what's happening, but I want to make a couple of points and follow with a
question.

First point ...
C double precision numbers can be exact for integer values up to a big
number that I can't remember. The machine instructions for add and multiply
_should_ preserve this property for operations whose result remains within
the domain of integers with an exact double representation. One half (0.5)
also has an exact double representation, and the same should be true
regarding arithmetic operations. What I'm leading up to is that $sos itself
should be (and probably is) exact given the test cases you used to exercise
your code.

Second point ...
Here's where order matters. $sos**0.5 probably does not have an exact double
representation, while $sos*$sos does. Thus you get a "reside" when you
multiply $sos**0.5 with itself. Square rooting $sos*$sos probably results in
an exact answer because $sos*$sos is an exact square, and the machine code
for square root probably handles that correctly.

So now I have a question for the PERL experts out there. Is there a way to
_really_know_ what the bit pattern of $sos is? If there is, then we can bit
by bit check our arithmetic. I've done this before in C, and what I recall
is that printf() (print in Perl) should not be implicitly trusted. For
example, print "1.0 = ", 1.0; results in the output "1.0 = 1", which is
correct this time, but the author of print didn't guarantee this is always
the case. What I'd like to see (and my Perl skills are too weak to do) is
something like a 'bit capture' of $sos followed by bit ANDs with binary 1
followed by a bit shift all printed out within a loop (Yes, I trust the
output of print 1;).

My $0.02,

--Mat






More information about the spug-list mailing list