Thread: Re: [BUGS] BUG #4660: float functions return -0
I reported the following bug to -bugs, and I'd like to discuss whether we need to fix the issue or how to fix it. "ITAGAKI Takahiro" <itagaki.takahiro@oss.ntt.co.jp> wrote: > Bug reference: 4660 > PostgreSQL version: 8.3.3 > Operating system: Fedora 8 > Description: float functions return -0 > Details: > Float8 versions of trunc(), ceil() and round() could return -0 on some > version of glibc. > > postgres=# SELECT pg_catalog.trunc((-0.1)::float8); > -0 > postgres=# SELECT pg_catalog.ceil((-0.1)::float8); > -0 > postgres=# SELECT pg_catalog.round((-0.1)::float8); > -0 We already have some codes to avoid -0 float8um (unary minus), but there are no protection in trunc(), ceil() and round() at least. It is platform-dependent behavior (msvcrt doesn't return -0), and there is a difference between float8 and numeric (numeric doesn't support -0). 1. Remove 'avoid -0' from float8um because -0 is a possible value for floating point numbers. 2. Add 'avoid -0' codesto those functions. (Are there any places where we also add it?) 3. Move 'avoid -0' codes to float8out() and float8send(). '-0' could be stored in database, but users receives only '+0'. Fixes might be needed by float4 versions. I'll write a patch when we come to a decision. Regards, --- ITAGAKI Takahiro NTT Open Source Software Center
ITAGAKI Takahiro <itagaki.takahiro@oss.ntt.co.jp> writes: > We already have some codes to avoid -0 float8um (unary minus), > but there are no protection in trunc(), ceil() and round() at least. I looked into the CVS history to find out when the anti-minus-zero code got put into float8um. It seems to have been done by Tom Lockhart here: http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/backend/utils/adt/float.c.diff?r1=1.13;r2=1.14 The CVS commit message saysCheck for zero in unary minus floating point code (IEEE allows anexplicit negative zero whichlooks ugly in a query result!). along with some other unrelated changes. I can find no evidence in the mailing list archives that there was any discussion about the point, so I think Tom did that on his own authority. I'm of the opinion that minus zero was put into the IEEE floating point standard by people who know a great deal more about the topic than anyone on this list does, and that we do not have the expertise to be second-guessing how it should work. Not long ago we took out code that was interfering with spec-compliant treatment of IEEE infinity; I think we should take out this code too. Yes, it will be platform dependent, because various platforms get the IEEE spec wrong to some degree, but so what? This is hardly the only platform dependence of that kind. regards, tom lane
Tom Lane wrote: > ITAGAKI Takahiro <itagaki.takahiro@oss.ntt.co.jp> writes: > > We already have some codes to avoid -0 float8um (unary minus), > > but there are no protection in trunc(), ceil() and round() at least. > > I looked into the CVS history to find out when the anti-minus-zero code > got put into float8um. It seems to have been done by Tom Lockhart here: > > http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/backend/utils/adt/float.c.diff?r1=1.13;r2=1.14 > > The CVS commit message says > Check for zero in unary minus floating point code (IEEE allows an > explicit negative zero which looks ugly in a query result!). > along with some other unrelated changes. I can find no evidence in the > mailing list archives that there was any discussion about the point, > so I think Tom did that on his own authority. > > I'm of the opinion that minus zero was put into the IEEE floating point > standard by people who know a great deal more about the topic than > anyone on this list does, and that we do not have the expertise to be > second-guessing how it should work. Not long ago we took out code that > was interfering with spec-compliant treatment of IEEE infinity; I think > we should take out this code too. > > Yes, it will be platform dependent, because various platforms get the > IEEE spec wrong to some degree, but so what? This is hardly the only > platform dependence of that kind. Agreed. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + If your life is a hard drive, Christ can be your backup. +
Tom Lane <tgl@sss.pgh.pa.us> writes: > The CVS commit message says > Check for zero in unary minus floating point code (IEEE allows an > explicit negative zero which looks ugly in a query result!). > I'm of the opinion that minus zero was put into the IEEE floating point > standard by people who know a great deal more about the topic than > anyone on this list does, and that we do not have the expertise to be > second-guessing how it should work. Not long ago we took out code that > was interfering with spec-compliant treatment of IEEE infinity; I think > we should take out this code too. If the original complaint was that it looked ugly in query results then the right way to fix it would surely in float4out and float8out. Interfering with IEEE floating points may be a bad idea but surely it's up to us how we want to represent those values in text. But without a convenient and widely used binary format that kind of restricts our options. If we squash -0 on float[48]out then dumps will lose information. So I guess there's nothing we can do about it now. I wonder if we're going to find users complaining about things like "displaying -0 matching results" though... -- Gregory Stark EnterpriseDB http://www.enterprisedb.com Ask me about EnterpriseDB's Slony Replication support!
Gregory Stark <stark@enterprisedb.com> writes: > Tom Lane <tgl@sss.pgh.pa.us> writes: >> I'm of the opinion that minus zero was put into the IEEE floating point >> standard by people who know a great deal more about the topic than >> anyone on this list does, and that we do not have the expertise to be >> second-guessing how it should work. Not long ago we took out code that >> was interfering with spec-compliant treatment of IEEE infinity; I think >> we should take out this code too. > If the original complaint was that it looked ugly in query results then the > right way to fix it would surely in float4out and float8out. Interfering with > IEEE floating points may be a bad idea but surely it's up to us how we want to > represent those values in text. > But without a convenient and widely used binary format that kind of restricts > our options. If we squash -0 on float[48]out then dumps will lose information. The point I'm trying to make is that we should deliver IEEE-compliant results if we are on a platform that complies with the spec. Right down to the minus sign. If that surprises people who are unfamiliar with the spec, well, there are a lot of things about floating point arithmetic that surprise people who aren't familiar with it. regards, tom lane
On Wed, Feb 18, 2009 at 2:57 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > The point I'm trying to make is that we should deliver IEEE-compliant > results if we are on a platform that complies with the spec. Right down > to the minus sign. If that surprises people who are unfamiliar with the > spec, well, there are a lot of things about floating point arithmetic > that surprise people who aren't familiar with it. Agreed. There are plenty of things about floats that are downright wonky, and when people start seeing minus zero in their float computations it might prompt them into doing some reading, and figuring out that what they really wanted was numeric. (not saying that floats are without application, but I've often encountered them in places they ought not to be) Cheers, BJ
Brendan Jurd <direvus@gmail.com> writes: > On Wed, Feb 18, 2009 at 2:57 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> The point I'm trying to make is that we should deliver IEEE-compliant >> results if we are on a platform that complies with the spec. Right down >> to the minus sign. If that surprises people who are unfamiliar with the >> spec, well, there are a lot of things about floating point arithmetic >> that surprise people who aren't familiar with it. > Agreed. There are plenty of things about floats that are downright > wonky, and when people start seeing minus zero in their float > computations it might prompt them into doing some reading, and > figuring out that what they really wanted was numeric. I pulled the special code out of float8um/float4um and got the following two changes in the regression tests: *** src/test/regress/expected/numerology.out Mon Aug 4 22:43:18 2008 --- src/test/regress/results/numerology.out Tue Feb 17 20:05:01 2009 *************** *** 92,98 **** ORDER BY two, max_float, min_float; two | max_float | min_float -----+----------------------+----------------------- ! 1 | 1.2345678901234e+200 | 0 2 | 0 | -1.2345678901234e+200 (2 rows) --- 92,98 ---- ORDER BY two, max_float, min_float; two | max_float | min_float -----+----------------------+----------------------- ! 1 | 1.2345678901234e+200 | -0 2 | 0 | -1.2345678901234e+200 (2 rows) *************** *** 104,110 **** ORDER BY two, max_float, min_float; two | max_float | min_float -----+----------------------+----------------------- ! 1 | 1.2345678901234e+200 | 0 2 | 0 | -1.2345678901234e+200 (2 rows) --- 104,110 ---- ORDER BY two, max_float, min_float; two | max_float | min_float -----+----------------------+----------------------- ! 1 | 1.2345678901234e+200 | -0 2 | 0 | -1.2345678901234e+200 (2 rows) ====================================================================== This is on a minus-zero-clean platform of course (same results on Fedora 9 and current Mac OS X). My HP box still produces the old results, so we will need two variants of this expected-result file. Other platforms might show yet other diffs of course, but we'll have to wait for buildfarm results to know more. Last call for objections ... regards, tom lane