From: sln on
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
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
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
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
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
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5
Prev: Newbie: Regular expresion
Next: CGI and UTF-8