rint() replacement

Started by Bruce Momjianalmost 23 years ago11 messageshackers
Jump to latest
#1Bruce Momjian
bruce@momjian.us

In working on an rint() for Win32, I found two --- one in
port/qnx4/rint.c and another in dt_common.c. The first is very simple,
using fmod, while the second is very complicated.

I would like to pick the best one and move it to /port. Any idea why
there are two different methods for rint() --- is the second one
complicated because it doesn't use fmod?

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#1)
Re: rint() replacement

Bruce Momjian <pgman@candle.pha.pa.us> writes:

In working on an rint() for Win32, I found two --- one in
port/qnx4/rint.c and another in dt_common.c. The first is very simple,
using fmod, while the second is very complicated.

Not to mention desperately hardware-specific. The dt_common.c routine
is a rip from utils/adt/float.c, which has absolutely no business being
where it is --- it might have some claim to live in a Sun-specific
backend/port/ file, but it is not general by any stretch of the
imagination. (And I think we gave up supporting SunOS awhile back
anyway.)

I can't believe that Windoze does not offer rint(); it's in the C99
standard. Have you checked?

regards, tom lane

#3Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#2)
Re: rint() replacement

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

In working on an rint() for Win32, I found two --- one in
port/qnx4/rint.c and another in dt_common.c. The first is very simple,
using fmod, while the second is very complicated.

Not to mention desperately hardware-specific. The dt_common.c routine
is a rip from utils/adt/float.c, which has absolutely no business being
where it is --- it might have some claim to live in a Sun-specific
backend/port/ file, but it is not general by any stretch of the
imagination. (And I think we gave up supporting SunOS awhile back
anyway.)

Removed from float.c and ecpg.

I can't believe that Windoze does not offer rint(); it's in the C99
standard. Have you checked?

Both PeerDirect and SRA used rint.c, so they certainly needed it.

Also, there is a special HPUX 9 configure test to look for rint() a
different location. I am not sure if the new replacement rint() test
has invalidated that code. Do we still support HPUX 9? (I added a
comment to the configure script to mention it might now be broken.)

I see a cbrt() in float.c. Do we actually have platforms that don't
have cbrt()/cube root? I am inclined to remove it more move it to
/port.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Attachments:

