[perl #59006] stringifying Floats into PIR literals loses (a lot of) precision
On Wed Sep 24 22:31:36 2008, [EMAIL PROTECTED] wrote: On Tuesday 23 September 2008 21:37:09 Patrick R. Michaud wrote: +1 in favor of applying this patch (and updating any tests to match) -- this will _really_ improve things for PCT and Rakudo. Thanks! Applied as r31402. -- c This closes out the original request. Resolving ticket. -- Will Coke Coleda
Re: [perl #59006] stringifying Floats into PIR literals loses (a lot of) precision
On Tuesday 23 September 2008 21:37:09 Patrick R. Michaud wrote: +1 in favor of applying this patch (and updating any tests to match) -- this will _really_ improve things for PCT and Rakudo. Thanks! Applied as r31402. -- c
Re: [perl #59006] stringifying Floats into PIR literals loses (a lot of) precision
On Thursday 18 September 2008 06:13:30 Patrick R. Michaud (via RT) wrote: When generating PIR output (e.g., from the compiler tools), we often need to convert a Float value into an equivalent representation for PIR. Unfortunately, all of the mechanisms I've looked at for doing this lose a lot of precision, which really isn't acceptable. The prime candidate for this seems to be the Cget_repr opcode, which AFAICT is intended for this purpose. However, it appears to provide only about 7 digits of precision. Yes. The approaches I've tried thus far are simple stringification, the get_repr opcode, and variations on sprintf formats. Here's an example showing the difficulty: $ cat x.pir .sub 'main' $N0 = exp 1.0 'as_pir'($N0) .end .sub 'as_pir' .param pmc value print set_p_s : $S0 = value say $S0 print get_repr : $S0 = get_repr value say $S0 print printf %g: $P0 = new 'ResizablePMCArray' push $P0, value $S0 = sprintf '%g', $P0 say $S0 .end $ ./parrot x.pir set_p_s : 2.71828 get_repr : 2.718282 printf %g: 2.71828 By way of comparison, Perl 5 gives a far more reasonable result: $ perl -e 'print exp(1),\n' 2.71828182845905 One approach might be to take whatever algorithm Perl 5 uses for stringifying its floats (or something close to it), and adopt that for get_repr and/or Float stringification. How about 15 digits of precision? The attached patch (which requires a reconfigure) does so. It also drops trailing zeroes, which may or may not be what you want. It's much more precise though: set_p_s : 2.71828182845905 get_repr : 2.718281828459045 printf %g: 2.718282 (I used %.15g for the format.) Note that several tests fail as they rely on hard-coded values matching the %vg and %g formats, with seven digits of precision retaining any trailing zeroes. -- c === config/auto/format.pm == --- config/auto/format.pm (revision 31407) +++ config/auto/format.pm (local) @@ -67,7 +67,7 @@ $nvsize = $floatsize; if ( $nv eq double ) { $nvsize = $doublesize; -$nvformat = %f; +$nvformat = %.15g; } elsif ( $nv eq long double ) { === src/string.c == --- src/string.c (revision 31407) +++ src/string.c (local) @@ -2079,7 +2079,7 @@ /* Too damn hard--hand it off to Parrot_sprintf, which'll probably use the system sprintf anyway, but has gigantic buffers that are awfully hard to overflow. */ -return Parrot_sprintf_c(interp, %vg, f); +return Parrot_sprintf_c(interp, FLOATVAL_FMT, f); }
Re: [perl #59006] stringifying Floats into PIR literals loses (a lot of) precision
On Tue, Sep 23, 2008 at 08:47:15PM -0700, chromatic wrote: On Thursday 18 September 2008 06:13:30 Patrick R. Michaud (via RT) wrote: When generating PIR output (e.g., from the compiler tools), we often need to convert a Float value into an equivalent representation for PIR. Unfortunately, all of the mechanisms I've looked at for doing this lose a lot of precision, which really isn't acceptable. How about 15 digits of precision? The attached patch (which requires a reconfigure) does so. It also drops trailing zeroes, which may or may not be what you want. It's much more precise though: set_p_s : 2.71828182845905 get_repr : 2.718281828459045 printf %g: 2.718282 The patch works very well -- I even tried it with very large (1.234e+34) and very small (1.234e-34) positive numbers and always got back a reasonable string that preserved the level of precision I was looking for. Dropping the trailing zeroes is fine (and preferred). +1 in favor of applying this patch (and updating any tests to match) -- this will _really_ improve things for PCT and Rakudo. Thanks! Pm
[perl #59006] stringifying Floats into PIR literals loses (a lot of) precision
# New Ticket Created by Patrick R. Michaud # Please include the string: [perl #59006] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt3/Ticket/Display.html?id=59006 When generating PIR output (e.g., from the compiler tools), we often need to convert a Float value into an equivalent representation for PIR. Unfortunately, all of the mechanisms I've looked at for doing this lose a lot of precision, which really isn't acceptable. The prime candidate for this seems to be the Cget_repr opcode, which AFAICT is intended for this purpose. However, it appears to provide only about 7 digits of precision. The approaches I've tried thus far are simple stringification, the get_repr opcode, and variations on sprintf formats. Here's an example showing the difficulty: $ cat x.pir .sub 'main' $N0 = exp 1.0 'as_pir'($N0) .end .sub 'as_pir' .param pmc value print set_p_s : $S0 = value say $S0 print get_repr : $S0 = get_repr value say $S0 print printf %g: $P0 = new 'ResizablePMCArray' push $P0, value $S0 = sprintf '%g', $P0 say $S0 .end $ ./parrot x.pir set_p_s : 2.71828 get_repr : 2.718282 printf %g: 2.71828 By way of comparison, Perl 5 gives a far more reasonable result: $ perl -e 'print exp(1),\n' 2.71828182845905 One approach might be to take whatever algorithm Perl 5 uses for stringifying its floats (or something close to it), and adopt that for get_repr and/or Float stringification. The current situation blocks PCT's (and thus HLLs such as Rakudo) ability to generate reasonably accurate PIR involving floating point constants. Phrased another way: to get reasonable floating point semantics HLLs are currently having to restrict themselves to supporting floating point literal syntaxes that directly or easily translate to PIR output and don't rely on actually computing the float value. Pm
Re: [perl #59006] stringifying Floats into PIR literals loses (a lot of) precision
On Thu, Sep 18, 2008 at 9:13 AM, Patrick R. Michaud (via RT) [EMAIL PROTECTED] wrote: # New Ticket Created by Patrick R. Michaud # Please include the string: [perl #59006] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt3/Ticket/Display.html?id=59006 When generating PIR output (e.g., from the compiler tools), we often need to convert a Float value into an equivalent representation for PIR. SNIP This sounds very much like partcl's need to support [set tcl_precision 0] -- Will Coke Coleda