Konrad Korzeniowski | 16 Dec 18:06

number() floated?

Hi there,

I'm using 1.1.26-6 version of libxslt (Debian Lenny), and cannot find any explanation regarding described below behaviour.

I got following simple xslt file:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
    <xsl:template match="/">
    <xsl:value-of select="number('8.95')"/>
    </xsl:template>
</xsl:stylesheet>

running xsltproc with this xsl against any xml gives:
8.949999999999999

Is this expected? Shouldn't this be 8.85?

Thanks for any explanation.

Best regards,
Konrad Korzeniowski
_______________________________________________
xslt mailing list, project page http://xmlsoft.org/XSLT/
xslt <at> gnome.org
http://mail.gnome.org/mailman/listinfo/xslt
Laurence Rowe | 3 Jan 21:53
Picon
Gravatar

Re: number() floated?

On 16 December 2011 17:06, Konrad Korzeniowski <konrad <at> pandur.net> wrote:
> Hi there,
>
> I'm using 1.1.26-6 version of libxslt (Debian Lenny), and cannot find any
> explanation regarding described below behaviour.
>
> I got following simple xslt file:
>
> <?xml version="1.0" encoding="UTF-8"?>
>
> <xsl:stylesheet version="1.0"
> xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
>     <xsl:template match="/">
>     <xsl:value-of select="number('8.95')"/>
>     </xsl:template>
> </xsl:stylesheet>
>
>
> running xsltproc with this xsl against any xml gives:
> 8.949999999999999
>
> Is this expected? Shouldn't this be 8.85?
>
> Thanks for any explanation.

Not all decimals may be exactly represented in binary floating point.
See: http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding

Laurence
Vincent Lefevre | 3 Jan 23:00

Re: number() floated?

On 2012-01-03 20:53:40 +0000, Laurence Rowe wrote:
> On 16 December 2011 17:06, Konrad Korzeniowski <konrad <at> pandur.net> wrote:
> > I got following simple xslt file:
> >
> > <?xml version="1.0" encoding="UTF-8"?>
> >
> > <xsl:stylesheet version="1.0"
> > xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
> >     <xsl:template match="/">
> >     <xsl:value-of select="number('8.95')"/>
> >     </xsl:template>
> > </xsl:stylesheet>
> >
> >
> > running xsltproc with this xsl against any xml gives:
> > 8.949999999999999
> >
> > Is this expected? Shouldn't this be 8.85?
> >
> > Thanks for any explanation.
> 
> Not all decimals may be exactly represented in binary floating point.
> See: http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding

Except that this seems to be a bug here:

$ /usr/bin/printf "%a\n" 8.95
0x8.f33333333333333p+0

This is the binary value represented internally.

$ /usr/bin/printf "%a\n" 8.949999999999999
0x8.f33333333332eb2p+0

This is quite different!

Now, if the XSLT spec says that the value should be rounded *downward*
to decimal with a fixed number of decimal digits, this would be correct.
But this would be a quite surprising choice.

--

-- 
Vincent Lefèvre <vincent <at> vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)
Vincent Lefevre | 3 Jan 23:33

Re: number() floated?

On 2012-01-03 23:00:16 +0100, Vincent Lefevre wrote:
> On 2012-01-03 20:53:40 +0000, Laurence Rowe wrote:
> > On 16 December 2011 17:06, Konrad Korzeniowski <konrad <at> pandur.net> wrote:
[...]
> > >     <xsl:value-of select="number('8.95')"/>
[...]
> 
> Except that this seems to be a bug here:

After looking at the spec, I confirm this is a bug. The XPath spec
says for number(): "a string that consists of optional whitespace
followed by an optional minus sign followed by a Number followed
by whitespace is converted to the IEEE 754 number that is nearest
(according to the IEEE 754 round-to-nearest rule) to the mathematical
value represented by the string"

The nearest value X is the following one (represented exactly in
radix 16, thanks to %a):

> $ /usr/bin/printf "%a\n" 8.95
> 0x8.f33333333333333p+0

But actually (see below) the internal representation doesn't matter
here.

Concerning xsl:value-of, the XSLT spec says that for a number, the
XPath string() fucntion is used, and the XPath spec says for the
above value: "otherwise, the number is represented in decimal form
as a Number including [...]; beyond the one required digit after
the decimal point there must be as many, but only as many, more
digits as are needed to uniquely distinguish the number from all
other IEEE 754 numeric values." (FYI, that's the IEEE 754 rule for
conversions.)