/bjm/difftext/plainDownload+20-120
/bjm/diff2text/plainDownload+0-111
#4Andrew Dunstan
andrew@dunslane.net
In reply to: Bruce Momjian (#3)
Re: rint() replacement

speaking of rint(), I just got this on Linux on a clean get from CVS:

gcc -O2 -Wall -Wmissing-prototypes -Wmissing-declarations -fpic -I../../../.
./src/interfaces/ecpg/include -I../../../../src/include/utils -I../../../../
src/include -c -o dt_common.o dt_common.c
dt_common.c: In function `dt2time':
dt_common.c:1271: warning: implicit declaration of function `rint'

which I guess is kinda undesirable...

andrew

#5Dann Corbit
DCorbit@connx.com
In reply to: Andrew Dunstan (#4)
Re: rint() replacement

This is the rint() definition:
http://www.gnu.org/manual/glibc-2.2.5/html_node/Rounding-Functions.html

There was a bug in glibc rint, but I think it has been fixed.

Probably, most of the time nearbyint() is what is really wanted instead
of rint(). The rint() function can throw an exception even when it does
what is wanted.

If the current rounding mode is round toward -INF, rint(x) is identical
to floor(x).

If the current rounding mode is round toward +INF, rint(x) is identical
to ceil(x).

If the current rounding mode is round to nearest, rint(x) is identical
to nearest(x).

If the current rounding mode is round toward zero, rint(x) is identical
to trunc(x).

Most of the time, this is what rint() is doing if we are round to
nearest:
return floor(x+0.5);

Show quoted text

-----Original Message-----
From: Andrew Dunstan [mailto:andrew@dunslane.net]
Sent: Friday, May 09, 2003 11:54 AM
To: PostgreSQL-development
Subject: Re: [HACKERS] rint() replacement

speaking of rint(), I just got this on Linux on a clean get from CVS:

gcc -O2 -Wall -Wmissing-prototypes -Wmissing-declarations
-fpic -I../../../. ./src/interfaces/ecpg/include
-I../../../../src/include/utils -I../../../../
src/include -c -o dt_common.o dt_common.c
dt_common.c: In function `dt2time':
dt_common.c:1271: warning: implicit declaration of function `rint'

which I guess is kinda undesirable...

andrew

---------------------------(end of
broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#3)
Re: rint() replacement

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Also, there is a special HPUX 9 configure test to look for rint() a
different location. I am not sure if the new replacement rint() test
has invalidated that code. Do we still support HPUX 9? (I added a
comment to the configure script to mention it might now be broken.)

HPUX 9 is obsolete (heck, HP is about to obsolete HPUX 10...). If
there's any beta testers out there still running it, they can find out
for us. But I'd say that if you are providing a portable rint() in
/port, we could get rid of the HPUXMATHLIB crock and let configure
fall back to using the /port version.

I see a cbrt() in float.c. Do we actually have platforms that don't
have cbrt()/cube root? I am inclined to remove it more move it to
/port.

Hardly worth the trouble. The substitute implementation is small
and portable...

regards, tom lane

#7Bruce Momjian
bruce@momjian.us
In reply to: Andrew Dunstan (#4)
Re: rint() replacement

Andrew Dunstan wrote:

speaking of rint(), I just got this on Linux on a clean get from CVS:

gcc -O2 -Wall -Wmissing-prototypes -Wmissing-declarations -fpic -I../../../.
./src/interfaces/ecpg/include -I../../../../src/include/utils -I../../../../
src/include -c -o dt_common.o dt_common.c
dt_common.c: In function `dt2time':
dt_common.c:1271: warning: implicit declaration of function `rint'

which I guess is kinda undesirable...

OK, fixed. I added '#include <math.h>'.

However, this illustrates another problem. dt_common and other ecpg
files test for c.h defines but there is no #include of c.h or
postgres.h, so they never get triggered. That needs to be fixed.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#8Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#6)
Re: rint() replacement

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Also, there is a special HPUX 9 configure test to look for rint() a
different location. I am not sure if the new replacement rint() test
has invalidated that code. Do we still support HPUX 9? (I added a
comment to the configure script to mention it might now be broken.)

HPUX 9 is obsolete (heck, HP is about to obsolete HPUX 10...). If
there's any beta testers out there still running it, they can find out
for us. But I'd say that if you are providing a portable rint() in
/port, we could get rid of the HPUXMATHLIB crock and let configure
fall back to using the /port version.

OK, removed.

I see a cbrt() in float.c. Do we actually have platforms that don't
have cbrt()/cube root? I am inclined to remove it more move it to
/port.

Hardly worth the trouble. The substitute implementation is small
and portable...

Sorry, my paragraph was bad. Should I remove cbrt or move it to /port?

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#8)
Re: rint() replacement

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Tom Lane wrote:

Hardly worth the trouble. The substitute implementation is small
and portable...

Sorry, my paragraph was bad. Should I remove cbrt or move it to /port?

I'd leave it sit as-is. I don't think it's worth fooling with.

regards, tom lane

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dann Corbit (#5)
Re: rint() replacement

"Dann Corbit" <DCorbit@connx.com> writes:

Probably, most of the time nearbyint() is what is really wanted instead
of rint(). The rint() function can throw an exception even when it does
what is wanted.

The real issue here is "what is portable behavior"?

PG never changes the rounding mode, so we should always get the default,
which is round-to-nearest-even unless there have been big changes made
while I wasn't looking.

Expressing that as nearest() instead of rint() would be fine with me if
all platforms recognized nearest(). But rint() is more likely to be
portable in the real world, AFAIK.

I do have a bit of a problem with the CVS-tip version of this code: it
falls back to implementing rint() in terms of modf(). I would like to
know the justification for assuming that modf() is more portable than
rint().

Most of the time, this is what rint() is doing if we are round to
nearest:
return floor(x+0.5);

I'd be happier with that as a fallback implementation ...

regards, tom lane

In reply to: Tom Lane (#10)
Re: rint() replacement

On Sat, May 10, 2003 at 12:29:27AM -0400, Tom Lane wrote:

"Dann Corbit" <DCorbit@connx.com> writes:

I do have a bit of a problem with the CVS-tip version of this code: it
falls back to implementing rint() in terms of modf(). I would like to
know the justification for assuming that modf() is more portable than
rint().

modf() is part of C89 and POSIX, just as floor(). I have modf()
here, I do not have rint().

rint() was a BSD thing and is now part of C99.

Kurt