pgsql: Improve type numeric's calculations for ln(), log(), exp(), pow(

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-committers(at)postgresql(dot)org
Subject: pgsql: Improve type numeric's calculations for ln(), log(), exp(), pow(
Date: 2015-11-14 19:56:02
Message-ID: E1Zxgva-0000tn-Ox@gemulon.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-committers

Improve type numeric's calculations for ln(), log(), exp(), pow().

Set the "rscales" for intermediate-result calculations to ensure that
suitable numbers of significant digits are maintained throughout. The
previous coding hadn't thought this through in any detail, and as a result
could deliver results with many inaccurate digits, or in the worst cases
even fail with divide-by-zero errors as a result of losing all nonzero
digits of intermediate results.

In exp_var(), get rid entirely of the logic that separated the calculation
into integer and fractional parts: that was neither accurate nor
particularly fast. The existing range-reduction method of dividing by 2^n
can be applied across the full input range instead of only 0..1, as long as
we are careful to set an appropriate rscale for each step.

Also fix the logic in mul_var() for shortening the calculation when the
caller asks for fewer output digits than an exact calculation would
require. This bug doesn't affect simple multiplications since that code
path asks for an exact result, but it does contribute to accuracy issues
in the transcendental math functions.

In passing, improve performance of mul_var() a bit by forcing the shorter
input to be on the left, thus reducing the number of iterations of the
outer loop and probably also reducing the number of carry-propagation
steps needed.

This is arguably a bug fix, but in view of the lack of field complaints,
it does not seem worth the risk of back-patching.

Dean Rasheed

Branch
------
master

Details
-------
http://git.postgresql.org/pg/commitdiff/7d9a4737c268f61fb8800957631f12d3f13be218

Modified Files
--------------
src/backend/utils/adt/numeric.c | 604 ++++++++-----
src/test/regress/expected/numeric.out | 302 +++++++
src/test/regress/expected/numeric_big.out | 1376 +++++++++++++++++++++++++++++
src/test/regress/sql/numeric.sql | 103 +++
src/test/regress/sql/numeric_big.sql | 695 +++++++++++++++
5 files changed, 2853 insertions(+), 227 deletions(-)

Browse pgsql-committers by date

  From Date Subject
Next Message Tom Lane 2015-11-15 19:41:45 pgsql: Fix ruleutils.c's dumping of whole-row Vars in ROW() and VALUES(
Previous Message Bruce Momjian 2015-11-14 19:00:59 pgsql: Fix spelling error in postgresql.conf