Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Math

Reply
 
 
Ilya Zakharevich
Guest
Posts: n/a
 
      07-25-2007
[A complimentary Cc of this posting was sent to
Brian Blackmore
<(E-Mail Removed)>], who wrote in article <f82pte$kl3$(E-Mail Removed)>:
> > For some unfathomable reasons, Perl uses non-invertible transformations
> > between strings and numbers. So if your handling of numbers involves
> > converting them to strings, then back, the precision will be lost.


> Yes, but I would question which programming languages don't suffer
> from this behavior?


What other programming languages with multi-representation numbers do
you know?

> As is mentioned by perlnumber, converting from
> floating point to string is performed by the C compiler,


Nope, by C RT libraries. And the for these libraries, they do it
following instructions from perl.

> whence Perl is at the mercy of the system on which it was compiled.


And this the CHOICE made by perl. It could have done the conversion
itself.

> Moreover, I must admit a bit of childish moronicity here in claiming
> that I know of no language whatsoever that stores floats with
> infinite precision, whence string conversion is always faulty.


I do not follow your usage of "whence", so cannot comment.

> Indeed, I was also thinking of something simple like 1/3, but have
> you an example of a language where "1/3"=1/3? Or are there so many
> that I'm just being dim?


Yes. E.g., see

perl -MMath:ari=:int

Hope this helps,
Ilya

 
Reply With Quote
 
 
 
 
Brian Blackmore
Guest
Posts: n/a
 
      07-25-2007
Ilya Zakharevich <(E-Mail Removed)> wrote:
> [A complimentary Cc of this posting was sent to
> Brian Blackmore
> <(E-Mail Removed)>], who wrote in article <f82pte$kl3$(E-Mail Removed)>:
> > > For some unfathomable reasons, Perl uses non-invertible transformations
> > > between strings and numbers. So if your handling of numbers involves
> > > converting them to strings, then back, the precision will be lost.


> > Yes, but I would question which programming languages don't suffer
> > from this behavior?


> What other programming languages with multi-representation numbers do
> you know?


I thought we were talking about the classic `type conversion' issue.

> > As is mentioned by perlnumber, converting from
> > floating point to string is performed by the C compiler,


> Nope, by C RT libraries. And the for these libraries, they do it
> following instructions from perl.


Following your advice, and checking perlnumber, what I found was what
I said up above:

"RESTRICTION: The conversions marked with "(*)" above
involve steps performed by the C compiler. In particular,
bugs/features of the compiler used may lead to breakage of
some of the above rules."

Since "native floating_point --> decimal string (*)" and
"decimal string --> native floating point (*)" are so marked, I
interpret that to mean that perl is at the whim of whatever C compiler
was used.

> > whence Perl is at the mercy of the system on which it was compiled.


> And this the CHOICE made by perl. It could have done the conversion
> itself.


True, but that's a bit like saying that it's output could be based on
the TeX typesetting engine, that it's input stream should be entirely
XMLized and should natively handle images and gestured input, and that
it should natively translated any symbol set into the appropriate
characters necessary to create code.

> > Moreover, I must admit a bit of childish moronicity here in claiming
> > that I know of no language whatsoever that stores floats with
> > infinite precision, whence string conversion is always faulty.


> I do not follow your usage of "whence", so cannot comment.


Lacking a programming language where float->string conversion is
invertible, converting to strings in any language creates a loss of
precision, which is no difficulty to imagine given a base ten
representation in a string in comparison to a base two representation
for a float.

> > Indeed, I was also thinking of something simple like 1/3, but have
> > you an example of a language where "1/3"=1/3? Or are there so many
> > that I'm just being dim?


> Yes. E.g., see


> perl -MMath:ari=:int


So perl has the ability after all, and doesn't use non-invertible
transforms, so there are no unfathomable reasons.

In any case, I don't find this a satisfactory example of a programming
language that avoids the concern in question. If anything, we've just
verified that arbitrary precision can doubtless be added to any Turing
complete language. That does not imply that Perl is any better or
worse than anything else in that regard.

Am I still missing the obvious examples of programming languages where
type casts are invertible without information loss?

--
Brian Blackmore
blb8 at po dot cwru dot edu
 
Reply With Quote
 
 
 
 
Ilya Zakharevich
Guest
Posts: n/a
 
      07-25-2007
[A complimentary Cc of this posting was sent to
Brian Blackmore
<(E-Mail Removed)>], who wrote in article <f86uje$3mf$(E-Mail Removed)>:
> > > > For some unfathomable reasons, Perl uses non-invertible transformations
> > > > between strings and numbers. So if your handling of numbers involves
> > > > converting them to strings, then back, the precision will be lost.

>
> > > Yes, but I would question which programming languages don't suffer
> > > from this behavior?


> > What other programming languages with multi-representation numbers do
> > you know?


> I thought we were talking about the classic `type conversion' issue.


