dbTalk Databases Forums  

[BUGS] round(50.5) = 50

mailing.database.pgsql-bugs mailing.database.pgsql-bugs


Discuss [BUGS] round(50.5) = 50 in the mailing.database.pgsql-bugs forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Philipp Matthias Hahn
 
Posts: n/a

Default [BUGS] round(50.5) = 50 - 02-28-2004 , 02:19 PM






Hello!

# SELECT round(5.5::float4),round(50.5::float4);
round | round
-------+-------
6 | 50
(1 row)

I think this is a bug, since I would expect 6 and 51. Doing the same
without the float4-cast, it works correct. This bug bites me while
passing parameters to a plpgsql function.

This happens both with Debian 7.3.4-9 and 7.4.1-3

Is this a real bug or am I missing something? A bug fix or work-around
would be nice.

BYtE
Philipp
--
Dipl.-Inform. Philipp.Hahn (AT) informatik (DOT) uni-oldenburg.de
Abteilung Systemsoftware und verteilte Systeme, Fk. II
Carl von Ossietzky Universitaet Oldenburg, 26111 Oldenburg, Germany
http://www.svs.informatik.uni-oldenb...ontact/pmhahn/
Telefon: +49 441 798-2866 Telefax: +49 441 798-2756


---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match

Reply With Quote
  #2  
Old   
Peter Eisentraut
 
Posts: n/a

Default Re: [BUGS] round(50.5) = 50 - 02-28-2004 , 09:04 PM






Philipp Matthias Hahn wrote:
Quote:
# SELECT round(5.5::float4),round(50.5::float4);
round | round
-------+-------
6 | 50
(1 row)

I think this is a bug, since I would expect 6 and 51.
The default rounding mode for floating point (determined by your C
library, mostly) it to round toward the closest even number. If you
are at all concerned abou that, you probably shouldn't be using
floating point, but rather numeric.


---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faqs/FAQ.html


Reply With Quote
  #3  
Old   
Chris Browne
 
Posts: n/a

Default Re: [BUGS] round(50.5) = 50 - 03-05-2004 , 08:39 PM



Philipp.Hahn (AT) informatik (DOT) uni-oldenburg.de (Philipp Matthias Hahn) writes:
Quote:
# SELECT round(5.5::float4),round(50.5::float4);
round | round
-------+-------
6 | 50
(1 row)

I think this is a bug, since I would expect 6 and 51. Doing the same
without the float4-cast, it works correct. This bug bites me while
passing parameters to a plpgsql function.

This happens both with Debian 7.3.4-9 and 7.4.1-3

Is this a real bug or am I missing something? A bug fix or work-around
would be nice.
Why would this be a bug?

A common policy for rounding is "round to even." That has the merit
of not being biased whether you're working with positive or negative
values.

It looks as though your LIBC is using "round-to-even."
--
(reverse (concatenate 'string "gro.mca" "@" "enworbbc"))
http://cbbrowne.com/info/sap.html
"For those of you who are into writing programs that are as obscure
and complicated as possible, there are opportunities for... real fun
here" -- Arthur Norman

---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org


Reply With Quote
  #4  
Old   
Philipp Matthias Hahn
 
Posts: n/a

Default Re: [BUGS] round(50.5) = 50 - 03-05-2004 , 08:39 PM



Peter Eisentraut wrote:
Quote:
Philipp Matthias Hahn wrote:

# SELECT round(5.5::float4),round(50.5::float4);
round | round
-------+-------
6 | 50
(1 row)

I think this is a bug, since I would expect 6 and 51.

The default rounding mode for floating point (determined by your C
library, mostly) it to round toward the closest even number.
No, see program and its results below.
If you don't cast the numbers above to "float4", you get the correct
results "6" and "51". Something is broken with casting "float8" to
"float4", since there is no numerical problem representing .5 either in
float4 or float8.

$ dpkg -l libc6 gcc | tail -2
ii libc6 2.3.2.ds1-11 GNU C Library: Shared libraries
ii gcc 3.3.2-2 The GNU C compiler
$ cat x.c
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define rf(f) printf("roundf(%f)=%f lroundf(%f)=%ld\n", f, roundf(f), f,
lroundf(f));
#define rd(d) printf("round(%lf)=%lf lround(%lf)=%ld\n", d, round(d), d,
lround(d));

int main(void) {
rf(5.5f);
rf(50.5f);
rd(5.5);
rd(50.5);
}
$ gcc -lm -std=c99 -Wall x.c
$ ./a.out
roundf(5.500000)=6.000000 lroundf(5.500000)=6
roundf(50.500000)=51.000000 lroundf(50.500000)=51
round(5.500000)=6.000000 lround(5.500000)=6
round(50.500000)=51.000000 lround(50.500000)=51

Quote:
If you are at all concerned abou that, you probably shouldn't be
using floating point, but rather numeric.
Yes, I did switch back to numeric, which solved this problem. I
originally switched from numeric(4,1) to float, because I had trouble
with Java and Cocoon.

BYtE
Philipp
--
Dipl.-Inform. Philipp.Hahn (AT) informatik (DOT) uni-oldenburg.de
Abteilung Systemsoftware und verteilte Systeme, Fk. II
Carl von Ossietzky Universitaet Oldenburg, 26111 Oldenburg, Germany
http://www.svs.informatik.uni-oldenb...ontact/pmhahn/
Telefon: +49 441 798-2866 Telefax: +49 441 798-2756


---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings


Reply With Quote
  #5  
Old   
Stephan Szabo
 
Posts: n/a

Default Re: [BUGS] round(50.5) = 50 - 03-05-2004 , 10:30 PM




On Mon, 1 Mar 2004, Philipp Matthias Hahn wrote:

Quote:
Peter Eisentraut wrote:
Philipp Matthias Hahn wrote:

# SELECT round(5.5::float4),round(50.5::float4);
round | round
-------+-------
6 | 50
(1 row)

I think this is a bug, since I would expect 6 and 51.

The default rounding mode for floating point (determined by your C
library, mostly) it to round toward the closest even number.

No, see program and its results below.
Postgresql uses rint/rintf to do the rounding not round/roundf so you're
comparing apples and oranges (specifically round/roundf explicitly do not
honor the rounding direction)

----
From my system man pages:

double rint(double x);
float rintf(float x);
long double rintl(long double x);

DESCRIPTION

The nearbyint functions round their argument to an integer value in
floating point format, using the current rounding direction and without
raising the inexact exception.

The rint functions do the same, but will raise the inexact exception when
the result differs in value from the argument.


double round(double x);
float roundf(float x);
long double roundl(long double x);

DESCRIPTION

These functions round x to the nearest integer, but round halfway cases
away from zero (regardless of the current rounding direction), instead of
to the nearest even integer like rint().


---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match


Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.