pgsql: Fix precision and rounding issues in money multiplication and di

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-committers(at)postgresql(dot)org
Subject: pgsql: Fix precision and rounding issues in money multiplication and di
Date: 2017-05-21 17:05:38
Message-ID: E1dCUIU-0004MG-DA@gemulon.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-committers

Fix precision and rounding issues in money multiplication and division.

The cash_div_intX functions applied rint() to the result of the division.
That's not merely useless (because the result is already an integer) but
it causes precision loss for values larger than 2^52 or so, because of
the forced conversion to float8.

On the other hand, the cash_mul_fltX functions neglected to apply rint() to
their multiplication results, thus possibly causing off-by-one outputs.

Per C standard, arithmetic between any integral value and a float value is
performed in float format. Thus, cash_mul_flt4 and cash_div_flt4 produced
answers good to only about six digits, even when the float value is exact.
We can improve matters noticeably by widening the float inputs to double.
(It's tempting to consider using "long double" arithmetic if available,
but that's probably too much of a stretch for a back-patched fix.)

Also, document that cash_div_intX operators truncate rather than round.

Per bug #14663 from Richard Pistole. Back-patch to all supported branches.

Discussion: https://postgr.es/m/22403.1495223615@sss.pgh.pa.us

Branch
------
REL9_4_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/83f4e8f71cdf6838197fd3ac2e7c50c105c87d35

Modified Files
--------------
doc/src/sgml/datatype.sgml | 5 +++++
src/backend/utils/adt/cash.c | 16 ++++++++--------
src/test/regress/expected/money.out | 38 +++++++++++++++++++++++++++++++++++++
src/test/regress/sql/money.sql | 10 ++++++++++
4 files changed, 61 insertions(+), 8 deletions(-)

Browse pgsql-committers by date

  From Date Subject
Next Message Piotr Stefaniak 2017-05-21 19:52:46 Re: pgindent (was Re: [COMMITTERS] pgsql: Preventive maintenance in advance of pgindent run.)
Previous Message Tom Lane 2017-05-21 15:46:11 pgsql: Fix contrib/sepgsql regression tests for partition NOT NULL chan