If you mean *explicit* conversion from binary representation to string
and back, then ANY language I know can do it losslessly.

> > Nope, by C RT libraries. And the for these libraries, they do it
> > following instructions from perl.

>
> Following your advice, and checking perlnumber, what I found was what
> I said up above:
>
> "RESTRICTION: The conversions marked with "(*)" above
> involve steps performed by the C compiler. In particular,
> bugs/features of the compiler used may lead to breakage of
> some of the above rules."


I wonder whether it is the original text (written by me); might be so.
It does not make any sense; the intent is clear, but the wording is
very bad... I tried to "keep things simple", but this error is not in
that category...

> Since "native floating_point --> decimal string (*)" and
> "decimal string --> native floating point (*)" are so marked, I
> interpret that to mean that perl is at the whim of whatever C compiler
> was used.


Yes - in the sense, that usually C compiler determines which CRTL is used.

What you are missing however, that even if Perl uses CRTL functions,
they take a lot of "options". And it is the options which Perl uses
which lead to precision loss.

AND, as I said, Perl could have used some specialized functions tuned
up to its problem domain (multi-representation).

> > > whence Perl is at the mercy of the system on which it was compiled.

>
> > And this the CHOICE made by perl. It could have done the conversion
> > itself.

>
> True, but that's a bit like saying that it's output could be based on
> the TeX typesetting engine, that it's input stream should be entirely
> XMLized and should natively handle images and gestured input, and that
> it should natively translated any symbol set into the appropriate
> characters necessary to create code.


Sorry, I have no idea what was it you wanted to express here.

> Lacking a programming language where float->string conversion is
> invertible,


??? See above.

> converting to strings in any language creates a loss of
> precision, which is no difficulty to imagine given a base ten
> representation in a string in comparison to a base two representation
> for a float.


> > > Indeed, I was also thinking of something simple like 1/3, but have
> > > you an example of a language where "1/3"=1/3? Or are there so many
> > > that I'm just being dim?

>
> > Yes. E.g., see

>
> > perl -MMath:ari=:int

>
> So perl has the ability after all, and doesn't use non-invertible
> transforms, so there are no unfathomable reasons.


Again, the way I can parse this, it makes no sense.

Hope this helps,
Ilya
 
Reply With Quote
 
Robert Hicks
Guest
Posts: n/a
 
      07-26-2007
So the answer is "yes" but be careful. : )

Robert

 
Reply With Quote
 
Peter J. Holzer
Guest
Posts: n/a
 
      07-26-2007
On 2007-07-23 17:52, Brian Blackmore <(E-Mail Removed)> wrote:
> Ilya Zakharevich <(E-Mail Removed)> wrote:
>> For some unfathomable reasons, Perl uses non-invertible transformations
>> between strings and numbers. So if your handling of numbers involves
>> converting them to strings, then back, the precision will be lost.

>
> Yes, but I would question which programming languages don't suffer
> from this behavior?


I don't know. Which does? C certainly doesn't (although specific
implementations might).

> As is mentioned by perlnumber, converting from floating point to
> string is performed by the C compiler, whence Perl is at the mercy of
> the system on which it was compiled.


The glibc has no problem in this regard, AFAICT.

> Moreover, I must admit a bit of childish moronicity here in claiming
> that I know of no language whatsoever that stores floats with infinite
> precision, whence string conversion is always faulty.