As a consequence, the output value should be "8.95" (like the input)
because 8.95 rounds to X and has less than 17 digits.

--

-- 
Vincent Lefèvre <vincent <at> vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)
Laurence Rowe | 4 Jan 01:33
Picon
Gravatar

Re: number() floated?

On 3 January 2012 22:33, Vincent Lefevre <vincent+gnome <at> vinc17.org> wrote:
> On 2012-01-03 23:00:16 +0100, Vincent Lefevre wrote:
>> On 2012-01-03 20:53:40 +0000, Laurence Rowe wrote:
>> > On 16 December 2011 17:06, Konrad Korzeniowski <konrad <at> pandur.net> wrote:
> [...]
>> > >     <xsl:value-of select="number('8.95')"/>
> [...]
>>
>> Except that this seems to be a bug here:
>
> After looking at the spec, I confirm this is a bug. The XPath spec
> says for number(): "a string that consists of optional whitespace
> followed by an optional minus sign followed by a Number followed
> by whitespace is converted to the IEEE 754 number that is nearest
> (according to the IEEE 754 round-to-nearest rule) to the mathematical
> value represented by the string"
>
> The nearest value X is the following one (represented exactly in
> radix 16, thanks to %a):
>
>> $ /usr/bin/printf "%a\n" 8.95
>> 0x8.f33333333333333p+0
>
> But actually (see below) the internal representation doesn't matter
> here.
>
> Concerning xsl:value-of, the XSLT spec says that for a number, the
> XPath string() fucntion is used, and the XPath spec says for the
> above value: "otherwise, the number is represented in decimal form
> as a Number including [...]; beyond the one required digit after
> the decimal point there must be as many, but only as many, more
> digits as are needed to uniquely distinguish the number from all
> other IEEE 754 numeric values." (FYI, that's the IEEE 754 rule for
> conversions.)
>
> As a consequence, the output value should be "8.95" (like the input)
> because 8.95 rounds to X and has less than 17 digits.

You're right, xpath.c just prints DBL_DIG digits (a constant from
float.h). However, doing this properly is difficult, see:
http://bugs.python.org/issue1580.

Laurence
Vincent Lefevre | 4 Jan 03:01

Re: number() floated?

On 2012-01-04 00:33:44 +0000, Laurence Rowe wrote:
> On 3 January 2012 22:33, Vincent Lefevre <vincent+gnome <at> vinc17.org> wrote:
> > As a consequence, the output value should be "8.95" (like the input)
> > because 8.95 rounds to X and has less than 17 digits.
> 
> You're right, xpath.c just prints DBL_DIG digits (a constant from
> float.h).

At least, this guarantees that when the value is read back in decimal,
this will give the same floating-point number.

BTW, I've just noticed that my examples with printf were incorrect:
I didn't pay attention to the fact that /usr/bin/printf uses the
long double type, and not the double type (this doesn't seem to be
documented).

> However, doing this properly is difficult, see:
> http://bugs.python.org/issue1580.

The reference I have is

@InProceedings{BurgerDybvig1996,
  author = {R.~G. Burger and R.~Kent Dybvig},
  title = {Printing Floating-Point Numbers Quickly and Accurately},
  booktitle =    {Proceedings of the {SIGPLAN'96} Conference on  Programming Languages Design and Implementation},
  year =         1996,
  pages =      {108--116},
  month =        jun,
}

but I see it is mentioned there. Then I agree that it may be
difficult, but not specifically for the XPath behavior. AFAIK,
printing with DBL_DIG digits seems easier just because it is
already implemented in the C library. :)

FYI, the wanted behavior is implemented in GNU MPFR, but that
would be overkill to use MPFR just for that (arbitrary precision
would be a nice extension, though).

--

-- 
Vincent Lefèvre <vincent <at> vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)
Phil Shafer | 4 Jan 06:38
Favicon

Re: number() floated?

Konrad Korzeniowski writes:
>running xsltproc with this xsl against any xml gives:
>8.949999999999999

You may be hitting this rounding error:

https://bugzilla.gnome.org/show_bug.cgi?id=629325

Thanks,
 Phil

Gmane