Prev: Newbie: Regular expresion
Next: CGI and UTF-8
From: sln on 22 Sep 2009 21:33 On Tue, 22 Sep 2009 14:42:09 -0700, John Stanley <stanley(a)peak.org> wrote: > >On Tue, 22 Sep 2009, Shiping Zhang wrote: > >> On 9?22?, ??1?08?, Shiping Zhang <spz...(a)gmail.com> wrote: >>> Is this a bug in perl? >>> >>> $v = sprintf "%.1f", 2.25; >>> print $v, "\n"; >>> >>> The above code produced 2.2 >>>... > >> Okay, it's not a bug. This is due to limitation of machine (binary) >> representation of floating point numbers. A test C program behaved >> the same. > >I don't think I missed class that day, but what binary representation of >floating point CANNOT represent the base ten number "2.25"? That's 10.01 >base two. > Thats very true. And its non-repeating. Therefore, it should not be a problem going from (1.001 x 2**1)base 2, to 2.25 base 10 and having it display correctly when it comes to rounding and formatting string representation. I'm not sure that rounding happens the same way on all systems when there is a repeting binary fraction (like .55 base 10). From wikipedia: http://en.wikipedia.org/wiki/IEEE_754-1985 I wonder if you do a bitwise examination of a float variable if it will show the sign, exp, fraction bits like in the standard? Or on the language level, are the bitwise operators restricted to operations on integers? Where are the calculators that do binary <-> decimal fractions? Don't want to do it by hand all the time. -sln
From: Josef Moellers on 23 Sep 2009 03:05 J�rgen Exner wrote: > Shiping Zhang <spz1st(a)gmail.com> wrote: >> Is this a bug in perl? >> >> $v = sprintf "%.1f", 2.25; >> print $v, "\n"; >> >> The above code produced 2.2 > > I cannot reproduce this observation. For me it prints 2.3. > ( v5.10.0 built for MSWin32-x86-multi-thread) v5.8,8 running on Kubuntu 8.04LTS has the same peculiarity: $v = sprintf "%.1f", 2.25; print $v, "\n"; $v = sprintf "%.1f", 2.35; print $v, "\n"; 2.2 2.4 -- These are my personal views and not those of Fujitsu Technology Solutions! Josef M�llers (Pinguinpfleger bei FTS) If failure had no penalty success would not be a prize (T. Pratchett) Company Details: http://de.ts.fujitsu.com/imprint.html
From: Peter J. Holzer on 23 Sep 2009 13:21 On 2009-09-22 17:34, J�rgen Exner <jurgenex(a)hotmail.com> wrote: > Shiping Zhang <spz1st(a)gmail.com> wrote: >>Is this a bug in perl? >> >>$v = sprintf "%.1f", 2.25; >>print $v, "\n"; >> >>The above code produced 2.2 > > I cannot reproduce this observation. For me it prints 2.3. > ( v5.10.0 built for MSWin32-x86-multi-thread) Strange. It should produce 2.2 (2.25 is exactly halfway between 2.2 and 2.3, so the "round to even" rule is used). However, 2.2 and 2.3 aren't exactly representable, so maybe that's where the rounding error is. On Debian Linux (perl, v5.10.0 built for i486-linux-gnu-thread-multi), this: perl -e 'for(2.15,2.25,2.35,2.45,2.55,2.65, 2.75, 2.85, 2.95) {printf "%.60f %.1f\n", $_, $_ }' prints: 2.149999999999999911182158029987476766109466552734375000000000 2.1 2.250000000000000000000000000000000000000000000000000000000000 2.2 2.350000000000000088817841970012523233890533447265625000000000 2.4 2.450000000000000177635683940025046467781066894531250000000000 2.5 2.549999999999999822364316059974953532218933105468750000000000 2.5 2.649999999999999911182158029987476766109466552734375000000000 2.6 2.750000000000000000000000000000000000000000000000000000000000 2.8 2.850000000000000088817841970012523233890533447265625000000000 2.9 2.950000000000000177635683940025046467781066894531250000000000 3.0 which is exactly correct: The values which are slightly above or below 0.x5 are rounded up or down as appropriate, and 2.25 and 2.75 are rounded to even. hp
From: sln on 23 Sep 2009 15:21 On Wed, 23 Sep 2009 19:21:08 +0200, "Peter J. Holzer" <hjp-usenet2(a)hjp.at> wrote: >On 2009-09-22 17:34, J�rgen Exner <jurgenex(a)hotmail.com> wrote: >> Shiping Zhang <spz1st(a)gmail.com> wrote: >>>Is this a bug in perl? >>> >>>$v = sprintf "%.1f", 2.25; >>>print $v, "\n"; >>> >>>The above code produced 2.2 >> >> I cannot reproduce this observation. For me it prints 2.3. >> ( v5.10.0 built for MSWin32-x86-multi-thread) > >Strange. It should produce 2.2 (2.25 is exactly halfway between 2.2 and >2.3, so the "round to even" rule is used). However, 2.2 and 2.3 aren't >exactly representable, so maybe that's where the rounding error is. > >On Debian Linux (perl, v5.10.0 built for i486-linux-gnu-thread-multi), >this: > >perl -e 'for(2.15,2.25,2.35,2.45,2.55,2.65, 2.75, 2.85, 2.95) {printf "%.60f %.1f\n", $_, $_ }' > >prints: > >2.149999999999999911182158029987476766109466552734375000000000 2.1 >2.250000000000000000000000000000000000000000000000000000000000 2.2 >2.350000000000000088817841970012523233890533447265625000000000 2.4 >2.450000000000000177635683940025046467781066894531250000000000 2.5 >2.549999999999999822364316059974953532218933105468750000000000 2.5 >2.649999999999999911182158029987476766109466552734375000000000 2.6 >2.750000000000000000000000000000000000000000000000000000000000 2.8 >2.850000000000000088817841970012523233890533447265625000000000 2.9 >2.950000000000000177635683940025046467781066894531250000000000 3.0 > >which is exactly correct: The values which are slightly above or below >0.x5 are rounded up or down as appropriate, and 2.25 and 2.75 are >rounded to even. > > hp I never heard of that "round to even" rule. On my build it rounds "up" all the time. Maybe I don't have the latest build. perl -e "for(2.15,2.25,2.35,2.45,2.55,2.65, 2.75, 2.85, 2.95) {printf \"%.60f %.1f\n\", $_, $_ }" 2.149999999999999900000000000000000000000000000000000000000000 2.1 2.250000000000000000000000000000000000000000000000000000000000 2.3 2.350000000000000100000000000000000000000000000000000000000000 2.4 2.450000000000000200000000000000000000000000000000000000000000 2.5 2.549999999999999800000000000000000000000000000000000000000000 2.5 2.649999999999999900000000000000000000000000000000000000000000 2.6 2.750000000000000000000000000000000000000000000000000000000000 2.8 2.850000000000000100000000000000000000000000000000000000000000 2.9 2.950000000000000200000000000000000000000000000000000000000000 3.0 I'm sure this is a result of a define flag passed via compiler option. I' got the active state 5.10 built using gcc. I looked over the build parameters using perl -V. I've only used MS compilers, so I don't know some of the options listed. I looked for optimizations that I recognized, only saw O2, compile for speed. MS has some /FP: optimizations like precise/strict,etc.., that gcc doesen't. Gcc looks like it has nvtype as double, its size 64 bit. ---------------- v5.10.0 built for MSWin32-x86-multi-thread (with 5 registered patches) Binary build 1004 [287188] provided by ActiveState http://www.ActiveState.com Built Sep 3 2008 13:16:37 -------------- -sln
From: Peter J. Holzer on 23 Sep 2009 16:51
On 2009-09-23 19:21, sln(a)netherlands.com <sln(a)netherlands.com> wrote: > On Wed, 23 Sep 2009 19:21:08 +0200, "Peter J. Holzer" <hjp-usenet2(a)hjp.at> wrote: >>On 2009-09-22 17:34, J�rgen Exner <jurgenex(a)hotmail.com> wrote: >>> Shiping Zhang <spz1st(a)gmail.com> wrote: >>>>Is this a bug in perl? >>>> >>>>$v = sprintf "%.1f", 2.25; >>>>print $v, "\n"; >>>> >>>>The above code produced 2.2 >>> >>> I cannot reproduce this observation. For me it prints 2.3. >>> ( v5.10.0 built for MSWin32-x86-multi-thread) >> >>Strange. It should produce 2.2 (2.25 is exactly halfway between 2.2 and >>2.3, so the "round to even" rule is used). However, 2.2 and 2.3 aren't >>exactly representable, so maybe that's where the rounding error is. >> >>On Debian Linux (perl, v5.10.0 built for i486-linux-gnu-thread-multi), >>this: >> >>perl -e 'for(2.15,2.25,2.35,2.45,2.55,2.65, 2.75, 2.85, 2.95) {printf "%.60f %.1f\n", $_, $_ }' >> >>prints: >> >>2.149999999999999911182158029987476766109466552734375000000000 2.1 >>2.250000000000000000000000000000000000000000000000000000000000 2.2 >>2.350000000000000088817841970012523233890533447265625000000000 2.4 >>2.450000000000000177635683940025046467781066894531250000000000 2.5 >>2.549999999999999822364316059974953532218933105468750000000000 2.5 >>2.649999999999999911182158029987476766109466552734375000000000 2.6 >>2.750000000000000000000000000000000000000000000000000000000000 2.8 >>2.850000000000000088817841970012523233890533447265625000000000 2.9 >>2.950000000000000177635683940025046467781066894531250000000000 3.0 >> >>which is exactly correct: The values which are slightly above or below >>0.x5 are rounded up or down as appropriate, and 2.25 and 2.75 are >>rounded to even. > > I never heard of that "round to even" rule. It is mentioned in this group just about every time that rounding is discussed, which is probably at least once or twice per year. The rule was used at least since the early 20th century (Wikipedia cites a book from 1906). In IEEE-754 arithmetic (which is used in all current FP units) it is the default rounding mode. > On my build it rounds "up" > all the time. Maybe I don't have the latest build. > > perl -e "for(2.15,2.25,2.35,2.45,2.55,2.65, 2.75, 2.85, 2.95) {printf \"%.60f %.1f\n\", $_, $_ }" > > 2.149999999999999900000000000000000000000000000000000000000000 2.1 > 2.250000000000000000000000000000000000000000000000000000000000 2.3 > 2.350000000000000100000000000000000000000000000000000000000000 2.4 > 2.450000000000000200000000000000000000000000000000000000000000 2.5 > 2.549999999999999800000000000000000000000000000000000000000000 2.5 > 2.649999999999999900000000000000000000000000000000000000000000 2.6 > 2.750000000000000000000000000000000000000000000000000000000000 2.8 > 2.850000000000000100000000000000000000000000000000000000000000 2.9 > 2.950000000000000200000000000000000000000000000000000000000000 3.0 > > I'm sure this is a result of a define flag passed via compiler option. More likely it's caused by the implementation of sprintf in the C library. > I' got the active state 5.10 built using gcc. I looked over the build > parameters using perl -V. Is there a "standard" C library on Windows which gcc has to use or does it use the glibc? I suspect it's the former (I've seen similar results with Microsofts C compiler). hp |