Nope. Converting a binary number of a given precision to decimal and
back to binary is always possible without loss[0]. The problem seems to
be that perl uses only 15 decimal digits, while it would need 16 to
cover the 53 bits of mantissa (I think 16 should be enough, but I
haven't considered all cases - maybe there are some where 17 are
required).


> Indeed, I was also thinking of something simple like 1/3, but have
> you an example of a language where "1/3"=1/3? Or are there so many
> that I'm just being dim?


That's a completely different problem. 1/3 cannot be precisely
represented in binary, so the question whether it could be converted to
decimal and back is moot. The closest approximation to 1/3 which can be
represented in a 64 bit FP number
(0.33333333333333331482961625624739099293947219848 6328125) can be
converted to decimal and back without loss of precision.


hp


[0] In fact that's true for any two integral bases.

--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | http://www.velocityreviews.com/forums/(E-Mail Removed) |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
 
Reply With Quote
 
Brian Blackmore
Guest
Posts: n/a
 
      07-27-2007
Ilya Zakharevich <(E-Mail Removed)> wrote:
> [A complimentary Cc of this posting was sent to
> Brian Blackmore
> <(E-Mail Removed)>], who wrote in article <f82pte$kl3$(E-Mail Removed)>:
> > > For some unfathomable reasons, Perl uses non-invertible transformations
> > > between strings and numbers. So if your handling of numbers involves
> > > converting them to strings, then back, the precision will be lost.


> > Yes, but I would question which programming languages don't suffer
> > from this behavior?


> What other programming languages with multi-representation numbers do
> you know?


Yeah, I have to apologize here because I've conflated a couple of
ideas and caused a minor communication problem. Certainly the 1/3
issue is a matter of representation, whence a different issue, but I
brought that in from the other part of the thread. I think I've
been looking for a specific example to the first statement way up
above here, about losing precision during conversion. Is what you
had in mind something like this:

#!/usr/bin/perl

$a=42.1; for (1..30) { $a+=0.1 }
$b="$a"; print "a=",$a," b=",$b,"\n";
$a==$b ? print "Equal\n" : print "Not equal\n" ;

> > As is mentioned by perlnumber, converting from
> > floating point to string is performed by the C compiler,


> Nope, by C RT libraries. And the for these libraries, they do it
> following instructions from perl.


I would like to know for future reference if this is in the manuals
or if I misinterpreted what's in perlnumber. Also, are these
instructions discussed anywhere, or just in the source? I'd like to
know exactly what's happening, so I can look at the sources, but it
might be nice to have this type of example in perlnumber.

> > whence Perl is at the mercy of the system on which it was compiled.


> And this the CHOICE made by perl. It could have done the conversion
> itself.


Is it a choice of what parameters to pass to CRTL that is causing
the fault, or is it the choice to use the CRTL period? If it's a
parameter issue, why haven't the parameters been changed?

> > Moreover, I must admit a bit of childish moronicity here in claiming
> > that I know of no language whatsoever that stores floats with
> > infinite precision, whence string conversion is always faulty.


> I do not follow your usage of "whence", so cannot comment.


Sorry, I conflated in the 1/3 example here.


Thanks all for the patience, and I hope we're not too far off topic,
but I just want to make sure I understand what actually is
unfathomable here and why, so I don't fall prey to these problems in
the future.


--
Brian Blackmore
blb8 at po dot cwru dot edu
 
Reply With Quote
 
Peter J. Holzer
Guest
Posts: n/a
 
      07-27-2007
On 2007-07-27 12:26, José Luis Pérez Diez <(E-Mail Removed)> wrote:
> In article <(E-Mail Removed)>, Peter J. Holzer
> wrote:
>> Nope. Converting a binary number of a given precision to decimal and
>> back to binary is always possible without loss[0]. The problem seems to
>> be that perl uses only 15 decimal digits, while it would need 16 to
>> cover the 53 bits of mantissa (I think 16 should be enough, but I
>> haven't considered all cases - maybe there are some where 17 are
>> required).
>>

> perl -Mbignum=a,100 -e 'my $numero=0; for (0..53) {$numero+= 1/2**$_}
> ;$numero =~ s/0*$//g;print length($numero)."\n$numero\n";'
> 55
> 1.999999999999999888977697537484345957636833190917 96875


