Commit b813d143 authored by Tom Lane's avatar Tom Lane

Alter scale selection for NUMERIC division and transcendental functions

so that precision of result is always at least as good as you'd get from
float8 arithmetic (ie, always at least 16 digits of accuracy).  Per
pg_hackers discussion a few days ago.
parent c74c7e60
This diff is collapsed.
......@@ -5,7 +5,7 @@
*
* 1998 Jan Wieck
*
* $Header: /cvsroot/pgsql/src/include/utils/numeric.h,v 1.15 2001/11/05 17:46:36 momjian Exp $
* $Id: numeric.h,v 1.16 2002/10/02 19:21:26 tgl Exp $
*
* ----------
*/
......@@ -13,29 +13,36 @@
#ifndef _PG_NUMERIC_H_
#define _PG_NUMERIC_H_
/* ----------
* The hardcoded limits and defaults of the numeric data type
* ----------
/*
* Hardcoded precision limit - arbitrary, but must be small enough that
* dscale values will fit in 14 bits.
*/
#define NUMERIC_MAX_PRECISION 1000
#define NUMERIC_DEFAULT_PRECISION 30
#define NUMERIC_DEFAULT_SCALE 6
/* ----------
/*
* Internal limits on the scales chosen for calculation results
* ----------
*/
#define NUMERIC_MAX_DISPLAY_SCALE NUMERIC_MAX_PRECISION
#define NUMERIC_MIN_DISPLAY_SCALE (NUMERIC_DEFAULT_SCALE + 4)
#define NUMERIC_MIN_DISPLAY_SCALE 0
#define NUMERIC_MAX_RESULT_SCALE (NUMERIC_MAX_PRECISION * 2)
#define NUMERIC_MIN_RESULT_SCALE (NUMERIC_DEFAULT_PRECISION + 4)
/*
* For inherently inexact calculations such as division and square root,
* we try to get at least this many significant digits; the idea is to
* deliver a result no worse than float8 would.
*/
#define NUMERIC_MIN_SIG_DIGITS 16
/* ----------
/*
* Standard number of extra digits carried internally while doing
* inexact calculations.
*/
#define NUMERIC_EXTRA_DIGITS 4
/*
* Sign values and macros to deal with packing/unpacking n_sign_dscale
* ----------
*/
#define NUMERIC_SIGN_MASK 0xC000
#define NUMERIC_POS 0x0000
......@@ -48,7 +55,7 @@
NUMERIC_SIGN(n) != NUMERIC_NEG)
/* ----------
/*
* The Numeric data type stored in the database
*
* NOTE: by convention, values in the packed form have been stripped of
......@@ -56,7 +63,6 @@
* in the last byte, if the number of digits is odd). In particular,
* if the value is zero, there will be no digits at all! The weight is
* arbitrary in that case, but we normally set it to zero.
* ----------
*/
typedef struct NumericData
{
......
......@@ -2,15 +2,15 @@
-- AGGREGATES
--
SELECT avg(four) AS avg_1 FROM onek;
avg_1
--------------
1.5000000000
avg_1
---------------------
1.50000000000000000
(1 row)
SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100;
avg_32
---------------
32.6666666667
avg_32
--------------------
32.666666666666667
(1 row)
-- In 7.1, avg(float4) is computed using float8 arithmetic.
......@@ -118,9 +118,9 @@ select ten, count(four), sum(DISTINCT four) from onek group by ten;
(10 rows)
SELECT newavg(four) AS avg_1 FROM onek;
avg_1
--------------
1.5000000000
avg_1
---------------------
1.50000000000000000
(1 row)
SELECT newsum(four) AS sum_1500 FROM onek;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment