[GENARAL] round() bug?

Started by Willy-Bas Loosalmost 12 years ago7 messagesgeneral
Jump to latest
#1Willy-Bas Loos
willybas@gmail.com

Hi,
I ran into some strange behavior.
Seems like a bug to me?

wbloos=# select round(0.5::numeric), round(0.5::double precision);
round | round
-------+-------
1 | 0
(1 row)

wbloos=# select version();

version
--------------------------------------------------------------------------------------------------------------
PostgreSQL 9.1.13 on x86_64-unknown-linux-gnu, compiled by gcc
(Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1, 64-bit
(1 row)

Cheers,
--
Willy-Bas Loos

#2David G. Johnston
david.g.johnston@gmail.com
In reply to: Willy-Bas Loos (#1)
Re: [GENARAL] round() bug

Willy-Bas Loos-3 wrote

Hi,
I ran into some strange behavior.
Seems like a bug to me?

wbloos=# select round(0.5::numeric), round(0.5::double precision);
round | round
-------+-------
1 | 0
(1 row)

Not a bug; and likely to simple to have escaped notice this long so the
first reaction should be "what am I missing here?"

[google: round .5 postgresql]

http://grokbase.com/t/postgresql/pgsql-hackers/03ap11tckn/round-function-wrong/oldest

Round( numeric ) - 0.5 rounds away from zero
Round( float ) - platform dependent, IEEE 0.5 rounds toward even

You can argue the decision but at this point it's not likely to change.

David J.

--
View this message in context: http://postgresql.1045698.n5.nabble.com/GENARAL-round-bug-tp5800087p5800118.html
Sent from the PostgreSQL - general mailing list archive at Nabble.com.

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

In reply to: David G. Johnston (#2)
Re: [GENARAL] round() bug

On 15/04/2014 17:20, David G Johnston wrote:

Willy-Bas Loos-3 wrote

Hi, I ran into some strange behavior. Seems like a bug to me?

wbloos=# select round(0.5::numeric), round(0.5::double precision);
round | round -------+------- 1 | 0 (1 row)

Not a bug; and likely to simple to have escaped notice this long so
the first reaction should be "what am I missing here?"

[google: round .5 postgresql]

http://grokbase.com/t/postgresql/pgsql-hackers/03ap11tckn/round-function-wrong/oldest

Round( numeric ) - 0.5 rounds away from zero Round( float ) -
platform dependent, IEEE 0.5 rounds toward even

You can argue the decision but at this point it's not likely to
change.

Interestingly, I get different results (on both 9.1.4 and 9.3.0) on Windows:

postgres=# select round(0.5::numeric), round(0.5::double precision);
round | round
-------+-------
1 | 1
(1 row)

postgres=# select version();
version
-------------------------------------------------------------
PostgreSQL 9.1.4, compiled by Visual C++ build 1500, 64-bit
(1 row)

.... Same on 9.3.0.

Ray.

--
Raymond O'Donnell :: Galway :: Ireland
rod@iol.ie

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#4David G. Johnston
david.g.johnston@gmail.com
In reply to: Raymond O'Donnell (#3)
Re: [GENARAL] round() bug

Raymond O'Donnell wrote

On 15/04/2014 17:20, David G Johnston wrote:

Willy-Bas Loos-3 wrote

Hi, I ran into some strange behavior. Seems like a bug to me?

wbloos=# select round(0.5::numeric), round(0.5::double precision);
round | round -------+------- 1 | 0 (1 row)

Not a bug; and likely to simple to have escaped notice this long so
the first reaction should be "what am I missing here?"

[google: round .5 postgresql]

http://grokbase.com/t/postgresql/pgsql-hackers/03ap11tckn/round-function-wrong/oldest

Round( numeric ) - 0.5 rounds away from zero Round( float ) -
platform dependent, IEEE 0.5 rounds toward even

You can argue the decision but at this point it's not likely to
change.

Interestingly, I get different results (on both 9.1.4 and 9.3.0) on
Windows:

postgres=# select round(0.5::numeric), round(0.5::double precision);
round | round
-------+-------
1 | 1
(1 row)

postgres=# select version();
version
-------------------------------------------------------------
PostgreSQL 9.1.4, compiled by Visual C++ build 1500, 64-bit
(1 row)

.... Same on 9.3.0.

I'm not particularly surprised that Windows is not being IEEE compliant, and
instead chooses the more common round-away-from-zero behavior, here though I
am unsure where the dependent implementation would end up existing.

David J.

--
View this message in context: http://postgresql.1045698.n5.nabble.com/GENARAL-round-bug-tp5800087p5800121.html
Sent from the PostgreSQL - general mailing list archive at Nabble.com.

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

In reply to: David G. Johnston (#4)
Re: [GENARAL] round() bug

On 15/04/2014 17:34, David G Johnston wrote:

Raymond O'Donnell wrote

On 15/04/2014 17:20, David G Johnston wrote:

Willy-Bas Loos-3 wrote

Hi, I ran into some strange behavior. Seems like a bug to me?

wbloos=# select round(0.5::numeric), round(0.5::double precision);
round | round -------+------- 1 | 0 (1 row)

Not a bug; and likely to simple to have escaped notice this long so
the first reaction should be "what am I missing here?"

[google: round .5 postgresql]

http://grokbase.com/t/postgresql/pgsql-hackers/03ap11tckn/round-function-wrong/oldest

Round( numeric ) - 0.5 rounds away from zero Round( float ) -
platform dependent, IEEE 0.5 rounds toward even

You can argue the decision but at this point it's not likely to
change.

Interestingly, I get different results (on both 9.1.4 and 9.3.0) on
Windows:

postgres=# select round(0.5::numeric), round(0.5::double precision);
round | round
-------+-------
1 | 1
(1 row)

postgres=# select version();
version
-------------------------------------------------------------
PostgreSQL 9.1.4, compiled by Visual C++ build 1500, 64-bit
(1 row)

.... Same on 9.3.0.

I'm not particularly surprised that Windows is not being IEEE compliant, and
instead chooses the more common round-away-from-zero behavior, here though I
am unsure where the dependent implementation would end up existing.

Oh, so does the rounding code use OS facilities, then, rather than being
implemented in Postgres? - Didn't know that, though I was aware PG does
that in other areas (collation, for example).

Ray.

--
Raymond O'Donnell :: Galway :: Ireland
rod@iol.ie

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#6Adrian Klaver
adrian.klaver@aklaver.com
In reply to: Raymond O'Donnell (#5)
Re: [GENARAL] round() bug

On 04/15/2014 10:21 AM, Raymond O'Donnell wrote:

On 15/04/2014 17:34, David G Johnston wrote:

Oh, so does the rounding code use OS facilities, then, rather than being
implemented in Postgres? - Didn't know that, though I was aware PG does
that in other areas (collation, for example).

See the thread below for that discussion:

/messages/by-id/34608c0c0906150358xbc53de2pe0c7053779e7b0ca@mail.gmail.com

Ray.

--
Adrian Klaver
adrian.klaver@aklaver.com

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#7Laurenz Albe
laurenz.albe@cybertec.at
In reply to: Raymond O'Donnell (#5)
Re: [GENARAL] round() bug

Raymond O'Donnell wrote:

Interestingly, I get different results (on both 9.1.4 and 9.3.0) on
Windows:

I'm not particularly surprised that Windows is not being IEEE compliant, and
instead chooses the more common round-away-from-zero behavior, here though I
am unsure where the dependent implementation would end up existing.

Oh, so does the rounding code use OS facilities, then, rather than being
implemented in Postgres? - Didn't know that, though I was aware PG does
that in other areas (collation, for example).

Yes.

But this here:
http://msdn.microsoft.com/en-us/library/0b34tf65.aspx
claims that Windows C++ is IEEE compliant, so it should behave like Linux.

On systems where the function exists, PostgreSQL uses the rint() function.
On other systems (like Windows), it defines rint() as

double
rint(double x)
{
return (x >= 0.0) ? floor(x + 0.5) : ceil(x - 0.5);
}

It is interesting that the above function, when applied to 0.5 on my
Linux x86_64 system, yields "1".

So while rint() follows the IEEE standard's default (if a value is exactly
between two integers, round to the even one), PostgreSQL's replacement
function doesn't.

So maybe there is a bug after all, and the replacement function
should be changed.

Yours,
Laurenz Albe

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general