I'm not quite sure what you are trying to demonstrate here. That number
is not exactly representable in an IEEE-64bit-FP number (the mantissa is
one bit too long, afaics).

The nearest two numbers are

1.999999999999999777955395074968691915273666381835 9375 and 2.0

1.999999999999999777955395074968691915273666381835 9375 is adequately
represented by 1.9999999999999998, which indeed uses 17 digits in
decimal. So you have demonstrated that at least 17 decimal digits are
needed to represent 53 bits of mantissa. That answers my question -
thanks; but I would have preferred a more direct answer.

hp


--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | (E-Mail Removed) |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
 
Reply With Quote
 
Brian Blackmore
Guest
Posts: n/a
 
      07-27-2007
Brian Blackmore <(E-Mail Removed)> wrote:
> Ilya Zakharevich <(E-Mail Removed)> wrote:
> > [A complimentary Cc of this posting was sent to
> > Brian Blackmore
> > <(E-Mail Removed)>], who wrote in article <f82pte$kl3$(E-Mail Removed)>:
> > > > For some unfathomable reasons, Perl uses non-invertible transformations
> > > > between strings and numbers. So if your handling of numbers involves
> > > > converting them to strings, then back, the precision will be lost.


> > > Yes, but I would question which programming languages don't suffer
> > > from this behavior?


> > What other programming languages with multi-representation numbers do
> > you know?


> Yeah, I have to apologize here because I've conflated a couple of
> ideas and caused a minor communication problem. Certainly the 1/3
> issue is a matter of representation, whence a different issue, but I
> brought that in from the other part of the thread. I think I've
> been looking for a specific example to the first statement way up
> above here, about losing precision during conversion. Is what you
> had in mind something like this:


> #!/usr/bin/perl


> $a=42.1; for (1..30) { $a+=0.1 }
> $b="$a"; print "a=",$a," b=",$b,"\n";
> $a==$b ? print "Equal\n" : print "Not equal\n" ;



Sorry, I rescind my understanding because in C:

#include <stdio.h>
#include <stdlib.h>

int main() {
double a=42.1;
char* c;
double d;
int i=30;

for(;i>0;i--) { a+=0.1; }
sprintf(c,"%f",a);
d=atof(c);

printf("%f\n",a);
printf("%f\n",d);

if(a!=d) { printf("Lost precision\n"); }
else { printf("Okay\n"); }

return 0;
}


Both report on lost precision.

So now I'm back to being confused. When you speak of these
non-invertible transforms, is this what you had in mind? If so, it
doesn't seem to work on C either (contrary to a statement from
another person's post in this thread).

If this is not what you had in mind, can you give an example of Perl
going bad in the way you mentioned?

Thanks a bunch for your time.

--
Brian Blackmore
blb8 at po dot cwru dot edu
 
Reply With Quote
 
Ilya Zakharevich
Guest
Posts: n/a
 
      07-27-2007
[A complimentary Cc of this posting was sent to
Brian Blackmore
<(E-Mail Removed)>], who wrote in article <f8d43c$5ed$(E-Mail Removed)>:
> #!/usr/bin/perl
>
> $a=42.1; for (1..30) { $a+=0.1 }
> $b="$a"; print "a=",$a," b=",$b,"\n";
> $a==$b ? print "Equal\n" : print "Not equal\n" ;
>
> > > As is mentioned by perlnumber, converting from
> > > floating point to string is performed by the C compiler,

>
> > Nope, by C RT libraries. And the for these libraries, they do it
> > following instructions from perl.

>
> I would like to know for future reference if this is in the manuals
> or if I misinterpreted what's in perlnumber.


I think we discussed this already. I might have oversimplified things
when I wrote perlnumber (or [hopefully ;-] it might have been a later edit).

> Also, are these instructions discussed anywhere, or just in the
> source?


Might be in the autogenerated POD for Configure variables:

perl -V:d_Gconvert

There is also perlvar for $#, but I suspect it is erroneous.

> > > whence Perl is at the mercy of the system on which it was compiled.

