]> granicus.if.org Git - postgresql/commitdiff
Add documentation and regression tests concerning rounding of numerics.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 3 Jul 2015 21:04:39 +0000 (17:04 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 3 Jul 2015 21:04:39 +0000 (17:04 -0400)
Michael Paquier, reviewed by Fabien Coelho

doc/src/sgml/datatype.sgml
src/test/regress/expected/int2.out
src/test/regress/expected/int4.out
src/test/regress/expected/int8-exp-three-digits.out
src/test/regress/expected/int8.out
src/test/regress/expected/numeric.out
src/test/regress/sql/int2.sql
src/test/regress/sql/int4.sql
src/test/regress/sql/int8.sql
src/test/regress/sql/numeric.sql

index 9d5ce953f1728343f664699c5fab65ef31aa1ed6..8e13555a3aa5518d11eac71c1536bb6acf4032be 100644 (file)
@@ -612,6 +612,31 @@ NUMERIC
      equivalent.  Both types are part of the <acronym>SQL</acronym>
      standard.
     </para>
+
+    <para>
+     When rounding values, the <type>numeric</type> type rounds ties away
+     from zero, while (on most machines) the <type>real</type>
+     and <type>double precision</type> types round ties to the nearest even
+     number.  For example:
+
+<programlisting>
+SELECT x,
+  round(x::numeric) AS num_round,
+  round(x::double precision) AS dbl_round
+FROM generate_series(-3.5, 3.5, 1) as x;
+  x   | num_round | dbl_round
+------+-----------+-----------
+ -3.5 |        -4 |        -4
+ -2.5 |        -3 |        -2
+ -1.5 |        -2 |        -2
+ -0.5 |        -1 |        -0
+  0.5 |         1 |         0
+  1.5 |         2 |         2
+  2.5 |         3 |         2
+  3.5 |         4 |         4
+(8 rows)
+</programlisting>
+    </para>
    </sect2>
 
 
index 311fe730a5b4a01fbca9c5e3b08c248bbefb32ff..3ea4ed93a0aad5819b0f660fd619b6fa2ea4183f 100644 (file)
@@ -286,3 +286,23 @@ FROM (VALUES (-2.5::float8),
   2.5 |          2
 (7 rows)
 
+-- check rounding when casting from numeric
+SELECT x, x::int2 AS int2_value
+FROM (VALUES (-2.5::numeric),
+             (-1.5::numeric),
+             (-0.5::numeric),
+             (0.0::numeric),
+             (0.5::numeric),
+             (1.5::numeric),
+             (2.5::numeric)) t(x);
+  x   | int2_value 
+------+------------
+ -2.5 |         -3
+ -1.5 |         -2
+ -0.5 |         -1
+  0.0 |          0
+  0.5 |          1
+  1.5 |          2
+  2.5 |          3
+(7 rows)
+
index 83fe022d7fe83cceccbe87b4e168ffb15e837f90..372fd4d94c8c5f3d1f50359f20d55212145143ce 100644 (file)
@@ -383,3 +383,23 @@ FROM (VALUES (-2.5::float8),
   2.5 |          2
 (7 rows)
 
+-- check rounding when casting from numeric
+SELECT x, x::int4 AS int4_value
+FROM (VALUES (-2.5::numeric),
+             (-1.5::numeric),
+             (-0.5::numeric),
+             (0.0::numeric),
+             (0.5::numeric),
+             (1.5::numeric),
+             (2.5::numeric)) t(x);
+  x   | int4_value 
+------+------------
+ -2.5 |         -3
+ -1.5 |         -2
+ -0.5 |         -1
+  0.0 |          0
+  0.5 |          1
+  1.5 |          2
+  2.5 |          3
+(7 rows)
+
index a4f0cc23ec5fb73c4149026a426b0b8a2988d4e0..7ad4dcea0fd63797adebeb11291d44b1dd61909d 100644 (file)
@@ -866,3 +866,23 @@ FROM (VALUES (-2.5::float8),
   2.5 |          2
 (7 rows)
 
+-- check rounding when casting from numeric
+SELECT x, x::int8 AS int8_value
+FROM (VALUES (-2.5::numeric),
+             (-1.5::numeric),
+             (-0.5::numeric),
+             (0.0::numeric),
+             (0.5::numeric),
+             (1.5::numeric),
+             (2.5::numeric)) t(x);
+  x   | int8_value 
+------+------------
+ -2.5 |         -3
+ -1.5 |         -2
+ -0.5 |         -1
+  0.0 |          0
+  0.5 |          1
+  1.5 |          2
+  2.5 |          3
+(7 rows)
+
index da8be51886c23c50b183cae24a574e368a07dae1..ed0bd34221eb56302f209a83ca302f3874b7e458 100644 (file)
@@ -866,3 +866,23 @@ FROM (VALUES (-2.5::float8),
   2.5 |          2
 (7 rows)
 
+-- check rounding when casting from numeric
+SELECT x, x::int8 AS int8_value
+FROM (VALUES (-2.5::numeric),
+             (-1.5::numeric),
+             (-0.5::numeric),
+             (0.0::numeric),
+             (0.5::numeric),
+             (1.5::numeric),
+             (2.5::numeric)) t(x);
+  x   | int8_value 
+------+------------
+ -2.5 |         -3
+ -1.5 |         -2
+ -0.5 |         -1
+  0.0 |          0
+  0.5 |          1
+  1.5 |          2
+  2.5 |          3
+(7 rows)
+
index 9d6814564df961c4dd4e6d449db3d32a9efe0894..e6ee548e7c0b4d4c1489f599d1261185f5fc2306 100644 (file)
@@ -730,6 +730,30 @@ SELECT a, ceil(a), ceiling(a), floor(a), round(a) FROM ceil_floor_round;
 (7 rows)
 
 DROP TABLE ceil_floor_round;
+-- Check rounding, it should round ties away from zero.
+SELECT i as pow,
+       round((-2.5 * 10 ^ i)::numeric, -i),
+       round((-1.5 * 10 ^ i)::numeric, -i),
+       round((-0.5 * 10 ^ i)::numeric, -i),
+       round((0.5 * 10 ^ i)::numeric, -i),
+       round((1.5 * 10 ^ i)::numeric, -i),
+       round((2.5 * 10 ^ i)::numeric, -i)
+FROM generate_series(-5,5) AS t(i);
+ pow |  round   |  round   |  round   |  round  |  round  |  round  
+-----+----------+----------+----------+---------+---------+---------
+  -5 | -0.00003 | -0.00002 | -0.00001 | 0.00001 | 0.00002 | 0.00003
+  -4 |  -0.0003 |  -0.0002 |  -0.0001 |  0.0001 |  0.0002 |  0.0003
+  -3 |   -0.003 |   -0.002 |   -0.001 |   0.001 |   0.002 |   0.003
+  -2 |    -0.03 |    -0.02 |    -0.01 |    0.01 |    0.02 |    0.03
+  -1 |     -0.3 |     -0.2 |     -0.1 |     0.1 |     0.2 |     0.3
+   0 |       -3 |       -2 |       -1 |       1 |       2 |       3
+   1 |      -30 |      -20 |      -10 |      10 |      20 |      30
+   2 |     -300 |     -200 |     -100 |     100 |     200 |     300
+   3 |    -3000 |    -2000 |    -1000 |    1000 |    2000 |    3000
+   4 |   -30000 |   -20000 |   -10000 |   10000 |   20000 |   30000
+   5 |  -300000 |  -200000 |  -100000 |  100000 |  200000 |  300000
+(11 rows)
+
 -- Testing for width_bucket(). For convenience, we test both the
 -- numeric and float8 versions of the function in this file.
 -- errors
index 5e9774e922722cfc31235c1e0ad524ba4cede37c..7dbafb6dacc815e9f96bd5b0a7fddf9cbe03cfa9 100644 (file)
@@ -102,3 +102,13 @@ FROM (VALUES (-2.5::float8),
              (0.5::float8),
              (1.5::float8),
              (2.5::float8)) t(x);
+
+-- check rounding when casting from numeric
+SELECT x, x::int2 AS int2_value
+FROM (VALUES (-2.5::numeric),
+             (-1.5::numeric),
+             (-0.5::numeric),
+             (0.0::numeric),
+             (0.5::numeric),
+             (1.5::numeric),
+             (2.5::numeric)) t(x);
index d1881405252716f596e6f718cbb161a31db050b9..f014cb2d3250a0b2c347f215545b474f59ca8b41 100644 (file)
@@ -145,3 +145,13 @@ FROM (VALUES (-2.5::float8),
              (0.5::float8),
              (1.5::float8),
              (2.5::float8)) t(x);
+
+-- check rounding when casting from numeric
+SELECT x, x::int4 AS int4_value
+FROM (VALUES (-2.5::numeric),
+             (-1.5::numeric),
+             (-0.5::numeric),
+             (0.0::numeric),
+             (0.5::numeric),
+             (1.5::numeric),
+             (2.5::numeric)) t(x);
index 69723759fe3993f8562526fc90b551000d4d6420..e890452236f95d41715c5e5b17b8b49c1fe32de2 100644 (file)
@@ -215,3 +215,13 @@ FROM (VALUES (-2.5::float8),
              (0.5::float8),
              (1.5::float8),
              (2.5::float8)) t(x);
+
+-- check rounding when casting from numeric
+SELECT x, x::int8 AS int8_value
+FROM (VALUES (-2.5::numeric),
+             (-1.5::numeric),
+             (-0.5::numeric),
+             (0.0::numeric),
+             (0.5::numeric),
+             (1.5::numeric),
+             (2.5::numeric)) t(x);
index 1633e4c375244f35b517d7a699b2a7c8ea7d3225..982287c33ad602001a97da5e67b464c9a59c8e64 100644 (file)
@@ -667,6 +667,16 @@ INSERT INTO ceil_floor_round VALUES ('-0.000001');
 SELECT a, ceil(a), ceiling(a), floor(a), round(a) FROM ceil_floor_round;
 DROP TABLE ceil_floor_round;
 
+-- Check rounding, it should round ties away from zero.
+SELECT i as pow,
+       round((-2.5 * 10 ^ i)::numeric, -i),
+       round((-1.5 * 10 ^ i)::numeric, -i),
+       round((-0.5 * 10 ^ i)::numeric, -i),
+       round((0.5 * 10 ^ i)::numeric, -i),
+       round((1.5 * 10 ^ i)::numeric, -i),
+       round((2.5 * 10 ^ i)::numeric, -i)
+FROM generate_series(-5,5) AS t(i);
+
 -- Testing for width_bucket(). For convenience, we test both the
 -- numeric and float8 versions of the function in this file.