>
> > And this the CHOICE made by perl. It could have done the conversion
> > itself.

>
> Is it a choice of what parameters to pass to CRTL that is causing
> the fault, or is it the choice to use the CRTL period? If it's a
> parameter issue, why haven't the parameters been changed?


There are two conflicting targets:

a) One does not want a silly semantic of number conversion (like
information loss);

b) One does not want to see silly bug reports like

why
perl -wle "$#='%.17g'; print 17.1"
prints garbage digits?

(I assume that this value of $# is the default, so setting it
would not appear in the bug report.)

c) The conversion should not be too slow.

With the current choice of $#, one STILL gets stuff as in "b". And
the precision is always always lost. But with finer $#, the bug
reports would be more frequent.

About mid-90s, there was a discussion about adding custom
stringification function, which does not has semantic of %.NNg, but
does better: it emits the minimal number of digits such that the
following conversion to a number would result in the initial number.
Somebody did a test, and found that using this custom function would
significantly slow down number-to-string conversion. So "c" was violate.

["a" would be fixed; it is not clear how this would change "b",
since fixing "a" increases number of cases where people would see
mismatch with "school arithmetic" (after performing arithmetic
operations on numbers with a few significant digits).]

However, a couple of years after this, I did some research, and found
out that perl was not caching results of number-to-string conversion.
After fixing it, the number of times perl calls number-to-string
conversion routines should have changed dramatically.

So it MIGHT be that using such a custom conversion function would not
violate "c". It also MIGHT be that it would not significantly
increase the flow of "b".

Choices, choices, choices - and shortage of time.

Hope this helps,
Ilya
 
Reply With Quote
 
Peter J. Holzer
Guest
Posts: n/a
 
      07-27-2007
On 2007-07-27 19:05, Brian Blackmore <(E-Mail Removed)> wrote:
> Brian Blackmore <(E-Mail Removed)> wrote:
>> Is what you had in mind something like this:

>
>> #!/usr/bin/perl

>
>> $a=42.1; for (1..30) { $a+=0.1 }


$a after that is not 45.1. It is about 45.100000000000044.

>> $b="$a"; print "a=",$a," b=",$b,"\n";
>> $a==$b ? print "Equal\n" : print "Not equal\n" ;

>
>
> Sorry, I rescind my understanding because in C:
>
> #include <stdio.h>
> #include <stdlib.h>
>
> int main() {
> double a=42.1;
> char* c;
> double d;
> int i=30;
>
> for(;i>0;i--) { a+=0.1; }
> sprintf(c,"%f",a);
> d=atof(c);
>
> printf("%f\n",a);
> printf("%f\n",d);
>
> if(a!=d) { printf("Lost precision\n"); }
> else { printf("Okay\n"); }
>
> return 0;
> }
>
>
> Both report on lost precision.


For me it reports "segmentation fault (core dumped)" (well, actually the
shell reports that, the program dies before it can report anything). c
is used without being initialized.

The problem in your C program is that you are rounding a to six
fractional digits. Of course the number isn't the same when you round
it.

You need at least 16 or 17 for the 53 bits of mantissa (log10(2**53) ==
15.95). If you replace sprintf(c,"%f",a); with sprintf(c,"%.15f",a); (2
digits before the decimal point, 15 after is 17 digits total), the
program reports "Okay".

You can do the same in Perl of course. The problem in Perl is that Perl
does conversions between numeric and string values automatically and the
programmer may not be aware of it - so he may lose precision without
noticing it. In C you explicitely have to use (s)printf, and you
hopefully do think about possible loss of precision there.

hp


--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | (E-Mail Removed) |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Math.random() and Math.round(Math.random()) and Math.floor(Math.random()*2) VK Javascript 15 05-02-2010 03:43 PM
Math.min and Math.max for byte / short Philipp Java 9 07-23-2008 12:37 AM
math.h trig functions questions (and some forgotten high school math) Mark Healey C Programming 7 05-22-2006 10:42 AM
Re: Is still math.h the C++ math library ? AciD_X C++ 4 04-01-2004 07:29 PM
Why can I not use: Math a=new Math(); chirs Java 18 03-02-2004 06:00 PM



Advertisments