diff --git a/configure b/configure
index 0bc4a69b04..7291311ae3 100755
--- a/configure
+++ b/configure
@@ -732,6 +732,7 @@ CPP
BITCODE_CXXFLAGS
BITCODE_CFLAGS
CFLAGS_VECTOR
+PERMIT_DECLARATION_AFTER_STATEMENT
LLVM_BINPATH
LLVM_CXXFLAGS
LLVM_CFLAGS
@@ -5261,6 +5262,7 @@ if test "$GCC" = yes -a "$ICC" = no; then
CFLAGS="-Wall -Wmissing-prototypes -Wpointer-arith"
CXXFLAGS="-Wall -Wpointer-arith"
# These work in some but not all gcc versions
+ save_CFLAGS=$CFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wdeclaration-after-statement, for CFLAGS" >&5
$as_echo_n "checking whether ${CC} supports -Wdeclaration-after-statement, for CFLAGS... " >&6; }
@@ -5301,7 +5303,13 @@ if test x"$pgac_cv_prog_CC_cflags__Wdeclaration_after_statement" = x"yes"; then
fi
- # -Wdeclaration-after-statement isn't applicable for C++
+ # -Wdeclaration-after-statement isn't applicable for C++. Specific C files
+ # disable it, so AC_SUBST the negative form.
+ PERMIT_DECLARATION_AFTER_STATEMENT=
+ if test x"save_$CFLAGS" != x"$CFLAGS"; then
+ PERMIT_DECLARATION_AFTER_STATEMENT=-Wno-declaration-after-statement
+ fi
+
# Really don't want VLAs to be used in our dialect of C
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Werror=vla, for CFLAGS" >&5
diff --git a/configure.in b/configure.in
index 5960a3c2b2..8a55e8e8a5 100644
--- a/configure.in
+++ b/configure.in
@@ -476,8 +476,15 @@ if test "$GCC" = yes -a "$ICC" = no; then
CFLAGS="-Wall -Wmissing-prototypes -Wpointer-arith"
CXXFLAGS="-Wall -Wpointer-arith"
# These work in some but not all gcc versions
+ save_CFLAGS=$CFLAGS
PGAC_PROG_CC_CFLAGS_OPT([-Wdeclaration-after-statement])
- # -Wdeclaration-after-statement isn't applicable for C++
+ # -Wdeclaration-after-statement isn't applicable for C++. Specific C files
+ # disable it, so AC_SUBST the negative form.
+ PERMIT_DECLARATION_AFTER_STATEMENT=
+ if test x"save_$CFLAGS" != x"$CFLAGS"; then
+ PERMIT_DECLARATION_AFTER_STATEMENT=-Wno-declaration-after-statement
+ fi
+ AC_SUBST(PERMIT_DECLARATION_AFTER_STATEMENT)
# Really don't want VLAs to be used in our dialect of C
PGAC_PROG_CC_CFLAGS_OPT([-Werror=vla])
# -Wvla is not applicable for C++
diff --git a/contrib/btree_gist/expected/float4.out b/contrib/btree_gist/expected/float4.out
index abbd9eef4e..dfe732049e 100644
--- a/contrib/btree_gist/expected/float4.out
+++ b/contrib/btree_gist/expected/float4.out
@@ -33,11 +33,11 @@ SELECT count(*) FROM float4tmp WHERE a > -179.0;
(1 row)
SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3;
- a | ?column?
-----------+----------
- -179 | 0
- -189.024 | 10.0239
- -158.177 | 20.8226
+ a | ?column?
+------------+-----------
+ -179 | 0
+ -189.02386 | 10.023865
+ -158.17741 | 20.822586
(3 rows)
CREATE INDEX float4idx ON float4tmp USING gist ( a );
@@ -82,10 +82,10 @@ SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3;
(3 rows)
SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3;
- a | ?column?
-----------+----------
- -179 | 0
- -189.024 | 10.0239
- -158.177 | 20.8226
+ a | ?column?
+------------+-----------
+ -179 | 0
+ -189.02386 | 10.023865
+ -158.17741 | 20.822586
(3 rows)
diff --git a/contrib/btree_gist/expected/float8.out b/contrib/btree_gist/expected/float8.out
index 5111dbdfae..ebd0ef3d68 100644
--- a/contrib/btree_gist/expected/float8.out
+++ b/contrib/btree_gist/expected/float8.out
@@ -33,11 +33,11 @@ SELECT count(*) FROM float8tmp WHERE a > -1890.0;
(1 row)
SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3;
- a | ?column?
---------------+------------
- -1890 | 0
- -2003.634512 | 113.634512
- -1769.73634 | 120.26366
+ a | ?column?
+--------------+--------------------
+ -1890 | 0
+ -2003.634512 | 113.63451200000009
+ -1769.73634 | 120.26366000000007
(3 rows)
CREATE INDEX float8idx ON float8tmp USING gist ( a );
@@ -82,10 +82,10 @@ SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3;
(3 rows)
SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3;
- a | ?column?
---------------+------------
- -1890 | 0
- -2003.634512 | 113.634512
- -1769.73634 | 120.26366
+ a | ?column?
+--------------+--------------------
+ -1890 | 0
+ -2003.634512 | 113.63451200000009
+ -1769.73634 | 120.26366000000007
(3 rows)
diff --git a/contrib/cube/expected/cube.out b/contrib/cube/expected/cube.out
index 1a65e6944a..5b89cb1a26 100644
--- a/contrib/cube/expected/cube.out
+++ b/contrib/cube/expected/cube.out
@@ -81,21 +81,21 @@ SELECT 'NaN'::cube AS cube;
(1 row)
SELECT '.1234567890123456'::cube AS cube;
- cube
----------------------
- (0.123456789012346)
+ cube
+----------------------
+ (0.1234567890123456)
(1 row)
SELECT '+.1234567890123456'::cube AS cube;
- cube
----------------------
- (0.123456789012346)
+ cube
+----------------------
+ (0.1234567890123456)
(1 row)
SELECT '-.1234567890123456'::cube AS cube;
- cube
-----------------------
- (-0.123456789012346)
+ cube
+-----------------------
+ (-0.1234567890123456)
(1 row)
-- simple lists (points)
@@ -943,9 +943,9 @@ SELECT cube_distance('(42,42,42,42)'::cube,'(137,137,137,137)'::cube);
(1 row)
SELECT cube_distance('(42,42,42)'::cube,'(137,137)'::cube);
- cube_distance
-------------------
- 140.762210837994
+ cube_distance
+--------------------
+ 140.76221083799445
(1 row)
-- Test of cube function (text to cube)
@@ -1356,8 +1356,9 @@ SELECT cube_size('(42,137)'::cube);
0
(1 row)
--- Test of distances
+-- Test of distances (euclidean distance may not be bit-exact)
--
+SET extra_float_digits = 0;
SELECT cube_distance('(1,1)'::cube, '(4,5)'::cube);
cube_distance
---------------
@@ -1370,6 +1371,7 @@ SELECT '(1,1)'::cube <-> '(4,5)'::cube as d_e;
5
(1 row)
+RESET extra_float_digits;
SELECT distance_chebyshev('(1,1)'::cube, '(4,5)'::cube);
distance_chebyshev
--------------------
@@ -1557,6 +1559,7 @@ RESET enable_bitmapscan;
INSERT INTO test_cube VALUES ('(1,1)'), ('(100000)'), ('(0, 100000)'); -- Some corner cases
SET enable_seqscan = false;
-- Test different metrics
+SET extra_float_digits = 0;
SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
c | dist
-------------------------+------------------
@@ -1567,6 +1570,7 @@ SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c
(1444, 403),(1346, 344) | 846
(5 rows)
+RESET extra_float_digits;
SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
c | dist
-------------------------+------
@@ -1751,6 +1755,7 @@ SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upp
-- Same queries with sequential scan (should give the same results as above)
RESET enable_seqscan;
SET enable_indexscan = OFF;
+SET extra_float_digits = 0;
SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
c | dist
-------------------------+------------------
@@ -1761,6 +1766,7 @@ SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c
(1444, 403),(1346, 344) | 846
(5 rows)
+RESET extra_float_digits;
SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
c | dist
-------------------------+------
diff --git a/contrib/cube/expected/cube_sci.out b/contrib/cube/expected/cube_sci.out
index 1e8269cdf0..488499ac8e 100644
--- a/contrib/cube/expected/cube_sci.out
+++ b/contrib/cube/expected/cube_sci.out
@@ -87,20 +87,20 @@ SELECT '-1e-300'::cube AS cube;
(1 row)
SELECT '1234567890123456'::cube AS cube;
- cube
-------------------------
- (1.23456789012346e+15)
+ cube
+-------------------------
+ (1.234567890123456e+15)
(1 row)
SELECT '+1234567890123456'::cube AS cube;
- cube
-------------------------
- (1.23456789012346e+15)
+ cube
+-------------------------
+ (1.234567890123456e+15)
(1 row)
SELECT '-1234567890123456'::cube AS cube;
- cube
--------------------------
- (-1.23456789012346e+15)
+ cube
+--------------------------
+ (-1.234567890123456e+15)
(1 row)
diff --git a/contrib/cube/sql/cube.sql b/contrib/cube/sql/cube.sql
index 59e7e4159d..7f8b2e3979 100644
--- a/contrib/cube/sql/cube.sql
+++ b/contrib/cube/sql/cube.sql
@@ -336,10 +336,12 @@ SELECT cube_inter('(1,2,3)'::cube, '(5,6,3)'::cube); -- point args
SELECT cube_size('(4,8),(15,16)'::cube);
SELECT cube_size('(42,137)'::cube);
--- Test of distances
+-- Test of distances (euclidean distance may not be bit-exact)
--
+SET extra_float_digits = 0;
SELECT cube_distance('(1,1)'::cube, '(4,5)'::cube);
SELECT '(1,1)'::cube <-> '(4,5)'::cube as d_e;
+RESET extra_float_digits;
SELECT distance_chebyshev('(1,1)'::cube, '(4,5)'::cube);
SELECT '(1,1)'::cube <=> '(4,5)'::cube as d_c;
SELECT distance_taxicab('(1,1)'::cube, '(4,5)'::cube);
@@ -395,7 +397,9 @@ INSERT INTO test_cube VALUES ('(1,1)'), ('(100000)'), ('(0, 100000)'); -- Some c
SET enable_seqscan = false;
-- Test different metrics
+SET extra_float_digits = 0;
SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
+RESET extra_float_digits;
SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
@@ -412,7 +416,9 @@ SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upp
-- Same queries with sequential scan (should give the same results as above)
RESET enable_seqscan;
SET enable_indexscan = OFF;
+SET extra_float_digits = 0;
SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
+RESET extra_float_digits;
SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
SELECT c~>1, c FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by left bound
diff --git a/contrib/pg_trgm/expected/pg_strict_word_trgm.out b/contrib/pg_trgm/expected/pg_strict_word_trgm.out
index 43898a3b98..1e1ee16ce9 100644
--- a/contrib/pg_trgm/expected/pg_strict_word_trgm.out
+++ b/contrib/pg_trgm/expected/pg_strict_word_trgm.out
@@ -1,6 +1,8 @@
DROP INDEX trgm_idx2;
\copy test_trgm3 from 'data/trgm2.data'
ERROR: relation "test_trgm3" does not exist
+-- reduce noise
+set extra_float_digits = 0;
select t,strict_word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <<% t order by sml desc, t;
t | sml
-------------------------------------+----------
diff --git a/contrib/pg_trgm/expected/pg_trgm.out b/contrib/pg_trgm/expected/pg_trgm.out
index 6efc54356a..b3e709f496 100644
--- a/contrib/pg_trgm/expected/pg_trgm.out
+++ b/contrib/pg_trgm/expected/pg_trgm.out
@@ -10,6 +10,8 @@ WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid);
--backslash is used in tests below, installcheck will fail if
--standard_conforming_string is off
set standard_conforming_strings=on;
+-- reduce noise
+set extra_float_digits = 0;
select show_trgm('');
show_trgm
-----------
diff --git a/contrib/pg_trgm/expected/pg_word_trgm.out b/contrib/pg_trgm/expected/pg_word_trgm.out
index bed61c4922..936d489390 100644
--- a/contrib/pg_trgm/expected/pg_word_trgm.out
+++ b/contrib/pg_trgm/expected/pg_word_trgm.out
@@ -1,5 +1,7 @@
CREATE TABLE test_trgm2(t text COLLATE "C");
\copy test_trgm2 from 'data/trgm2.data'
+-- reduce noise
+set extra_float_digits = 0;
select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
t | sml
-------------------------------------+----------
diff --git a/contrib/pg_trgm/sql/pg_strict_word_trgm.sql b/contrib/pg_trgm/sql/pg_strict_word_trgm.sql
index 98e0d379f8..ce0791f29b 100644
--- a/contrib/pg_trgm/sql/pg_strict_word_trgm.sql
+++ b/contrib/pg_trgm/sql/pg_strict_word_trgm.sql
@@ -2,6 +2,9 @@ DROP INDEX trgm_idx2;
\copy test_trgm3 from 'data/trgm2.data'
+-- reduce noise
+set extra_float_digits = 0;
+
select t,strict_word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <<% t order by sml desc, t;
select t,strict_word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <<% t order by sml desc, t;
select t,strict_word_similarity('Baykal',t) as sml from test_trgm2 where t %>> 'Baykal' order by sml desc, t;
diff --git a/contrib/pg_trgm/sql/pg_trgm.sql b/contrib/pg_trgm/sql/pg_trgm.sql
index 96ae542320..08459e64c3 100644
--- a/contrib/pg_trgm/sql/pg_trgm.sql
+++ b/contrib/pg_trgm/sql/pg_trgm.sql
@@ -9,6 +9,9 @@ WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid);
--standard_conforming_string is off
set standard_conforming_strings=on;
+-- reduce noise
+set extra_float_digits = 0;
+
select show_trgm('');
select show_trgm('(*&^$@%@');
select show_trgm('a b c');
diff --git a/contrib/pg_trgm/sql/pg_word_trgm.sql b/contrib/pg_trgm/sql/pg_word_trgm.sql
index 4b1db9706a..d9fa1c55e5 100644
--- a/contrib/pg_trgm/sql/pg_word_trgm.sql
+++ b/contrib/pg_trgm/sql/pg_word_trgm.sql
@@ -2,6 +2,9 @@ CREATE TABLE test_trgm2(t text COLLATE "C");
\copy test_trgm2 from 'data/trgm2.data'
+-- reduce noise
+set extra_float_digits = 0;
+
select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
diff --git a/contrib/seg/expected/seg.out b/contrib/seg/expected/seg.out
index a289dbe5f9..80b0bca156 100644
--- a/contrib/seg/expected/seg.out
+++ b/contrib/seg/expected/seg.out
@@ -1127,7 +1127,7 @@ FROM test_seg WHERE s @> '11.2..11.3' OR s IS NULL ORDER BY s;
2.1 | 6.95 | 11.8
2.3 | Infinity | Infinity
2.3 | Infinity | Infinity
- 2.4 | 6.85 | 11.3
+ 2.4 | 6.8500004 | 11.3
2.5 | 7 | 11.5
2.5 | 7.15 | 11.8
2.6 | Infinity | Infinity
@@ -1155,7 +1155,7 @@ FROM test_seg WHERE s @> '11.2..11.3' OR s IS NULL ORDER BY s;
4.5 | 59.75 | 115
4.7 | 8.25 | 11.8
4.8 | 8.15 | 11.5
- 4.8 | 8.2 | 11.6
+ 4.8 | 8.200001 | 11.6
4.8 | 8.65 | 12.5
4.8 | Infinity | Infinity
4.9 | 8.45 | 12
@@ -1244,7 +1244,7 @@ FROM test_seg WHERE s @> '11.2..11.3' OR s IS NULL ORDER BY s;
9 | 10.5 | 12
9 | Infinity | Infinity
9.2 | 10.6 | 12
- 9.4 | 10.8 | 12.2
+ 9.4 | 10.799999 | 12.2
9.5 | 10.75 | 12
9.5 | 10.85 | 12.2
9.5 | Infinity | Infinity
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 07b847a8e9..8bd57f376b 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -7871,16 +7871,37 @@ SET XML OPTION { DOCUMENT | CONTENT };
- This parameter adjusts the number of digits displayed for
+ This parameter adjusts the number of digits used for textual output of
floating-point values, including float4, float8,
- and geometric data types. The parameter value is added to the
- standard number of digits (FLT_DIG or DBL_DIG
- as appropriate). The value can be set as high as 3, to include
- partially-significant digits; this is especially useful for dumping
- float data that needs to be restored exactly. Or it can be set
- negative to suppress unwanted digits.
- See also .
+ and geometric data types.
+
+ If the value is 1 (the default) or above, float values are output in
+ shortest-precise format; see . The
+ actual number of digits generated depends only on the value being
+ output, not on the value of this parameter. At most 17 digits are
+ required for float8 values, and 9 for float4
+ values. This format is both fast and precise, preserving the original
+ binary float value exactly when correctly read. For historical
+ compatibility, values up to 3 are permitted.
+
+
+ If the value is zero or negative, then the output is rounded to a
+ given decimal precision. The precision used is the standard number of
+ digits for the type (FLT_DIG
+ or DBL_DIG as appropriate) reduced according to the
+ value of this parameter. (For example, specifying -1 will cause float4
+ values to be output rounded to 5 significant digits, and float8 values
+ rounded to 14 digits.) This format is slower and does not preserve all
+ the bits of the binary float value, but may be more human-readable.
+
+
+
+ The meaning of this parameter, and its default value, changed
+ in PostgreSQL 12;
+ see for further discussion.
+
+
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 7807210b36..b462c06990 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -671,13 +671,12 @@ FROM generate_series(-3.5, 3.5, 1) as x;
- The data types real and double
- precision are inexact, variable-precision numeric types.
- In practice, these types are usually implementations of
- IEEE Standard 754 for Binary Floating-Point
- Arithmetic (single and double precision, respectively), to the
- extent that the underlying processor, operating system, and
- compiler support it.
+ The data types real and double precision are
+ inexact, variable-precision numeric types. On all currently supported
+ platforms, these types are implementations of IEEE
+ Standard 754 for Binary Floating-Point Arithmetic (single and double
+ precision, respectively), to the extent that the underlying processor,
+ operating system, and compiler support it.
@@ -715,24 +714,57 @@ FROM generate_series(-3.5, 3.5, 1) as x;
- On most platforms, the real type has a range of at least
- 1E-37 to 1E+37 with a precision of at least 6 decimal digits. The
- double precision type typically has a range of around
- 1E-307 to 1E+308 with a precision of at least 15 digits. Values that
- are too large or too small will cause an error. Rounding might
- take place if the precision of an input number is too high.
- Numbers too close to zero that are not representable as distinct
- from zero will cause an underflow error.
+ On all currently supported platforms, the real type has a
+ range of around 1E-37 to 1E+37 with a precision of at least 6 decimal
+ digits. The double precision type has a range of around
+ 1E-307 to 1E+308 with a precision of at least 15 digits. Values that are
+ too large or too small will cause an error. Rounding might take place if
+ the precision of an input number is too high. Numbers too close to zero
+ that are not representable as distinct from zero will cause an underflow
+ error.
+
+
+
+ By default, floating point values are output in text form in their
+ shortest precise decimal representation; the decimal value produced is
+ closer to the true stored binary value than to any other value
+ representable in the same binary precision. (However, the output value is
+ currently never exactly midway between two
+ representable values, in order to avoid a widespread bug where input
+ routines do not properly respect the round-to-even rule.) This value will
+ use at most 17 significant decimal digits for float8
+ values, and at most 9 digits for float4 values.
- The setting controls the
- number of extra significant digits included when a floating point
- value is converted to text for output. With the default value of
- 0, the output is the same on every platform
- supported by PostgreSQL. Increasing it will produce output that
- more accurately represents the stored value, but may be unportable.
+ This shortest-precise output format is much faster to generate than the
+ historical rounded format.
+
+
+
+
+ For compatibility with output generated by older versions
+ of PostgreSQL, and to allow the output
+ precision to be reduced, the
+ parameter can be used to select rounded decimal output instead. Setting a
+ value of 0 restores the previous default of rounding the value to 6
+ (for float4) or 15 (for float8)
+ significant decimal digits. Setting a negative value reduces the number
+ of digits further; for example -2 would round output to 4 or 13 digits
+ respectively.
+
+
+
+ Any value of greater than 0
+ selects the shortest-precise format.
+
+
+
+
+ Applications that wanted precise values have historically had to set
+ to 3 obtain them. For maximum
+ compatibility between versions, they should continue to do so.
@@ -751,9 +783,7 @@ FROM generate_series(-3.5, 3.5, 1) as x;
These represent the IEEE 754 special values
infinity
, negative infinity
, and
- not-a-number
, respectively. (On a machine whose
- floating-point arithmetic does not follow IEEE 754, these values
- will probably not work as expected.) When writing these values
+ not-a-number
, respectively. When writing these values
as constants in an SQL command, you must put quotes around them,
for example UPDATE table SET x = '-Infinity'. On input,
these strings are recognized in a case-insensitive manner.
@@ -786,17 +816,6 @@ FROM generate_series(-3.5, 3.5, 1) as x;
double precision.
-
-
- The assumption that real and
- double precision have exactly 24 and 53 bits in the
- mantissa respectively is correct for IEEE-standard floating point
- implementations. On non-IEEE platforms it might be off a little, but
- for simplicity the same ranges of p are used
- on all platforms.
-
-
-
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index a84b2f96eb..c118f64040 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -261,6 +261,7 @@ CFLAGS = @CFLAGS@
CFLAGS_VECTOR = @CFLAGS_VECTOR@
CFLAGS_SSE42 = @CFLAGS_SSE42@
CFLAGS_ARMV8_CRC32C = @CFLAGS_ARMV8_CRC32C@
+PERMIT_DECLARATION_AFTER_STATEMENT = @PERMIT_DECLARATION_AFTER_STATEMENT@
CXXFLAGS = @CXXFLAGS@
LLVM_CPPFLAGS = @LLVM_CPPFLAGS@
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index eb111ee2db..37c202d21c 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -21,6 +21,7 @@
#include "catalog/pg_type.h"
#include "common/int.h"
+#include "common/shortest_dec.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "utils/array.h"
@@ -30,8 +31,15 @@
#include "utils/timestamp.h"
-/* Configurable GUC parameter */
-int extra_float_digits = 0; /* Added to DBL_DIG or FLT_DIG */
+/*
+ * Configurable GUC parameter
+ *
+ * If >0, use shortest-decimal format for output; this is both the default and
+ * allows for compatibility with clients that explicitly set a value here to
+ * get round-trip-accurate results. If 0 or less, then use the old, slow,
+ * decimal rounding method.
+ */
+int extra_float_digits = 1;
/* Cached constants for degree-based trig functions */
static bool degree_consts_set = false;
@@ -282,6 +290,12 @@ float4out(PG_FUNCTION_ARGS)
char *ascii = (char *) palloc(32);
int ndig = FLT_DIG + extra_float_digits;
+ if (extra_float_digits > 0)
+ {
+ float_to_shortest_decimal_buf(num, ascii);
+ PG_RETURN_CSTRING(ascii);
+ }
+
(void) pg_strfromd(ascii, 32, ndig, num);
PG_RETURN_CSTRING(ascii);
}
@@ -498,6 +512,12 @@ float8out_internal(double num)
char *ascii = (char *) palloc(32);
int ndig = DBL_DIG + extra_float_digits;
+ if (extra_float_digits > 0)
+ {
+ double_to_shortest_decimal_buf(num, ascii);
+ return ascii;
+ }
+
(void) pg_strfromd(ascii, 32, ndig, num);
return ascii;
}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 3a4a113b62..156d147c85 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2667,11 +2667,12 @@ static struct config_int ConfigureNamesInt[] =
{"extra_float_digits", PGC_USERSET, CLIENT_CONN_LOCALE,
gettext_noop("Sets the number of digits displayed for floating-point values."),
gettext_noop("This affects real, double precision, and geometric data types. "
- "The parameter value is added to the standard number of digits "
- "(FLT_DIG or DBL_DIG as appropriate).")
+ "A zero or negative parameter value is added to the standard "
+ "number of digits (FLT_DIG or DBL_DIG as appropriate). "
+ "Any value greater than zero selects precise output mode.")
},
&extra_float_digits,
- 0, -15, 3,
+ 1, -15, 3,
NULL, NULL, NULL
},
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index ad6c436f93..194f312096 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -651,7 +651,8 @@
# India
# You can create your own file in
# share/timezonesets/.
-#extra_float_digits = 0 # min -15, max 3
+#extra_float_digits = 1 # min -15, max 3; any value >0 actually
+ # selects precise output mode
#client_encoding = sql_ascii # actually, defaults to database
# encoding
diff --git a/src/common/Makefile b/src/common/Makefile
index d0c2b970eb..d84c7b6e6a 100644
--- a/src/common/Makefile
+++ b/src/common/Makefile
@@ -44,9 +44,11 @@ override CPPFLAGS += -DVAL_LIBS="\"$(LIBS)\""
override CPPFLAGS := -DFRONTEND -I. -I$(top_srcdir)/src/common $(CPPFLAGS)
LIBS += $(PTHREAD_LIBS)
-OBJS_COMMON = base64.o config_info.o controldata_utils.o exec.o file_perm.o \
- ip.o keywords.o kwlookup.o link-canary.o md5.o pg_lzcompress.o \
- pgfnames.o psprintf.o relpath.o \
+# If you add objects here, see also src/tools/msvc/Mkvcbuild.pm
+
+OBJS_COMMON = base64.o config_info.o controldata_utils.o d2s.o exec.o f2s.o \
+ file_perm.o ip.o keywords.o kwlookup.o link-canary.o md5.o \
+ pg_lzcompress.o pgfnames.o psprintf.o relpath.o \
rmtree.o saslprep.o scram-common.o string.o unicode_norm.o \
username.o wait_error.o
@@ -130,6 +132,13 @@ kwlist_d.h: $(top_srcdir)/src/include/parser/kwlist.h $(GEN_KEYWORDLIST_DEPS)
# that you don't get broken parsing code, even in a non-enable-depend build.
keywords.o keywords_shlib.o keywords_srv.o: kwlist_d.h
+# The code imported from Ryu gets a pass on declaration-after-statement,
+# in order to keep it more closely aligned with its upstream.
+RYU_FILES = d2s.o f2s.o
+RYU_OBJS = $(RYU_FILES) $(RYU_FILES:%.o=%_shlib.o) $(RYU_FILES:%.o=%_srv.o)
+
+$(RYU_OBJS): CFLAGS += $(PERMIT_DECLARATION_AFTER_STATEMENT)
+
# kwlist_d.h is in the distribution tarball, so it is not cleaned here.
clean distclean:
rm -f libpgcommon.a libpgcommon_shlib.a libpgcommon_srv.a
diff --git a/src/common/d2s.c b/src/common/d2s.c
new file mode 100644
index 0000000000..58f60977a5
--- /dev/null
+++ b/src/common/d2s.c
@@ -0,0 +1,1076 @@
+/*---------------------------------------------------------------------------
+ *
+ * Ryu floating-point output for double precision.
+ *
+ * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/d2s.c
+ *
+ * This is a modification of code taken from github.com/ulfjack/ryu under the
+ * terms of the Boost license (not the Apache license). The original copyright
+ * notice follows:
+ *
+ * Copyright 2018 Ulf Adams
+ *
+ * The contents of this file may be used under the terms of the Apache
+ * License, Version 2.0.
+ *
+ * (See accompanying file LICENSE-Apache or copy at
+ * http://www.apache.org/licenses/LICENSE-2.0)
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * Boost Software License, Version 1.0.
+ *
+ * (See accompanying file LICENSE-Boost or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Unless required by applicable law or agreed to in writing, this software is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+/*
+ * Runtime compiler options:
+ *
+ * -DRYU_ONLY_64_BIT_OPS Avoid using uint128 or 64-bit intrinsics. Slower,
+ * depending on your compiler.
+ */
+
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
+
+#include "common/shortest_dec.h"
+
+/*
+ * For consistency, we use 128-bit types if and only if the rest of PG also
+ * does, even though we could use them here without worrying about the
+ * alignment concerns that apply elsewhere.
+ */
+#if !defined(HAVE_INT128) && defined(_MSC_VER) \
+ && !defined(RYU_ONLY_64_BIT_OPS) && defined(_M_X64)
+#define HAS_64_BIT_INTRINSICS
+#endif
+
+#include "ryu_common.h"
+#include "digit_table.h"
+#include "d2s_full_table.h"
+#include "d2s_intrinsics.h"
+
+#define DOUBLE_MANTISSA_BITS 52
+#define DOUBLE_EXPONENT_BITS 11
+#define DOUBLE_BIAS 1023
+
+#define DOUBLE_POW5_INV_BITCOUNT 122
+#define DOUBLE_POW5_BITCOUNT 121
+
+
+static inline uint32
+pow5Factor(uint64 value)
+{
+ uint32 count = 0;
+
+ for (;;)
+ {
+ Assert(value != 0);
+ const uint64 q = div5(value);
+ const uint32 r = (uint32) (value - 5 * q);
+
+ if (r != 0)
+ break;
+
+ value = q;
+ ++count;
+ }
+ return count;
+}
+
+/* Returns true if value is divisible by 5^p. */
+static inline bool
+multipleOfPowerOf5(const uint64 value, const uint32 p)
+{
+ /*
+ * I tried a case distinction on p, but there was no performance
+ * difference.
+ */
+ return pow5Factor(value) >= p;
+}
+
+/* Returns true if value is divisible by 2^p. */
+static inline bool
+multipleOfPowerOf2(const uint64 value, const uint32 p)
+{
+ /* return __builtin_ctzll(value) >= p; */
+ return (value & ((UINT64CONST(1) << p) - 1)) == 0;
+}
+
+/*
+ * We need a 64x128-bit multiplication and a subsequent 128-bit shift.
+ *
+ * Multiplication:
+ *
+ * The 64-bit factor is variable and passed in, the 128-bit factor comes
+ * from a lookup table. We know that the 64-bit factor only has 55
+ * significant bits (i.e., the 9 topmost bits are zeros). The 128-bit
+ * factor only has 124 significant bits (i.e., the 4 topmost bits are
+ * zeros).
+ *
+ * Shift:
+ *
+ * In principle, the multiplication result requires 55 + 124 = 179 bits to
+ * represent. However, we then shift this value to the right by j, which is
+ * at least j >= 115, so the result is guaranteed to fit into 179 - 115 =
+ * 64 bits. This means that we only need the topmost 64 significant bits of
+ * the 64x128-bit multiplication.
+ *
+ * There are several ways to do this:
+ *
+ * 1. Best case: the compiler exposes a 128-bit type.
+ * We perform two 64x64-bit multiplications, add the higher 64 bits of the
+ * lower result to the higher result, and shift by j - 64 bits.
+ *
+ * We explicitly cast from 64-bit to 128-bit, so the compiler can tell
+ * that these are only 64-bit inputs, and can map these to the best
+ * possible sequence of assembly instructions. x86-64 machines happen to
+ * have matching assembly instructions for 64x64-bit multiplications and
+ * 128-bit shifts.
+ *
+ * 2. Second best case: the compiler exposes intrinsics for the x86-64
+ * assembly instructions mentioned in 1.
+ *
+ * 3. We only have 64x64 bit instructions that return the lower 64 bits of
+ * the result, i.e., we have to use plain C.
+ *
+ * Our inputs are less than the full width, so we have three options:
+ * a. Ignore this fact and just implement the intrinsics manually.
+ * b. Split both into 31-bit pieces, which guarantees no internal
+ * overflow, but requires extra work upfront (unless we change the
+ * lookup table).
+ * c. Split only the first factor into 31-bit pieces, which also
+ * guarantees no internal overflow, but requires extra work since the
+ * intermediate results are not perfectly aligned.
+ */
+#if defined(HAVE_INT128)
+
+/* Best case: use 128-bit type. */
+static inline uint64
+mulShift(const uint64 m, const uint64 *const mul, const int32 j)
+{
+ const uint128 b0 = ((uint128) m) * mul[0];
+ const uint128 b2 = ((uint128) m) * mul[1];
+
+ return (uint64) (((b0 >> 64) + b2) >> (j - 64));
+}
+
+static inline uint64
+mulShiftAll(const uint64 m, const uint64 *const mul, const int32 j,
+ uint64 *const vp, uint64 *const vm, const uint32 mmShift)
+{
+ *vp = mulShift(4 * m + 2, mul, j);
+ *vm = mulShift(4 * m - 1 - mmShift, mul, j);
+ return mulShift(4 * m, mul, j);
+}
+
+#elif defined(HAS_64_BIT_INTRINSICS)
+
+static inline uint64
+mulShift(const uint64 m, const uint64 *const mul, const int32 j)
+{
+ /* m is maximum 55 bits */
+ uint64 high1;
+
+ /* 128 */
+ const uint64 low1 = umul128(m, mul[1], &high1);
+
+ /* 64 */
+ uint64 high0;
+ uint64 sum;
+
+ /* 64 */
+ umul128(m, mul[0], &high0);
+ /* 0 */
+ sum = high0 + low1;
+
+ if (sum < high0)
+ {
+ ++high1;
+ /* overflow into high1 */
+ }
+ return shiftright128(sum, high1, j - 64);
+}
+
+static inline uint64
+mulShiftAll(const uint64 m, const uint64 *const mul, const int32 j,
+ uint64 *const vp, uint64 *const vm, const uint32 mmShift)
+{
+ *vp = mulShift(4 * m + 2, mul, j);
+ *vm = mulShift(4 * m - 1 - mmShift, mul, j);
+ return mulShift(4 * m, mul, j);
+}
+
+#else /* // !defined(HAVE_INT128) &&
+ * !defined(HAS_64_BIT_INTRINSICS) */
+
+static inline uint64
+mulShiftAll(uint64 m, const uint64 *const mul, const int32 j,
+ uint64 *const vp, uint64 *const vm, const uint32 mmShift)
+{
+ m <<= 1; /* m is maximum 55 bits */
+
+ uint64 tmp;
+ const uint64 lo = umul128(m, mul[0], &tmp);
+ uint64 hi;
+ const uint64 mid = tmp + umul128(m, mul[1], &hi);
+
+ hi += mid < tmp; /* overflow into hi */
+
+ const uint64 lo2 = lo + mul[0];
+ const uint64 mid2 = mid + mul[1] + (lo2 < lo);
+ const uint64 hi2 = hi + (mid2 < mid);
+
+ *vp = shiftright128(mid2, hi2, j - 64 - 1);
+
+ if (mmShift == 1)
+ {
+ const uint64 lo3 = lo - mul[0];
+ const uint64 mid3 = mid - mul[1] - (lo3 > lo);
+ const uint64 hi3 = hi - (mid3 > mid);
+
+ *vm = shiftright128(mid3, hi3, j - 64 - 1);
+ }
+ else
+ {
+ const uint64 lo3 = lo + lo;
+ const uint64 mid3 = mid + mid + (lo3 < lo);
+ const uint64 hi3 = hi + hi + (mid3 < mid);
+ const uint64 lo4 = lo3 - mul[0];
+ const uint64 mid4 = mid3 - mul[1] - (lo4 > lo3);
+ const uint64 hi4 = hi3 - (mid4 > mid3);
+
+ *vm = shiftright128(mid4, hi4, j - 64);
+ }
+
+ return shiftright128(mid, hi, j - 64 - 1);
+}
+
+#endif /* // HAS_64_BIT_INTRINSICS */
+
+static inline uint32
+decimalLength(const uint64 v)
+{
+ /* This is slightly faster than a loop. */
+ /* The average output length is 16.38 digits, so we check high-to-low. */
+ /* Function precondition: v is not an 18, 19, or 20-digit number. */
+ /* (17 digits are sufficient for round-tripping.) */
+ Assert(v < 100000000000000000L);
+ if (v >= 10000000000000000L)
+ {
+ return 17;
+ }
+ if (v >= 1000000000000000L)
+ {
+ return 16;
+ }
+ if (v >= 100000000000000L)
+ {
+ return 15;
+ }
+ if (v >= 10000000000000L)
+ {
+ return 14;
+ }
+ if (v >= 1000000000000L)
+ {
+ return 13;
+ }
+ if (v >= 100000000000L)
+ {
+ return 12;
+ }
+ if (v >= 10000000000L)
+ {
+ return 11;
+ }
+ if (v >= 1000000000L)
+ {
+ return 10;
+ }
+ if (v >= 100000000L)
+ {
+ return 9;
+ }
+ if (v >= 10000000L)
+ {
+ return 8;
+ }
+ if (v >= 1000000L)
+ {
+ return 7;
+ }
+ if (v >= 100000L)
+ {
+ return 6;
+ }
+ if (v >= 10000L)
+ {
+ return 5;
+ }
+ if (v >= 1000L)
+ {
+ return 4;
+ }
+ if (v >= 100L)
+ {
+ return 3;
+ }
+ if (v >= 10L)
+ {
+ return 2;
+ }
+ return 1;
+}
+
+/* A floating decimal representing m * 10^e. */
+typedef struct floating_decimal_64
+{
+ uint64 mantissa;
+ int32 exponent;
+} floating_decimal_64;
+
+static inline floating_decimal_64
+d2d(const uint64 ieeeMantissa, const uint32 ieeeExponent)
+{
+ int32 e2;
+ uint64 m2;
+
+ if (ieeeExponent == 0)
+ {
+ /* We subtract 2 so that the bounds computation has 2 additional bits. */
+ e2 = 1 - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2;
+ m2 = ieeeMantissa;
+ }
+ else
+ {
+ e2 = ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2;
+ m2 = (UINT64CONST(1) << DOUBLE_MANTISSA_BITS) | ieeeMantissa;
+ }
+
+#if STRICTLY_SHORTEST
+ const bool even = (m2 & 1) == 0;
+ const bool acceptBounds = even;
+#else
+ const bool acceptBounds = false;
+#endif
+
+ /* Step 2: Determine the interval of legal decimal representations. */
+ const uint64 mv = 4 * m2;
+
+ /* Implicit bool -> int conversion. True is 1, false is 0. */
+ const uint32 mmShift = ieeeMantissa != 0 || ieeeExponent <= 1;
+
+ /* We would compute mp and mm like this: */
+ /* uint64 mp = 4 * m2 + 2; */
+ /* uint64 mm = mv - 1 - mmShift; */
+
+ /* Step 3: Convert to a decimal power base using 128-bit arithmetic. */
+ uint64 vr,
+ vp,
+ vm;
+ int32 e10;
+ bool vmIsTrailingZeros = false;
+ bool vrIsTrailingZeros = false;
+
+ if (e2 >= 0)
+ {
+ /*
+ * I tried special-casing q == 0, but there was no effect on
+ * performance.
+ *
+ * This expr is slightly faster than max(0, log10Pow2(e2) - 1).
+ */
+ const uint32 q = log10Pow2(e2) - (e2 > 3);
+ const int32 k = DOUBLE_POW5_INV_BITCOUNT + pow5bits(q) - 1;
+ const int32 i = -e2 + q + k;
+
+ e10 = q;
+
+ vr = mulShiftAll(m2, DOUBLE_POW5_INV_SPLIT[q], i, &vp, &vm, mmShift);
+
+ if (q <= 21)
+ {
+ /*
+ * This should use q <= 22, but I think 21 is also safe. Smaller
+ * values may still be safe, but it's more difficult to reason
+ * about them.
+ *
+ * Only one of mp, mv, and mm can be a multiple of 5, if any.
+ */
+ const uint32 mvMod5 = (uint32) (mv - 5 * div5(mv));
+
+ if (mvMod5 == 0)
+ {
+ vrIsTrailingZeros = multipleOfPowerOf5(mv, q);
+ }
+ else if (acceptBounds)
+ {
+ /*----
+ * Same as min(e2 + (~mm & 1), pow5Factor(mm)) >= q
+ * <=> e2 + (~mm & 1) >= q && pow5Factor(mm) >= q
+ * <=> true && pow5Factor(mm) >= q, since e2 >= q.
+ *----
+ */
+ vmIsTrailingZeros = multipleOfPowerOf5(mv - 1 - mmShift, q);
+ }
+ else
+ {
+ /* Same as min(e2 + 1, pow5Factor(mp)) >= q. */
+ vp -= multipleOfPowerOf5(mv + 2, q);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * This expression is slightly faster than max(0, log10Pow5(-e2) - 1).
+ */
+ const uint32 q = log10Pow5(-e2) - (-e2 > 1);
+ const int32 i = -e2 - q;
+ const int32 k = pow5bits(i) - DOUBLE_POW5_BITCOUNT;
+ const int32 j = q - k;
+
+ e10 = q + e2;
+
+ vr = mulShiftAll(m2, DOUBLE_POW5_SPLIT[i], j, &vp, &vm, mmShift);
+
+ if (q <= 1)
+ {
+ /*
+ * {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q
+ * trailing 0 bits.
+ */
+ /* mv = 4 * m2, so it always has at least two trailing 0 bits. */
+ vrIsTrailingZeros = true;
+ if (acceptBounds)
+ {
+ /*
+ * mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff
+ * mmShift == 1.
+ */
+ vmIsTrailingZeros = mmShift == 1;
+ }
+ else
+ {
+ /*
+ * mp = mv + 2, so it always has at least one trailing 0 bit.
+ */
+ --vp;
+ }
+ }
+ else if (q < 63)
+ {
+ /* TODO(ulfjack):Use a tighter bound here. */
+ /*
+ * We need to compute min(ntz(mv), pow5Factor(mv) - e2) >= q - 1
+ */
+ /* <=> ntz(mv) >= q - 1 && pow5Factor(mv) - e2 >= q - 1 */
+ /* <=> ntz(mv) >= q - 1 (e2 is negative and -e2 >= q) */
+ /* <=> (mv & ((1 << (q - 1)) - 1)) == 0 */
+
+ /*
+ * We also need to make sure that the left shift does not
+ * overflow.
+ */
+ vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1);
+ }
+ }
+
+ /*
+ * Step 4: Find the shortest decimal representation in the interval of
+ * legal representations.
+ */
+ uint32 removed = 0;
+ uint8 lastRemovedDigit = 0;
+ uint64 output;
+
+ /* On average, we remove ~2 digits. */
+ if (vmIsTrailingZeros || vrIsTrailingZeros)
+ {
+ /* General case, which happens rarely (~0.7%). */
+ for (;;)
+ {
+ const uint64 vpDiv10 = div10(vp);
+ const uint64 vmDiv10 = div10(vm);
+
+ if (vpDiv10 <= vmDiv10)
+ break;
+
+ const uint32 vmMod10 = (uint32) (vm - 10 * vmDiv10);
+ const uint64 vrDiv10 = div10(vr);
+ const uint32 vrMod10 = (uint32) (vr - 10 * vrDiv10);
+
+ vmIsTrailingZeros &= vmMod10 == 0;
+ vrIsTrailingZeros &= lastRemovedDigit == 0;
+ lastRemovedDigit = (uint8) vrMod10;
+ vr = vrDiv10;
+ vp = vpDiv10;
+ vm = vmDiv10;
+ ++removed;
+ }
+
+ if (vmIsTrailingZeros)
+ {
+ for (;;)
+ {
+ const uint64 vmDiv10 = div10(vm);
+ const uint32 vmMod10 = (uint32) (vm - 10 * vmDiv10);
+
+ if (vmMod10 != 0)
+ break;
+
+ const uint64 vpDiv10 = div10(vp);
+ const uint64 vrDiv10 = div10(vr);
+ const uint32 vrMod10 = (uint32) (vr - 10 * vrDiv10);
+
+ vrIsTrailingZeros &= lastRemovedDigit == 0;
+ lastRemovedDigit = (uint8) vrMod10;
+ vr = vrDiv10;
+ vp = vpDiv10;
+ vm = vmDiv10;
+ ++removed;
+ }
+ }
+
+ if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0)
+ {
+ /* Round even if the exact number is .....50..0. */
+ lastRemovedDigit = 4;
+ }
+
+ /*
+ * We need to take vr + 1 if vr is outside bounds or we need to round
+ * up.
+ */
+ output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5);
+ }
+ else
+ {
+ /*
+ * Specialized for the common case (~99.3%). Percentages below are
+ * relative to this.
+ */
+ bool roundUp = false;
+ const uint64 vpDiv100 = div100(vp);
+ const uint64 vmDiv100 = div100(vm);
+
+ if (vpDiv100 > vmDiv100)
+ {
+ /* Optimization:remove two digits at a time(~86.2 %). */
+ const uint64 vrDiv100 = div100(vr);
+ const uint32 vrMod100 = (uint32) (vr - 100 * vrDiv100);
+
+ roundUp = vrMod100 >= 50;
+ vr = vrDiv100;
+ vp = vpDiv100;
+ vm = vmDiv100;
+ removed += 2;
+ }
+
+ /*----
+ * Loop iterations below (approximately), without optimization
+ * above:
+ *
+ * 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%,
+ * 6+: 0.02%
+ *
+ * Loop iterations below (approximately), with optimization
+ * above:
+ *
+ * 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02%
+ *----
+ */
+ for (;;)
+ {
+ const uint64 vpDiv10 = div10(vp);
+ const uint64 vmDiv10 = div10(vm);
+
+ if (vpDiv10 <= vmDiv10)
+ break;
+
+ const uint64 vrDiv10 = div10(vr);
+ const uint32 vrMod10 = (uint32) (vr - 10 * vrDiv10);
+
+ roundUp = vrMod10 >= 5;
+ vr = vrDiv10;
+ vp = vpDiv10;
+ vm = vmDiv10;
+ ++removed;
+ }
+
+ /*
+ * We need to take vr + 1 if vr is outside bounds or we need to round
+ * up.
+ */
+ output = vr + (vr == vm || roundUp);
+ }
+
+ const int32 exp = e10 + removed;
+
+ floating_decimal_64 fd;
+
+ fd.exponent = exp;
+ fd.mantissa = output;
+ return fd;
+}
+
+static inline int
+to_chars_df(const floating_decimal_64 v, const uint32 olength, char *const result)
+{
+ /* Step 5: Print the decimal representation. */
+ int index = 0;
+
+ uint64 output = v.mantissa;
+ int32 exp = v.exponent;
+
+ /*----
+ * On entry, mantissa * 10^exp is the result to be output.
+ * Caller has already done the - sign if needed.
+ *
+ * We want to insert the point somewhere depending on the output length
+ * and exponent, which might mean adding zeros:
+ *
+ * exp | format
+ * 1+ | ddddddddd000000
+ * 0 | ddddddddd
+ * -1 .. -len+1 | dddddddd.d to d.ddddddddd
+ * -len ... | 0.ddddddddd to 0.000dddddd
+ */
+ uint32 i = 0;
+ int32 nexp = exp + olength;
+
+ if (nexp <= 0)
+ {
+ /* -nexp is number of 0s to add after '.' */
+ Assert(nexp >= -3);
+ /* 0.000ddddd */
+ index = 2 - nexp;
+ /* won't need more than this many 0s */
+ memcpy(result, "0.000000", 8);
+ }
+ else if (exp < 0)
+ {
+ /*
+ * dddd.dddd; leave space at the start and move the '.' in after
+ */
+ index = 1;
+ }
+ else
+ {
+ /*
+ * We can save some code later by pre-filling with zeros. We know
+ * that there can be no more than 16 output digits in this form,
+ * otherwise we would not choose fixed-point output.
+ */
+ Assert(exp < 16 && exp + olength <= 16);
+ memset(result, '0', 16);
+ }
+
+ /*
+ * We prefer 32-bit operations, even on 64-bit platforms. We have at most
+ * 17 digits, and uint32 can store 9 digits. If output doesn't fit into
+ * uint32, we cut off 8 digits, so the rest will fit into uint32.
+ */
+ if ((output >> 32) != 0)
+ {
+ /* Expensive 64-bit division. */
+ const uint64 q = div1e8(output);
+ uint32 output2 = (uint32) (output - 100000000 * q);
+ const uint32 c = output2 % 10000;
+
+ output = q;
+ output2 /= 10000;
+
+ const uint32 d = output2 % 10000;
+ const uint32 c0 = (c % 100) << 1;
+ const uint32 c1 = (c / 100) << 1;
+ const uint32 d0 = (d % 100) << 1;
+ const uint32 d1 = (d / 100) << 1;
+
+ memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2);
+ memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2);
+ memcpy(result + index + olength - i - 6, DIGIT_TABLE + d0, 2);
+ memcpy(result + index + olength - i - 8, DIGIT_TABLE + d1, 2);
+ i += 8;
+ }
+
+ uint32 output2 = (uint32) output;
+
+ while (output2 >= 10000)
+ {
+ const uint32 c = output2 - 10000 * (output2 / 10000);
+ const uint32 c0 = (c % 100) << 1;
+ const uint32 c1 = (c / 100) << 1;
+
+ output2 /= 10000;
+ memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2);
+ memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2);
+ i += 4;
+ }
+ if (output2 >= 100)
+ {
+ const uint32 c = (output2 % 100) << 1;
+
+ output2 /= 100;
+ memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2);
+ i += 2;
+ }
+ if (output2 >= 10)
+ {
+ const uint32 c = output2 << 1;
+
+ memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2);
+ }
+ else
+ {
+ result[index] = (char) ('0' + output2);
+ }
+
+ if (index == 1)
+ {
+ /*
+ * nexp is 1..15 here, representing the number of digits before the
+ * point. A value of 16 is not possible because we switch to
+ * scientific notation when the display exponent reaches 15.
+ */
+ Assert(nexp < 16);
+ /* gcc only seems to want to optimize memmove for small 2^n */
+ if (nexp & 8)
+ {
+ memmove(result + index - 1, result + index, 8);
+ index += 8;
+ }
+ if (nexp & 4)
+ {
+ memmove(result + index - 1, result + index, 4);
+ index += 4;
+ }
+ if (nexp & 2)
+ {
+ memmove(result + index - 1, result + index, 2);
+ index += 2;
+ }
+ if (nexp & 1)
+ {
+ result[index - 1] = result[index];
+ }
+ result[nexp] = '.';
+ index = olength + 1;
+ }
+ else if (exp >= 0)
+ {
+ /* we supplied the trailing zeros earlier, now just set the length. */
+ index = olength + exp;
+ }
+ else
+ {
+ index = olength + (2 - nexp);
+ }
+
+ return index;
+}
+
+static inline int
+to_chars(floating_decimal_64 v, const bool sign, char *const result)
+{
+ /* Step 5: Print the decimal representation. */
+ int index = 0;
+
+ uint64 output = v.mantissa;
+ uint32 olength = decimalLength(output);
+ int32 exp = v.exponent + olength - 1;
+
+ if (sign)
+ {
+ result[index++] = '-';
+ }
+
+ /*
+ * The thresholds for fixed-point output are chosen to match printf
+ * defaults. Beware that both the code of to_chars_df and the value
+ * of DOUBLE_SHORTEST_DECIMAL_LEN are sensitive to these thresholds.
+ */
+ if (exp >= -4 && exp < 15)
+ return to_chars_df(v, olength, result + index) + sign;
+
+ /*
+ * If v.exponent is exactly 0, we might have reached here via the small
+ * integer fast path, in which case v.mantissa might contain trailing
+ * (decimal) zeros. For scientific notation we need to move these zeros
+ * into the exponent. (For fixed point this doesn't matter, which is why
+ * we do this here rather than above.)
+ *
+ * Since we already calculated the display exponent (exp) above based on
+ * the old decimal length, that value does not change here. Instead, we
+ * just reduce the display length for each digit removed.
+ *
+ * If we didn't get here via the fast path, the raw exponent will not
+ * usually be 0, and there will be no trailing zeros, so we pay no more
+ * than one div10/multiply extra cost. We claw back half of that by
+ * checking for divisibility by 2 before dividing by 10.
+ */
+ if (v.exponent == 0)
+ {
+ while ((output & 1) == 0)
+ {
+ const uint64 q = div10(output);
+ const uint32 r = (uint32) (output - 10 * q);
+
+ if (r != 0)
+ break;
+ output = q;
+ --olength;
+ }
+ }
+
+ /*----
+ * Print the decimal digits.
+ *
+ * The following code is equivalent to:
+ *
+ * for (uint32 i = 0; i < olength - 1; ++i) {
+ * const uint32 c = output % 10; output /= 10;
+ * result[index + olength - i] = (char) ('0' + c);
+ * }
+ * result[index] = '0' + output % 10;
+ *----
+ */
+
+ uint32 i = 0;
+
+ /*
+ * We prefer 32-bit operations, even on 64-bit platforms. We have at most
+ * 17 digits, and uint32 can store 9 digits. If output doesn't fit into
+ * uint32, we cut off 8 digits, so the rest will fit into uint32.
+ */
+ if ((output >> 32) != 0)
+ {
+ /* Expensive 64-bit division. */
+ const uint64 q = div1e8(output);
+ uint32 output2 = (uint32) (output - 100000000 * q);
+
+ output = q;
+
+ const uint32 c = output2 % 10000;
+
+ output2 /= 10000;
+
+ const uint32 d = output2 % 10000;
+ const uint32 c0 = (c % 100) << 1;
+ const uint32 c1 = (c / 100) << 1;
+ const uint32 d0 = (d % 100) << 1;
+ const uint32 d1 = (d / 100) << 1;
+
+ memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2);
+ memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2);
+ memcpy(result + index + olength - i - 5, DIGIT_TABLE + d0, 2);
+ memcpy(result + index + olength - i - 7, DIGIT_TABLE + d1, 2);
+ i += 8;
+ }
+
+ uint32 output2 = (uint32) output;
+
+ while (output2 >= 10000)
+ {
+ const uint32 c = output2 - 10000 * (output2 / 10000);
+
+ output2 /= 10000;
+
+ const uint32 c0 = (c % 100) << 1;
+ const uint32 c1 = (c / 100) << 1;
+
+ memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2);
+ memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2);
+ i += 4;
+ }
+ if (output2 >= 100)
+ {
+ const uint32 c = (output2 % 100) << 1;
+
+ output2 /= 100;
+ memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2);
+ i += 2;
+ }
+ if (output2 >= 10)
+ {
+ const uint32 c = output2 << 1;
+
+ /*
+ * We can't use memcpy here: the decimal dot goes between these two
+ * digits.
+ */
+ result[index + olength - i] = DIGIT_TABLE[c + 1];
+ result[index] = DIGIT_TABLE[c];
+ }
+ else
+ {
+ result[index] = (char) ('0' + output2);
+ }
+
+ /* Print decimal point if needed. */
+ if (olength > 1)
+ {
+ result[index + 1] = '.';
+ index += olength + 1;
+ }
+ else
+ {
+ ++index;
+ }
+
+ /* Print the exponent. */
+ result[index++] = 'e';
+ if (exp < 0)
+ {
+ result[index++] = '-';
+ exp = -exp;
+ }
+ else
+ result[index++] = '+';
+
+ if (exp >= 100)
+ {
+ const int32 c = exp % 10;
+
+ memcpy(result + index, DIGIT_TABLE + 2 * (exp / 10), 2);
+ result[index + 2] = (char) ('0' + c);
+ index += 3;
+ }
+ else
+ {
+ memcpy(result + index, DIGIT_TABLE + 2 * exp, 2);
+ index += 2;
+ }
+
+ return index;
+}
+
+static inline bool
+d2d_small_int(const uint64 ieeeMantissa,
+ const uint32 ieeeExponent,
+ floating_decimal_64 *v)
+{
+ const int32 e2 = (int32) ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS;
+
+ /*
+ * Avoid using multiple "return false;" here since it tends to provoke the
+ * compiler into inlining multiple copies of d2d, which is undesirable.
+ */
+
+ if (e2 >= -DOUBLE_MANTISSA_BITS && e2 <= 0)
+ {
+ /*----
+ * Since 2^52 <= m2 < 2^53 and 0 <= -e2 <= 52:
+ * 1 <= f = m2 / 2^-e2 < 2^53.
+ *
+ * Test if the lower -e2 bits of the significand are 0, i.e. whether
+ * the fraction is 0. We can use ieeeMantissa here, since the implied
+ * 1 bit can never be tested by this; the implied 1 can only be part
+ * of a fraction if e2 < -DOUBLE_MANTISSA_BITS which we already
+ * checked. (e.g. 0.5 gives ieeeMantissa == 0 and e2 == -53)
+ */
+ const uint64 mask = (UINT64CONST(1) << -e2) - 1;
+ const uint64 fraction = ieeeMantissa & mask;
+
+ if (fraction == 0)
+ {
+ /*----
+ * f is an integer in the range [1, 2^53).
+ * Note: mantissa might contain trailing (decimal) 0's.
+ * Note: since 2^53 < 10^16, there is no need to adjust
+ * decimalLength().
+ */
+ const uint64 m2 = (UINT64CONST(1) << DOUBLE_MANTISSA_BITS) | ieeeMantissa;
+
+ v->mantissa = m2 >> -e2;
+ v->exponent = 0;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/*
+ * Store the shortest decimal representation of the given double as an
+ * UNTERMINATED string in the caller's supplied buffer (which must be at least
+ * DOUBLE_SHORTEST_DECIMAL_LEN-1 bytes long).
+ *
+ * Returns the number of bytes stored.
+ */
+int
+double_to_shortest_decimal_bufn(double f, char *result)
+{
+ /*
+ * Step 1: Decode the floating-point number, and unify normalized and
+ * subnormal cases.
+ */
+ const uint64 bits = double_to_bits(f);
+
+ /* Decode bits into sign, mantissa, and exponent. */
+ const bool ieeeSign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0;
+ const uint64 ieeeMantissa = bits & ((UINT64CONST(1) << DOUBLE_MANTISSA_BITS) - 1);
+ const uint32 ieeeExponent = (uint32) ((bits >> DOUBLE_MANTISSA_BITS) & ((1u << DOUBLE_EXPONENT_BITS) - 1));
+
+ /* Case distinction; exit early for the easy cases. */
+ if (ieeeExponent == ((1u << DOUBLE_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0))
+ {
+ return copy_special_str(result, ieeeSign, ieeeExponent, ieeeMantissa);
+ }
+
+ floating_decimal_64 v;
+ const bool isSmallInt = d2d_small_int(ieeeMantissa, ieeeExponent, &v);
+
+ if (!isSmallInt)
+ {
+ v = d2d(ieeeMantissa, ieeeExponent);
+ }
+
+ return to_chars(v, ieeeSign, result);
+}
+
+/*
+ * Store the shortest decimal representation of the given double as a
+ * null-terminated string in the caller's supplied buffer (which must be at
+ * least DOUBLE_SHORTEST_DECIMAL_LEN bytes long).
+ *
+ * Returns the string length.
+ */
+int
+double_to_shortest_decimal_buf(double f, char *result)
+{
+ const int index = double_to_shortest_decimal_bufn(f, result);
+
+ /* Terminate the string. */
+ Assert(index < DOUBLE_SHORTEST_DECIMAL_LEN);
+ result[index] = '\0';
+ return index;
+}
+
+/*
+ * Return the shortest decimal representation as a null-terminated palloc'd
+ * string (outside the backend, uses malloc() instead).
+ *
+ * Caller is responsible for freeing the result.
+ */
+char *
+double_to_shortest_decimal(double f)
+{
+ char *const result = (char *) palloc(DOUBLE_SHORTEST_DECIMAL_LEN);
+
+ double_to_shortest_decimal_buf(f, result);
+ return result;
+}
diff --git a/src/common/d2s_full_table.h b/src/common/d2s_full_table.h
new file mode 100644
index 0000000000..d6520b437b
--- /dev/null
+++ b/src/common/d2s_full_table.h
@@ -0,0 +1,358 @@
+/*---------------------------------------------------------------------------
+ *
+ * Ryu floating-point output for double precision.
+ *
+ * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/d2s_full_table.h
+ *
+ * This is a modification of code taken from github.com/ulfjack/ryu under the
+ * terms of the Boost license (not the Apache license). The original copyright
+ * notice follows:
+ *
+ * Copyright 2018 Ulf Adams
+ *
+ * The contents of this file may be used under the terms of the Apache
+ * License, Version 2.0.
+ *
+ * (See accompanying file LICENSE-Apache or copy at
+ * http://www.apache.org/licenses/LICENSE-2.0)
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * Boost Software License, Version 1.0.
+ *
+ * (See accompanying file LICENSE-Boost or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Unless required by applicable law or agreed to in writing, this software is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+#ifndef RYU_D2S_FULL_TABLE_H
+#define RYU_D2S_FULL_TABLE_H
+
+/*
+ * These tables are generated (by the upstream) using PrintDoubleLookupTable
+ * from the upstream sources at github.com/ulfjack/ryu, and then modified (by
+ * us) by adding UINT64CONST.
+ */
+static const uint64 DOUBLE_POW5_INV_SPLIT[292][2] = {
+ {UINT64CONST(1), UINT64CONST(288230376151711744)}, {UINT64CONST(3689348814741910324), UINT64CONST(230584300921369395)},
+ {UINT64CONST(2951479051793528259), UINT64CONST(184467440737095516)}, {UINT64CONST(17118578500402463900), UINT64CONST(147573952589676412)},
+ {UINT64CONST(12632330341676300947), UINT64CONST(236118324143482260)}, {UINT64CONST(10105864273341040758), UINT64CONST(188894659314785808)},
+ {UINT64CONST(15463389048156653253), UINT64CONST(151115727451828646)}, {UINT64CONST(17362724847566824558), UINT64CONST(241785163922925834)},
+ {UINT64CONST(17579528692795369969), UINT64CONST(193428131138340667)}, {UINT64CONST(6684925324752475329), UINT64CONST(154742504910672534)},
+ {UINT64CONST(18074578149087781173), UINT64CONST(247588007857076054)}, {UINT64CONST(18149011334012135262), UINT64CONST(198070406285660843)},
+ {UINT64CONST(3451162622983977240), UINT64CONST(158456325028528675)}, {UINT64CONST(5521860196774363583), UINT64CONST(253530120045645880)},
+ {UINT64CONST(4417488157419490867), UINT64CONST(202824096036516704)}, {UINT64CONST(7223339340677503017), UINT64CONST(162259276829213363)},
+ {UINT64CONST(7867994130342094503), UINT64CONST(259614842926741381)}, {UINT64CONST(2605046489531765280), UINT64CONST(207691874341393105)},
+ {UINT64CONST(2084037191625412224), UINT64CONST(166153499473114484)}, {UINT64CONST(10713157136084480204), UINT64CONST(265845599156983174)},
+ {UINT64CONST(12259874523609494487), UINT64CONST(212676479325586539)}, {UINT64CONST(13497248433629505913), UINT64CONST(170141183460469231)},
+ {UINT64CONST(14216899864323388813), UINT64CONST(272225893536750770)}, {UINT64CONST(11373519891458711051), UINT64CONST(217780714829400616)},
+ {UINT64CONST(5409467098425058518), UINT64CONST(174224571863520493)}, {UINT64CONST(4965798542738183305), UINT64CONST(278759314981632789)},
+ {UINT64CONST(7661987648932456967), UINT64CONST(223007451985306231)}, {UINT64CONST(2440241304404055250), UINT64CONST(178405961588244985)},
+ {UINT64CONST(3904386087046488400), UINT64CONST(285449538541191976)}, {UINT64CONST(17880904128604832013), UINT64CONST(228359630832953580)},
+ {UINT64CONST(14304723302883865611), UINT64CONST(182687704666362864)}, {UINT64CONST(15133127457049002812), UINT64CONST(146150163733090291)},
+ {UINT64CONST(16834306301794583852), UINT64CONST(233840261972944466)}, {UINT64CONST(9778096226693756759), UINT64CONST(187072209578355573)},
+ {UINT64CONST(15201174610838826053), UINT64CONST(149657767662684458)}, {UINT64CONST(2185786488890659746), UINT64CONST(239452428260295134)},
+ {UINT64CONST(5437978005854438120), UINT64CONST(191561942608236107)}, {UINT64CONST(15418428848909281466), UINT64CONST(153249554086588885)},
+ {UINT64CONST(6222742084545298729), UINT64CONST(245199286538542217)}, {UINT64CONST(16046240111861969953), UINT64CONST(196159429230833773)},
+ {UINT64CONST(1768945645263844993), UINT64CONST(156927543384667019)}, {UINT64CONST(10209010661905972635), UINT64CONST(251084069415467230)},
+ {UINT64CONST(8167208529524778108), UINT64CONST(200867255532373784)}, {UINT64CONST(10223115638361732810), UINT64CONST(160693804425899027)},
+ {UINT64CONST(1599589762411131202), UINT64CONST(257110087081438444)}, {UINT64CONST(4969020624670815285), UINT64CONST(205688069665150755)},
+ {UINT64CONST(3975216499736652228), UINT64CONST(164550455732120604)}, {UINT64CONST(13739044029062464211), UINT64CONST(263280729171392966)},
+ {UINT64CONST(7301886408508061046), UINT64CONST(210624583337114373)}, {UINT64CONST(13220206756290269483), UINT64CONST(168499666669691498)},
+ {UINT64CONST(17462981995322520850), UINT64CONST(269599466671506397)}, {UINT64CONST(6591687966774196033), UINT64CONST(215679573337205118)},
+ {UINT64CONST(12652048002903177473), UINT64CONST(172543658669764094)}, {UINT64CONST(9175230360419352987), UINT64CONST(276069853871622551)},
+ {UINT64CONST(3650835473593572067), UINT64CONST(220855883097298041)}, {UINT64CONST(17678063637842498946), UINT64CONST(176684706477838432)},
+ {UINT64CONST(13527506561580357021), UINT64CONST(282695530364541492)}, {UINT64CONST(3443307619780464970), UINT64CONST(226156424291633194)},
+ {UINT64CONST(6443994910566282300), UINT64CONST(180925139433306555)}, {UINT64CONST(5155195928453025840), UINT64CONST(144740111546645244)},
+ {UINT64CONST(15627011115008661990), UINT64CONST(231584178474632390)}, {UINT64CONST(12501608892006929592), UINT64CONST(185267342779705912)},
+ {UINT64CONST(2622589484121723027), UINT64CONST(148213874223764730)}, {UINT64CONST(4196143174594756843), UINT64CONST(237142198758023568)},
+ {UINT64CONST(10735612169159626121), UINT64CONST(189713759006418854)}, {UINT64CONST(12277838550069611220), UINT64CONST(151771007205135083)},
+ {UINT64CONST(15955192865369467629), UINT64CONST(242833611528216133)}, {UINT64CONST(1696107848069843133), UINT64CONST(194266889222572907)},
+ {UINT64CONST(12424932722681605476), UINT64CONST(155413511378058325)}, {UINT64CONST(1433148282581017146), UINT64CONST(248661618204893321)},
+ {UINT64CONST(15903913885032455010), UINT64CONST(198929294563914656)}, {UINT64CONST(9033782293284053685), UINT64CONST(159143435651131725)},
+ {UINT64CONST(14454051669254485895), UINT64CONST(254629497041810760)}, {UINT64CONST(11563241335403588716), UINT64CONST(203703597633448608)},
+ {UINT64CONST(16629290697806691620), UINT64CONST(162962878106758886)}, {UINT64CONST(781423413297334329), UINT64CONST(260740604970814219)},
+ {UINT64CONST(4314487545379777786), UINT64CONST(208592483976651375)}, {UINT64CONST(3451590036303822229), UINT64CONST(166873987181321100)},
+ {UINT64CONST(5522544058086115566), UINT64CONST(266998379490113760)}, {UINT64CONST(4418035246468892453), UINT64CONST(213598703592091008)},
+ {UINT64CONST(10913125826658934609), UINT64CONST(170878962873672806)}, {UINT64CONST(10082303693170474728), UINT64CONST(273406340597876490)},
+ {UINT64CONST(8065842954536379782), UINT64CONST(218725072478301192)}, {UINT64CONST(17520720807854834795), UINT64CONST(174980057982640953)},
+ {UINT64CONST(5897060404116273733), UINT64CONST(279968092772225526)}, {UINT64CONST(1028299508551108663), UINT64CONST(223974474217780421)},
+ {UINT64CONST(15580034865808528224), UINT64CONST(179179579374224336)}, {UINT64CONST(17549358155809824511), UINT64CONST(286687326998758938)},
+ {UINT64CONST(2971440080422128639), UINT64CONST(229349861599007151)}, {UINT64CONST(17134547323305344204), UINT64CONST(183479889279205720)},
+ {UINT64CONST(13707637858644275364), UINT64CONST(146783911423364576)}, {UINT64CONST(14553522944347019935), UINT64CONST(234854258277383322)},
+ {UINT64CONST(4264120725993795302), UINT64CONST(187883406621906658)}, {UINT64CONST(10789994210278856888), UINT64CONST(150306725297525326)},
+ {UINT64CONST(9885293106962350374), UINT64CONST(240490760476040522)}, {UINT64CONST(529536856086059653), UINT64CONST(192392608380832418)},
+ {UINT64CONST(7802327114352668369), UINT64CONST(153914086704665934)}, {UINT64CONST(1415676938738538420), UINT64CONST(246262538727465495)},
+ {UINT64CONST(1132541550990830736), UINT64CONST(197010030981972396)}, {UINT64CONST(15663428499760305882), UINT64CONST(157608024785577916)},
+ {UINT64CONST(17682787970132668764), UINT64CONST(252172839656924666)}, {UINT64CONST(10456881561364224688), UINT64CONST(201738271725539733)},
+ {UINT64CONST(15744202878575200397), UINT64CONST(161390617380431786)}, {UINT64CONST(17812026976236499989), UINT64CONST(258224987808690858)},
+ {UINT64CONST(3181575136763469022), UINT64CONST(206579990246952687)}, {UINT64CONST(13613306553636506187), UINT64CONST(165263992197562149)},
+ {UINT64CONST(10713244041592678929), UINT64CONST(264422387516099439)}, {UINT64CONST(12259944048016053467), UINT64CONST(211537910012879551)},
+ {UINT64CONST(6118606423670932450), UINT64CONST(169230328010303641)}, {UINT64CONST(2411072648389671274), UINT64CONST(270768524816485826)},
+ {UINT64CONST(16686253377679378312), UINT64CONST(216614819853188660)}, {UINT64CONST(13349002702143502650), UINT64CONST(173291855882550928)},
+ {UINT64CONST(17669055508687693916), UINT64CONST(277266969412081485)}, {UINT64CONST(14135244406950155133), UINT64CONST(221813575529665188)},
+ {UINT64CONST(240149081334393137), UINT64CONST(177450860423732151)}, {UINT64CONST(11452284974360759988), UINT64CONST(283921376677971441)},
+ {UINT64CONST(5472479164746697667), UINT64CONST(227137101342377153)}, {UINT64CONST(11756680961281178780), UINT64CONST(181709681073901722)},
+ {UINT64CONST(2026647139541122378), UINT64CONST(145367744859121378)}, {UINT64CONST(18000030682233437097), UINT64CONST(232588391774594204)},
+ {UINT64CONST(18089373360528660001), UINT64CONST(186070713419675363)}, {UINT64CONST(3403452244197197031), UINT64CONST(148856570735740291)},
+ {UINT64CONST(16513570034941246220), UINT64CONST(238170513177184465)}, {UINT64CONST(13210856027952996976), UINT64CONST(190536410541747572)},
+ {UINT64CONST(3189987192878576934), UINT64CONST(152429128433398058)}, {UINT64CONST(1414630693863812771), UINT64CONST(243886605493436893)},
+ {UINT64CONST(8510402184574870864), UINT64CONST(195109284394749514)}, {UINT64CONST(10497670562401807014), UINT64CONST(156087427515799611)},
+ {UINT64CONST(9417575270359070576), UINT64CONST(249739884025279378)}, {UINT64CONST(14912757845771077107), UINT64CONST(199791907220223502)},
+ {UINT64CONST(4551508647133041040), UINT64CONST(159833525776178802)}, {UINT64CONST(10971762650154775986), UINT64CONST(255733641241886083)},
+ {UINT64CONST(16156107749607641435), UINT64CONST(204586912993508866)}, {UINT64CONST(9235537384944202825), UINT64CONST(163669530394807093)},
+ {UINT64CONST(11087511001168814197), UINT64CONST(261871248631691349)}, {UINT64CONST(12559357615676961681), UINT64CONST(209496998905353079)},
+ {UINT64CONST(13736834907283479668), UINT64CONST(167597599124282463)}, {UINT64CONST(18289587036911657145), UINT64CONST(268156158598851941)},
+ {UINT64CONST(10942320814787415393), UINT64CONST(214524926879081553)}, {UINT64CONST(16132554281313752961), UINT64CONST(171619941503265242)},
+ {UINT64CONST(11054691591134363444), UINT64CONST(274591906405224388)}, {UINT64CONST(16222450902391311402), UINT64CONST(219673525124179510)},
+ {UINT64CONST(12977960721913049122), UINT64CONST(175738820099343608)}, {UINT64CONST(17075388340318968271), UINT64CONST(281182112158949773)},
+ {UINT64CONST(2592264228029443648), UINT64CONST(224945689727159819)}, {UINT64CONST(5763160197165465241), UINT64CONST(179956551781727855)},
+ {UINT64CONST(9221056315464744386), UINT64CONST(287930482850764568)}, {UINT64CONST(14755542681855616155), UINT64CONST(230344386280611654)},
+ {UINT64CONST(15493782960226403247), UINT64CONST(184275509024489323)}, {UINT64CONST(1326979923955391628), UINT64CONST(147420407219591459)},
+ {UINT64CONST(9501865507812447252), UINT64CONST(235872651551346334)}, {UINT64CONST(11290841220991868125), UINT64CONST(188698121241077067)},
+ {UINT64CONST(1653975347309673853), UINT64CONST(150958496992861654)}, {UINT64CONST(10025058185179298811), UINT64CONST(241533595188578646)},
+ {UINT64CONST(4330697733401528726), UINT64CONST(193226876150862917)}, {UINT64CONST(14532604630946953951), UINT64CONST(154581500920690333)},
+ {UINT64CONST(1116074521063664381), UINT64CONST(247330401473104534)}, {UINT64CONST(4582208431592841828), UINT64CONST(197864321178483627)},
+ {UINT64CONST(14733813189500004432), UINT64CONST(158291456942786901)}, {UINT64CONST(16195403473716186445), UINT64CONST(253266331108459042)},
+ {UINT64CONST(5577625149489128510), UINT64CONST(202613064886767234)}, {UINT64CONST(8151448934333213131), UINT64CONST(162090451909413787)},
+ {UINT64CONST(16731667109675051333), UINT64CONST(259344723055062059)}, {UINT64CONST(17074682502481951390), UINT64CONST(207475778444049647)},
+ {UINT64CONST(6281048372501740465), UINT64CONST(165980622755239718)}, {UINT64CONST(6360328581260874421), UINT64CONST(265568996408383549)},
+ {UINT64CONST(8777611679750609860), UINT64CONST(212455197126706839)}, {UINT64CONST(10711438158542398211), UINT64CONST(169964157701365471)},
+ {UINT64CONST(9759603424184016492), UINT64CONST(271942652322184754)}, {UINT64CONST(11497031554089123517), UINT64CONST(217554121857747803)},
+ {UINT64CONST(16576322872755119460), UINT64CONST(174043297486198242)}, {UINT64CONST(11764721337440549842), UINT64CONST(278469275977917188)},
+ {UINT64CONST(16790474699436260520), UINT64CONST(222775420782333750)}, {UINT64CONST(13432379759549008416), UINT64CONST(178220336625867000)},
+ {UINT64CONST(3045063541568861850), UINT64CONST(285152538601387201)}, {UINT64CONST(17193446092222730773), UINT64CONST(228122030881109760)},
+ {UINT64CONST(13754756873778184618), UINT64CONST(182497624704887808)}, {UINT64CONST(18382503128506368341), UINT64CONST(145998099763910246)},
+ {UINT64CONST(3586563302416817083), UINT64CONST(233596959622256395)}, {UINT64CONST(2869250641933453667), UINT64CONST(186877567697805116)},
+ {UINT64CONST(17052795772514404226), UINT64CONST(149502054158244092)}, {UINT64CONST(12527077977055405469), UINT64CONST(239203286653190548)},
+ {UINT64CONST(17400360011128145022), UINT64CONST(191362629322552438)}, {UINT64CONST(2852241564676785048), UINT64CONST(153090103458041951)},
+ {UINT64CONST(15631632947708587046), UINT64CONST(244944165532867121)}, {UINT64CONST(8815957543424959314), UINT64CONST(195955332426293697)},
+ {UINT64CONST(18120812478965698421), UINT64CONST(156764265941034957)}, {UINT64CONST(14235904707377476180), UINT64CONST(250822825505655932)},
+ {UINT64CONST(4010026136418160298), UINT64CONST(200658260404524746)}, {UINT64CONST(17965416168102169531), UINT64CONST(160526608323619796)},
+ {UINT64CONST(2919224165770098987), UINT64CONST(256842573317791675)}, {UINT64CONST(2335379332616079190), UINT64CONST(205474058654233340)},
+ {UINT64CONST(1868303466092863352), UINT64CONST(164379246923386672)}, {UINT64CONST(6678634360490491686), UINT64CONST(263006795077418675)},
+ {UINT64CONST(5342907488392393349), UINT64CONST(210405436061934940)}, {UINT64CONST(4274325990713914679), UINT64CONST(168324348849547952)},
+ {UINT64CONST(10528270399884173809), UINT64CONST(269318958159276723)}, {UINT64CONST(15801313949391159694), UINT64CONST(215455166527421378)},
+ {UINT64CONST(1573004715287196786), UINT64CONST(172364133221937103)}, {UINT64CONST(17274202803427156150), UINT64CONST(275782613155099364)},
+ {UINT64CONST(17508711057483635243), UINT64CONST(220626090524079491)}, {UINT64CONST(10317620031244997871), UINT64CONST(176500872419263593)},
+ {UINT64CONST(12818843235250086271), UINT64CONST(282401395870821749)}, {UINT64CONST(13944423402941979340), UINT64CONST(225921116696657399)},
+ {UINT64CONST(14844887537095493795), UINT64CONST(180736893357325919)}, {UINT64CONST(15565258844418305359), UINT64CONST(144589514685860735)},
+ {UINT64CONST(6457670077359736959), UINT64CONST(231343223497377177)}, {UINT64CONST(16234182506113520537), UINT64CONST(185074578797901741)},
+ {UINT64CONST(9297997190148906106), UINT64CONST(148059663038321393)}, {UINT64CONST(11187446689496339446), UINT64CONST(236895460861314229)},
+ {UINT64CONST(12639306166338981880), UINT64CONST(189516368689051383)}, {UINT64CONST(17490142562555006151), UINT64CONST(151613094951241106)},
+ {UINT64CONST(2158786396894637579), UINT64CONST(242580951921985771)}, {UINT64CONST(16484424376483351356), UINT64CONST(194064761537588616)},
+ {UINT64CONST(9498190686444770762), UINT64CONST(155251809230070893)}, {UINT64CONST(11507756283569722895), UINT64CONST(248402894768113429)},
+ {UINT64CONST(12895553841597688639), UINT64CONST(198722315814490743)}, {UINT64CONST(17695140702761971558), UINT64CONST(158977852651592594)},
+ {UINT64CONST(17244178680193423523), UINT64CONST(254364564242548151)}, {UINT64CONST(10105994129412828495), UINT64CONST(203491651394038521)},
+ {UINT64CONST(4395446488788352473), UINT64CONST(162793321115230817)}, {UINT64CONST(10722063196803274280), UINT64CONST(260469313784369307)},
+ {UINT64CONST(1198952927958798777), UINT64CONST(208375451027495446)}, {UINT64CONST(15716557601334680315), UINT64CONST(166700360821996356)},
+ {UINT64CONST(17767794532651667857), UINT64CONST(266720577315194170)}, {UINT64CONST(14214235626121334286), UINT64CONST(213376461852155336)},
+ {UINT64CONST(7682039686155157106), UINT64CONST(170701169481724269)}, {UINT64CONST(1223217053622520399), UINT64CONST(273121871170758831)},
+ {UINT64CONST(15735968901865657612), UINT64CONST(218497496936607064)}, {UINT64CONST(16278123936234436413), UINT64CONST(174797997549285651)},
+ {UINT64CONST(219556594781725998), UINT64CONST(279676796078857043)}, {UINT64CONST(7554342905309201445), UINT64CONST(223741436863085634)},
+ {UINT64CONST(9732823138989271479), UINT64CONST(178993149490468507)}, {UINT64CONST(815121763415193074), UINT64CONST(286389039184749612)},
+ {UINT64CONST(11720143854957885429), UINT64CONST(229111231347799689)}, {UINT64CONST(13065463898708218666), UINT64CONST(183288985078239751)},
+ {UINT64CONST(6763022304224664610), UINT64CONST(146631188062591801)}, {UINT64CONST(3442138057275642729), UINT64CONST(234609900900146882)},
+ {UINT64CONST(13821756890046245153), UINT64CONST(187687920720117505)}, {UINT64CONST(11057405512036996122), UINT64CONST(150150336576094004)},
+ {UINT64CONST(6623802375033462826), UINT64CONST(240240538521750407)}, {UINT64CONST(16367088344252501231), UINT64CONST(192192430817400325)},
+ {UINT64CONST(13093670675402000985), UINT64CONST(153753944653920260)}, {UINT64CONST(2503129006933649959), UINT64CONST(246006311446272417)},
+ {UINT64CONST(13070549649772650937), UINT64CONST(196805049157017933)}, {UINT64CONST(17835137349301941396), UINT64CONST(157444039325614346)},
+ {UINT64CONST(2710778055689733971), UINT64CONST(251910462920982955)}, {UINT64CONST(2168622444551787177), UINT64CONST(201528370336786364)},
+ {UINT64CONST(5424246770383340065), UINT64CONST(161222696269429091)}, {UINT64CONST(1300097203129523457), UINT64CONST(257956314031086546)},
+ {UINT64CONST(15797473021471260058), UINT64CONST(206365051224869236)}, {UINT64CONST(8948629602435097724), UINT64CONST(165092040979895389)},
+ {UINT64CONST(3249760919670425388), UINT64CONST(264147265567832623)}, {UINT64CONST(9978506365220160957), UINT64CONST(211317812454266098)},
+ {UINT64CONST(15361502721659949412), UINT64CONST(169054249963412878)}, {UINT64CONST(2442311466204457120), UINT64CONST(270486799941460606)},
+ {UINT64CONST(16711244431931206989), UINT64CONST(216389439953168484)}, {UINT64CONST(17058344360286875914), UINT64CONST(173111551962534787)},
+ {UINT64CONST(12535955717491360170), UINT64CONST(276978483140055660)}, {UINT64CONST(10028764573993088136), UINT64CONST(221582786512044528)},
+ {UINT64CONST(15401709288678291155), UINT64CONST(177266229209635622)}, {UINT64CONST(9885339602917624555), UINT64CONST(283625966735416996)},
+ {UINT64CONST(4218922867592189321), UINT64CONST(226900773388333597)}, {UINT64CONST(14443184738299482427), UINT64CONST(181520618710666877)},
+ {UINT64CONST(4175850161155765295), UINT64CONST(145216494968533502)}, {UINT64CONST(10370709072591134795), UINT64CONST(232346391949653603)},
+ {UINT64CONST(15675264887556728482), UINT64CONST(185877113559722882)}, {UINT64CONST(5161514280561562140), UINT64CONST(148701690847778306)},
+ {UINT64CONST(879725219414678777), UINT64CONST(237922705356445290)}, {UINT64CONST(703780175531743021), UINT64CONST(190338164285156232)},
+ {UINT64CONST(11631070584651125387), UINT64CONST(152270531428124985)}, {UINT64CONST(162968861732249003), UINT64CONST(243632850284999977)},
+ {UINT64CONST(11198421533611530172), UINT64CONST(194906280227999981)}, {UINT64CONST(5269388412147313814), UINT64CONST(155925024182399985)},
+ {UINT64CONST(8431021459435702103), UINT64CONST(249480038691839976)}, {UINT64CONST(3055468352806651359), UINT64CONST(199584030953471981)},
+ {UINT64CONST(17201769941212962380), UINT64CONST(159667224762777584)}, {UINT64CONST(16454785461715008838), UINT64CONST(255467559620444135)},
+ {UINT64CONST(13163828369372007071), UINT64CONST(204374047696355308)}, {UINT64CONST(17909760324981426303), UINT64CONST(163499238157084246)},
+ {UINT64CONST(2830174816776909822), UINT64CONST(261598781051334795)}, {UINT64CONST(2264139853421527858), UINT64CONST(209279024841067836)},
+ {UINT64CONST(16568707141704863579), UINT64CONST(167423219872854268)}, {UINT64CONST(4373838538276319787), UINT64CONST(267877151796566830)},
+ {UINT64CONST(3499070830621055830), UINT64CONST(214301721437253464)}, {UINT64CONST(6488605479238754987), UINT64CONST(171441377149802771)},
+ {UINT64CONST(3003071137298187333), UINT64CONST(274306203439684434)}, {UINT64CONST(6091805724580460189), UINT64CONST(219444962751747547)},
+ {UINT64CONST(15941491023890099121), UINT64CONST(175555970201398037)}, {UINT64CONST(10748990379256517301), UINT64CONST(280889552322236860)},
+ {UINT64CONST(8599192303405213841), UINT64CONST(224711641857789488)}, {UINT64CONST(14258051472207991719), UINT64CONST(179769313486231590)}
+};
+
+static const uint64 DOUBLE_POW5_SPLIT[326][2] = {
+ {UINT64CONST(0), UINT64CONST(72057594037927936)}, {UINT64CONST(0), UINT64CONST(90071992547409920)},
+ {UINT64CONST(0), UINT64CONST(112589990684262400)}, {UINT64CONST(0), UINT64CONST(140737488355328000)},
+ {UINT64CONST(0), UINT64CONST(87960930222080000)}, {UINT64CONST(0), UINT64CONST(109951162777600000)},
+ {UINT64CONST(0), UINT64CONST(137438953472000000)}, {UINT64CONST(0), UINT64CONST(85899345920000000)},
+ {UINT64CONST(0), UINT64CONST(107374182400000000)}, {UINT64CONST(0), UINT64CONST(134217728000000000)},
+ {UINT64CONST(0), UINT64CONST(83886080000000000)}, {UINT64CONST(0), UINT64CONST(104857600000000000)},
+ {UINT64CONST(0), UINT64CONST(131072000000000000)}, {UINT64CONST(0), UINT64CONST(81920000000000000)},
+ {UINT64CONST(0), UINT64CONST(102400000000000000)}, {UINT64CONST(0), UINT64CONST(128000000000000000)},
+ {UINT64CONST(0), UINT64CONST(80000000000000000)}, {UINT64CONST(0), UINT64CONST(100000000000000000)},
+ {UINT64CONST(0), UINT64CONST(125000000000000000)}, {UINT64CONST(0), UINT64CONST(78125000000000000)},
+ {UINT64CONST(0), UINT64CONST(97656250000000000)}, {UINT64CONST(0), UINT64CONST(122070312500000000)},
+ {UINT64CONST(0), UINT64CONST(76293945312500000)}, {UINT64CONST(0), UINT64CONST(95367431640625000)},
+ {UINT64CONST(0), UINT64CONST(119209289550781250)}, {UINT64CONST(4611686018427387904), UINT64CONST(74505805969238281)},
+ {UINT64CONST(10376293541461622784), UINT64CONST(93132257461547851)}, {UINT64CONST(8358680908399640576), UINT64CONST(116415321826934814)},
+ {UINT64CONST(612489549322387456), UINT64CONST(72759576141834259)}, {UINT64CONST(14600669991935148032), UINT64CONST(90949470177292823)},
+ {UINT64CONST(13639151471491547136), UINT64CONST(113686837721616029)}, {UINT64CONST(3213881284082270208), UINT64CONST(142108547152020037)},
+ {UINT64CONST(4314518811765112832), UINT64CONST(88817841970012523)}, {UINT64CONST(781462496279003136), UINT64CONST(111022302462515654)},
+ {UINT64CONST(10200200157203529728), UINT64CONST(138777878078144567)}, {UINT64CONST(13292654125893287936), UINT64CONST(86736173798840354)},
+ {UINT64CONST(7392445620511834112), UINT64CONST(108420217248550443)}, {UINT64CONST(4628871007212404736), UINT64CONST(135525271560688054)},
+ {UINT64CONST(16728102434789916672), UINT64CONST(84703294725430033)}, {UINT64CONST(7075069988205232128), UINT64CONST(105879118406787542)},
+ {UINT64CONST(18067209522111315968), UINT64CONST(132348898008484427)}, {UINT64CONST(8986162942105878528), UINT64CONST(82718061255302767)},
+ {UINT64CONST(6621017659204960256), UINT64CONST(103397576569128459)}, {UINT64CONST(3664586055578812416), UINT64CONST(129246970711410574)},
+ {UINT64CONST(16125424340018921472), UINT64CONST(80779356694631608)}, {UINT64CONST(1710036351314100224), UINT64CONST(100974195868289511)},
+ {UINT64CONST(15972603494424788992), UINT64CONST(126217744835361888)}, {UINT64CONST(9982877184015493120), UINT64CONST(78886090522101180)},
+ {UINT64CONST(12478596480019366400), UINT64CONST(98607613152626475)}, {UINT64CONST(10986559581596820096), UINT64CONST(123259516440783094)},
+ {UINT64CONST(2254913720070624656), UINT64CONST(77037197775489434)}, {UINT64CONST(12042014186943056628), UINT64CONST(96296497219361792)},
+ {UINT64CONST(15052517733678820785), UINT64CONST(120370621524202240)}, {UINT64CONST(9407823583549262990), UINT64CONST(75231638452626400)},
+ {UINT64CONST(11759779479436578738), UINT64CONST(94039548065783000)}, {UINT64CONST(14699724349295723422), UINT64CONST(117549435082228750)},
+ {UINT64CONST(4575641699882439235), UINT64CONST(73468396926392969)}, {UINT64CONST(10331238143280436948), UINT64CONST(91835496157991211)},
+ {UINT64CONST(8302361660673158281), UINT64CONST(114794370197489014)}, {UINT64CONST(1154580038986672043), UINT64CONST(143492962746861268)},
+ {UINT64CONST(9944984561221445835), UINT64CONST(89683101716788292)}, {UINT64CONST(12431230701526807293), UINT64CONST(112103877145985365)},
+ {UINT64CONST(1703980321626345405), UINT64CONST(140129846432481707)}, {UINT64CONST(17205888765512323542), UINT64CONST(87581154020301066)},
+ {UINT64CONST(12283988920035628619), UINT64CONST(109476442525376333)}, {UINT64CONST(1519928094762372062), UINT64CONST(136845553156720417)},
+ {UINT64CONST(12479170105294952299), UINT64CONST(85528470722950260)}, {UINT64CONST(15598962631618690374), UINT64CONST(106910588403687825)},
+ {UINT64CONST(5663645234241199255), UINT64CONST(133638235504609782)}, {UINT64CONST(17374836326682913246), UINT64CONST(83523897190381113)},
+ {UINT64CONST(7883487353071477846), UINT64CONST(104404871487976392)}, {UINT64CONST(9854359191339347308), UINT64CONST(130506089359970490)},
+ {UINT64CONST(10770660513014479971), UINT64CONST(81566305849981556)}, {UINT64CONST(13463325641268099964), UINT64CONST(101957882312476945)},
+ {UINT64CONST(2994098996302961243), UINT64CONST(127447352890596182)}, {UINT64CONST(15706369927971514489), UINT64CONST(79654595556622613)},
+ {UINT64CONST(5797904354682229399), UINT64CONST(99568244445778267)}, {UINT64CONST(2635694424925398845), UINT64CONST(124460305557222834)},
+ {UINT64CONST(6258995034005762182), UINT64CONST(77787690973264271)}, {UINT64CONST(3212057774079814824), UINT64CONST(97234613716580339)},
+ {UINT64CONST(17850130272881932242), UINT64CONST(121543267145725423)}, {UINT64CONST(18073860448192289507), UINT64CONST(75964541966078389)},
+ {UINT64CONST(8757267504958198172), UINT64CONST(94955677457597987)}, {UINT64CONST(6334898362770359811), UINT64CONST(118694596821997484)},
+ {UINT64CONST(13182683513586250689), UINT64CONST(74184123013748427)}, {UINT64CONST(11866668373555425458), UINT64CONST(92730153767185534)},
+ {UINT64CONST(5609963430089506015), UINT64CONST(115912692208981918)}, {UINT64CONST(17341285199088104971), UINT64CONST(72445432630613698)},
+ {UINT64CONST(12453234462005355406), UINT64CONST(90556790788267123)}, {UINT64CONST(10954857059079306353), UINT64CONST(113195988485333904)},
+ {UINT64CONST(13693571323849132942), UINT64CONST(141494985606667380)}, {UINT64CONST(17781854114260483896), UINT64CONST(88434366004167112)},
+ {UINT64CONST(3780573569116053255), UINT64CONST(110542957505208891)}, {UINT64CONST(114030942967678664), UINT64CONST(138178696881511114)},
+ {UINT64CONST(4682955357782187069), UINT64CONST(86361685550944446)}, {UINT64CONST(15077066234082509644), UINT64CONST(107952106938680557)},
+ {UINT64CONST(5011274737320973344), UINT64CONST(134940133673350697)}, {UINT64CONST(14661261756894078100), UINT64CONST(84337583545844185)},
+ {UINT64CONST(4491519140835433913), UINT64CONST(105421979432305232)}, {UINT64CONST(5614398926044292391), UINT64CONST(131777474290381540)},
+ {UINT64CONST(12732371365632458552), UINT64CONST(82360921431488462)}, {UINT64CONST(6692092170185797382), UINT64CONST(102951151789360578)},
+ {UINT64CONST(17588487249587022536), UINT64CONST(128688939736700722)}, {UINT64CONST(15604490549419276989), UINT64CONST(80430587335437951)},
+ {UINT64CONST(14893927168346708332), UINT64CONST(100538234169297439)}, {UINT64CONST(14005722942005997511), UINT64CONST(125672792711621799)},
+ {UINT64CONST(15671105866394830300), UINT64CONST(78545495444763624)}, {UINT64CONST(1142138259283986260), UINT64CONST(98181869305954531)},
+ {UINT64CONST(15262730879387146537), UINT64CONST(122727336632443163)}, {UINT64CONST(7233363790403272633), UINT64CONST(76704585395276977)},
+ {UINT64CONST(13653390756431478696), UINT64CONST(95880731744096221)}, {UINT64CONST(3231680390257184658), UINT64CONST(119850914680120277)},
+ {UINT64CONST(4325643253124434363), UINT64CONST(74906821675075173)}, {UINT64CONST(10018740084832930858), UINT64CONST(93633527093843966)},
+ {UINT64CONST(3300053069186387764), UINT64CONST(117041908867304958)}, {UINT64CONST(15897591223523656064), UINT64CONST(73151193042065598)},
+ {UINT64CONST(10648616992549794273), UINT64CONST(91438991302581998)}, {UINT64CONST(4087399203832467033), UINT64CONST(114298739128227498)},
+ {UINT64CONST(14332621041645359599), UINT64CONST(142873423910284372)}, {UINT64CONST(18181260187883125557), UINT64CONST(89295889943927732)},
+ {UINT64CONST(4279831161144355331), UINT64CONST(111619862429909666)}, {UINT64CONST(14573160988285219972), UINT64CONST(139524828037387082)},
+ {UINT64CONST(13719911636105650386), UINT64CONST(87203017523366926)}, {UINT64CONST(7926517508277287175), UINT64CONST(109003771904208658)},
+ {UINT64CONST(684774848491833161), UINT64CONST(136254714880260823)}, {UINT64CONST(7345513307948477581), UINT64CONST(85159196800163014)},
+ {UINT64CONST(18405263671790372785), UINT64CONST(106448996000203767)}, {UINT64CONST(18394893571310578077), UINT64CONST(133061245000254709)},
+ {UINT64CONST(13802651491282805250), UINT64CONST(83163278125159193)}, {UINT64CONST(3418256308821342851), UINT64CONST(103954097656448992)},
+ {UINT64CONST(4272820386026678563), UINT64CONST(129942622070561240)}, {UINT64CONST(2670512741266674102), UINT64CONST(81214138794100775)},
+ {UINT64CONST(17173198981865506339), UINT64CONST(101517673492625968)}, {UINT64CONST(3019754653622331308), UINT64CONST(126897091865782461)},
+ {UINT64CONST(4193189667727651020), UINT64CONST(79310682416114038)}, {UINT64CONST(14464859121514339583), UINT64CONST(99138353020142547)},
+ {UINT64CONST(13469387883465536574), UINT64CONST(123922941275178184)}, {UINT64CONST(8418367427165960359), UINT64CONST(77451838296986365)},
+ {UINT64CONST(15134645302384838353), UINT64CONST(96814797871232956)}, {UINT64CONST(471562554271496325), UINT64CONST(121018497339041196)},
+ {UINT64CONST(9518098633274461011), UINT64CONST(75636560836900747)}, {UINT64CONST(7285937273165688360), UINT64CONST(94545701046125934)},
+ {UINT64CONST(18330793628311886258), UINT64CONST(118182126307657417)}, {UINT64CONST(4539216990053847055), UINT64CONST(73863828942285886)},
+ {UINT64CONST(14897393274422084627), UINT64CONST(92329786177857357)}, {UINT64CONST(4786683537745442072), UINT64CONST(115412232722321697)},
+ {UINT64CONST(14520892257159371055), UINT64CONST(72132645451451060)}, {UINT64CONST(18151115321449213818), UINT64CONST(90165806814313825)},
+ {UINT64CONST(8853836096529353561), UINT64CONST(112707258517892282)}, {UINT64CONST(1843923083806916143), UINT64CONST(140884073147365353)},
+ {UINT64CONST(12681666973447792349), UINT64CONST(88052545717103345)}, {UINT64CONST(2017025661527576725), UINT64CONST(110065682146379182)},
+ {UINT64CONST(11744654113764246714), UINT64CONST(137582102682973977)}, {UINT64CONST(422879793461572340), UINT64CONST(85988814176858736)},
+ {UINT64CONST(528599741826965425), UINT64CONST(107486017721073420)}, {UINT64CONST(660749677283706782), UINT64CONST(134357522151341775)},
+ {UINT64CONST(7330497575943398595), UINT64CONST(83973451344588609)}, {UINT64CONST(13774807988356636147), UINT64CONST(104966814180735761)},
+ {UINT64CONST(3383451930163631472), UINT64CONST(131208517725919702)}, {UINT64CONST(15949715511634433382), UINT64CONST(82005323578699813)},
+ {UINT64CONST(6102086334260878016), UINT64CONST(102506654473374767)}, {UINT64CONST(3015921899398709616), UINT64CONST(128133318091718459)},
+ {UINT64CONST(18025852251620051174), UINT64CONST(80083323807324036)}, {UINT64CONST(4085571240815512351), UINT64CONST(100104154759155046)},
+ {UINT64CONST(14330336087874166247), UINT64CONST(125130193448943807)}, {UINT64CONST(15873989082562435760), UINT64CONST(78206370905589879)},
+ {UINT64CONST(15230800334775656796), UINT64CONST(97757963631987349)}, {UINT64CONST(5203442363187407284), UINT64CONST(122197454539984187)},
+ {UINT64CONST(946308467778435600), UINT64CONST(76373409087490117)}, {UINT64CONST(5794571603150432404), UINT64CONST(95466761359362646)},
+ {UINT64CONST(16466586540792816313), UINT64CONST(119333451699203307)}, {UINT64CONST(7985773578781816244), UINT64CONST(74583407312002067)},
+ {UINT64CONST(5370530955049882401), UINT64CONST(93229259140002584)}, {UINT64CONST(6713163693812353001), UINT64CONST(116536573925003230)},
+ {UINT64CONST(18030785363914884337), UINT64CONST(72835358703127018)}, {UINT64CONST(13315109668038829614), UINT64CONST(91044198378908773)},
+ {UINT64CONST(2808829029766373305), UINT64CONST(113805247973635967)}, {UINT64CONST(17346094342490130344), UINT64CONST(142256559967044958)},
+ {UINT64CONST(6229622945628943561), UINT64CONST(88910349979403099)}, {UINT64CONST(3175342663608791547), UINT64CONST(111137937474253874)},
+ {UINT64CONST(13192550366365765242), UINT64CONST(138922421842817342)}, {UINT64CONST(3633657960551215372), UINT64CONST(86826513651760839)},
+ {UINT64CONST(18377130505971182927), UINT64CONST(108533142064701048)}, {UINT64CONST(4524669058754427043), UINT64CONST(135666427580876311)},
+ {UINT64CONST(9745447189362598758), UINT64CONST(84791517238047694)}, {UINT64CONST(2958436949848472639), UINT64CONST(105989396547559618)},
+ {UINT64CONST(12921418224165366607), UINT64CONST(132486745684449522)}, {UINT64CONST(12687572408530742033), UINT64CONST(82804216052780951)},
+ {UINT64CONST(11247779492236039638), UINT64CONST(103505270065976189)}, {UINT64CONST(224666310012885835), UINT64CONST(129381587582470237)},
+ {UINT64CONST(2446259452971747599), UINT64CONST(80863492239043898)}, {UINT64CONST(12281196353069460307), UINT64CONST(101079365298804872)},
+ {UINT64CONST(15351495441336825384), UINT64CONST(126349206623506090)}, {UINT64CONST(14206370669262903769), UINT64CONST(78968254139691306)},
+ {UINT64CONST(8534591299723853903), UINT64CONST(98710317674614133)}, {UINT64CONST(15279925143082205283), UINT64CONST(123387897093267666)},
+ {UINT64CONST(14161639232853766206), UINT64CONST(77117435683292291)}, {UINT64CONST(13090363022639819853), UINT64CONST(96396794604115364)},
+ {UINT64CONST(16362953778299774816), UINT64CONST(120495993255144205)}, {UINT64CONST(12532689120651053212), UINT64CONST(75309995784465128)},
+ {UINT64CONST(15665861400813816515), UINT64CONST(94137494730581410)}, {UINT64CONST(10358954714162494836), UINT64CONST(117671868413226763)},
+ {UINT64CONST(4168503687137865320), UINT64CONST(73544917758266727)}, {UINT64CONST(598943590494943747), UINT64CONST(91931147197833409)},
+ {UINT64CONST(5360365506546067587), UINT64CONST(114913933997291761)}, {UINT64CONST(11312142901609972388), UINT64CONST(143642417496614701)},
+ {UINT64CONST(9375932322719926695), UINT64CONST(89776510935384188)}, {UINT64CONST(11719915403399908368), UINT64CONST(112220638669230235)},
+ {UINT64CONST(10038208235822497557), UINT64CONST(140275798336537794)}, {UINT64CONST(10885566165816448877), UINT64CONST(87672373960336121)},
+ {UINT64CONST(18218643725697949000), UINT64CONST(109590467450420151)}, {UINT64CONST(18161618638695048346), UINT64CONST(136988084313025189)},
+ {UINT64CONST(13656854658398099168), UINT64CONST(85617552695640743)}, {UINT64CONST(12459382304570236056), UINT64CONST(107021940869550929)},
+ {UINT64CONST(1739169825430631358), UINT64CONST(133777426086938662)}, {UINT64CONST(14922039196176308311), UINT64CONST(83610891304336663)},
+ {UINT64CONST(14040862976792997485), UINT64CONST(104513614130420829)}, {UINT64CONST(3716020665709083144), UINT64CONST(130642017663026037)},
+ {UINT64CONST(4628355925281870917), UINT64CONST(81651261039391273)}, {UINT64CONST(10397130925029726550), UINT64CONST(102064076299239091)},
+ {UINT64CONST(8384727637859770284), UINT64CONST(127580095374048864)}, {UINT64CONST(5240454773662356427), UINT64CONST(79737559608780540)},
+ {UINT64CONST(6550568467077945534), UINT64CONST(99671949510975675)}, {UINT64CONST(3576524565420044014), UINT64CONST(124589936888719594)},
+ {UINT64CONST(6847013871814915412), UINT64CONST(77868710555449746)}, {UINT64CONST(17782139376623420074), UINT64CONST(97335888194312182)},
+ {UINT64CONST(13004302183924499284), UINT64CONST(121669860242890228)}, {UINT64CONST(17351060901807587860), UINT64CONST(76043662651806392)},
+ {UINT64CONST(3242082053549933210), UINT64CONST(95054578314757991)}, {UINT64CONST(17887660622219580224), UINT64CONST(118818222893447488)},
+ {UINT64CONST(11179787888887237640), UINT64CONST(74261389308404680)}, {UINT64CONST(13974734861109047050), UINT64CONST(92826736635505850)},
+ {UINT64CONST(8245046539531533005), UINT64CONST(116033420794382313)}, {UINT64CONST(16682369133275677888), UINT64CONST(72520887996488945)},
+ {UINT64CONST(7017903361312433648), UINT64CONST(90651109995611182)}, {UINT64CONST(17995751238495317868), UINT64CONST(113313887494513977)},
+ {UINT64CONST(8659630992836983623), UINT64CONST(141642359368142472)}, {UINT64CONST(5412269370523114764), UINT64CONST(88526474605089045)},
+ {UINT64CONST(11377022731581281359), UINT64CONST(110658093256361306)}, {UINT64CONST(4997906377621825891), UINT64CONST(138322616570451633)},
+ {UINT64CONST(14652906532082110942), UINT64CONST(86451635356532270)}, {UINT64CONST(9092761128247862869), UINT64CONST(108064544195665338)},
+ {UINT64CONST(2142579373455052779), UINT64CONST(135080680244581673)}, {UINT64CONST(12868327154477877747), UINT64CONST(84425425152863545)},
+ {UINT64CONST(2250350887815183471), UINT64CONST(105531781441079432)}, {UINT64CONST(2812938609768979339), UINT64CONST(131914726801349290)},
+ {UINT64CONST(6369772649532999991), UINT64CONST(82446704250843306)}, {UINT64CONST(17185587848771025797), UINT64CONST(103058380313554132)},
+ {UINT64CONST(3035240737254230630), UINT64CONST(128822975391942666)}, {UINT64CONST(6508711479211282048), UINT64CONST(80514359619964166)},
+ {UINT64CONST(17359261385868878368), UINT64CONST(100642949524955207)}, {UINT64CONST(17087390713908710056), UINT64CONST(125803686906194009)},
+ {UINT64CONST(3762090168551861929), UINT64CONST(78627304316371256)}, {UINT64CONST(4702612710689827411), UINT64CONST(98284130395464070)},
+ {UINT64CONST(15101637925217060072), UINT64CONST(122855162994330087)}, {UINT64CONST(16356052730901744401), UINT64CONST(76784476871456304)},
+ {UINT64CONST(1998321839917628885), UINT64CONST(95980596089320381)}, {UINT64CONST(7109588318324424010), UINT64CONST(119975745111650476)},
+ {UINT64CONST(13666864735807540814), UINT64CONST(74984840694781547)}, {UINT64CONST(12471894901332038114), UINT64CONST(93731050868476934)},
+ {UINT64CONST(6366496589810271835), UINT64CONST(117163813585596168)}, {UINT64CONST(3979060368631419896), UINT64CONST(73227383490997605)},
+ {UINT64CONST(9585511479216662775), UINT64CONST(91534229363747006)}, {UINT64CONST(2758517312166052660), UINT64CONST(114417786704683758)},
+ {UINT64CONST(12671518677062341634), UINT64CONST(143022233380854697)}, {UINT64CONST(1002170145522881665), UINT64CONST(89388895863034186)},
+ {UINT64CONST(10476084718758377889), UINT64CONST(111736119828792732)}, {UINT64CONST(13095105898447972362), UINT64CONST(139670149785990915)},
+ {UINT64CONST(5878598177316288774), UINT64CONST(87293843616244322)}, {UINT64CONST(16571619758500136775), UINT64CONST(109117304520305402)},
+ {UINT64CONST(11491152661270395161), UINT64CONST(136396630650381753)}, {UINT64CONST(264441385652915120), UINT64CONST(85247894156488596)},
+ {UINT64CONST(330551732066143900), UINT64CONST(106559867695610745)}, {UINT64CONST(5024875683510067779), UINT64CONST(133199834619513431)},
+ {UINT64CONST(10058076329834874218), UINT64CONST(83249896637195894)}, {UINT64CONST(3349223375438816964), UINT64CONST(104062370796494868)},
+ {UINT64CONST(4186529219298521205), UINT64CONST(130077963495618585)}, {UINT64CONST(14145795808130045513), UINT64CONST(81298727184761615)},
+ {UINT64CONST(13070558741735168987), UINT64CONST(101623408980952019)}, {UINT64CONST(11726512408741573330), UINT64CONST(127029261226190024)},
+ {UINT64CONST(7329070255463483331), UINT64CONST(79393288266368765)}, {UINT64CONST(13773023837756742068), UINT64CONST(99241610332960956)},
+ {UINT64CONST(17216279797195927585), UINT64CONST(124052012916201195)}, {UINT64CONST(8454331864033760789), UINT64CONST(77532508072625747)},
+ {UINT64CONST(5956228811614813082), UINT64CONST(96915635090782184)}, {UINT64CONST(7445286014518516353), UINT64CONST(121144543863477730)},
+ {UINT64CONST(9264989777501460624), UINT64CONST(75715339914673581)}, {UINT64CONST(16192923240304213684), UINT64CONST(94644174893341976)},
+ {UINT64CONST(1794409976670715490), UINT64CONST(118305218616677471)}, {UINT64CONST(8039035263060279037), UINT64CONST(73940761635423419)},
+ {UINT64CONST(5437108060397960892), UINT64CONST(92425952044279274)}, {UINT64CONST(16019757112352226923), UINT64CONST(115532440055349092)},
+ {UINT64CONST(788976158365366019), UINT64CONST(72207775034593183)}, {UINT64CONST(14821278253238871236), UINT64CONST(90259718793241478)},
+ {UINT64CONST(9303225779693813237), UINT64CONST(112824648491551848)}, {UINT64CONST(11629032224617266546), UINT64CONST(141030810614439810)},
+ {UINT64CONST(11879831158813179495), UINT64CONST(88144256634024881)}, {UINT64CONST(1014730893234310657), UINT64CONST(110180320792531102)},
+ {UINT64CONST(10491785653397664129), UINT64CONST(137725400990663877)}, {UINT64CONST(8863209042587234033), UINT64CONST(86078375619164923)},
+ {UINT64CONST(6467325284806654637), UINT64CONST(107597969523956154)}, {UINT64CONST(17307528642863094104), UINT64CONST(134497461904945192)},
+ {UINT64CONST(10817205401789433815), UINT64CONST(84060913690590745)}, {UINT64CONST(18133192770664180173), UINT64CONST(105076142113238431)},
+ {UINT64CONST(18054804944902837312), UINT64CONST(131345177641548039)}, {UINT64CONST(18201782118205355176), UINT64CONST(82090736025967524)},
+ {UINT64CONST(4305483574047142354), UINT64CONST(102613420032459406)}, {UINT64CONST(14605226504413703751), UINT64CONST(128266775040574257)},
+ {UINT64CONST(2210737537617482988), UINT64CONST(80166734400358911)}, {UINT64CONST(16598479977304017447), UINT64CONST(100208418000448638)},
+ {UINT64CONST(11524727934775246001), UINT64CONST(125260522500560798)}, {UINT64CONST(2591268940807140847), UINT64CONST(78287826562850499)},
+ {UINT64CONST(17074144231291089770), UINT64CONST(97859783203563123)}, {UINT64CONST(16730994270686474309), UINT64CONST(122324729004453904)},
+ {UINT64CONST(10456871419179046443), UINT64CONST(76452955627783690)}, {UINT64CONST(3847717237119032246), UINT64CONST(95566194534729613)},
+ {UINT64CONST(9421332564826178211), UINT64CONST(119457743168412016)}, {UINT64CONST(5888332853016361382), UINT64CONST(74661089480257510)},
+ {UINT64CONST(16583788103125227536), UINT64CONST(93326361850321887)}, {UINT64CONST(16118049110479146516), UINT64CONST(116657952312902359)},
+ {UINT64CONST(16991309721690548428), UINT64CONST(72911220195563974)}, {UINT64CONST(12015765115258409727), UINT64CONST(91139025244454968)},
+ {UINT64CONST(15019706394073012159), UINT64CONST(113923781555568710)}, {UINT64CONST(9551260955736489391), UINT64CONST(142404726944460888)},
+ {UINT64CONST(5969538097335305869), UINT64CONST(89002954340288055)}, {UINT64CONST(2850236603241744433), UINT64CONST(111253692925360069)}
+};
+
+#endif /* RYU_D2S_FULL_TABLE_H */
diff --git a/src/common/d2s_intrinsics.h b/src/common/d2s_intrinsics.h
new file mode 100644
index 0000000000..248889e649
--- /dev/null
+++ b/src/common/d2s_intrinsics.h
@@ -0,0 +1,202 @@
+/*---------------------------------------------------------------------------
+ *
+ * Ryu floating-point output for double precision.
+ *
+ * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/d2s_intrinsics.h
+ *
+ * This is a modification of code taken from github.com/ulfjack/ryu under the
+ * terms of the Boost license (not the Apache license). The original copyright
+ * notice follows:
+ *
+ * Copyright 2018 Ulf Adams
+ *
+ * The contents of this file may be used under the terms of the Apache
+ * License, Version 2.0.
+ *
+ * (See accompanying file LICENSE-Apache or copy at
+ * http://www.apache.org/licenses/LICENSE-2.0)
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * Boost Software License, Version 1.0.
+ *
+ * (See accompanying file LICENSE-Boost or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Unless required by applicable law or agreed to in writing, this software is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.
+ *
+ *---------------------------------------------------------------------------
+ */
+#ifndef RYU_D2S_INTRINSICS_H
+#define RYU_D2S_INTRINSICS_H
+
+#if defined(HAS_64_BIT_INTRINSICS)
+
+#include
+
+static inline uint64
+umul128(const uint64 a, const uint64 b, uint64 *const productHi)
+{
+ return _umul128(a, b, productHi);
+}
+
+static inline uint64
+shiftright128(const uint64 lo, const uint64 hi, const uint32 dist)
+{
+ /*
+ * For the __shiftright128 intrinsic, the shift value is always modulo 64.
+ * In the current implementation of the double-precision version of Ryu,
+ * the shift value is always < 64. (In the case RYU_OPTIMIZE_SIZE == 0,
+ * the shift value is in the range [49, 58]. Otherwise in the range [2,
+ * 59].) Check this here in case a future change requires larger shift
+ * values. In this case this function needs to be adjusted.
+ */
+ Assert(dist < 64);
+ return __shiftright128(lo, hi, (unsigned char) dist);
+}
+
+#else /* defined(HAS_64_BIT_INTRINSICS) */
+
+static inline uint64
+umul128(const uint64 a, const uint64 b, uint64 *const productHi)
+{
+ /*
+ * The casts here help MSVC to avoid calls to the __allmul library
+ * function.
+ */
+ const uint32 aLo = (uint32) a;
+ const uint32 aHi = (uint32) (a >> 32);
+ const uint32 bLo = (uint32) b;
+ const uint32 bHi = (uint32) (b >> 32);
+
+ const uint64 b00 = (uint64) aLo * bLo;
+ const uint64 b01 = (uint64) aLo * bHi;
+ const uint64 b10 = (uint64) aHi * bLo;
+ const uint64 b11 = (uint64) aHi * bHi;
+
+ const uint32 b00Lo = (uint32) b00;
+ const uint32 b00Hi = (uint32) (b00 >> 32);
+
+ const uint64 mid1 = b10 + b00Hi;
+ const uint32 mid1Lo = (uint32) (mid1);
+ const uint32 mid1Hi = (uint32) (mid1 >> 32);
+
+ const uint64 mid2 = b01 + mid1Lo;
+ const uint32 mid2Lo = (uint32) (mid2);
+ const uint32 mid2Hi = (uint32) (mid2 >> 32);
+
+ const uint64 pHi = b11 + mid1Hi + mid2Hi;
+ const uint64 pLo = ((uint64) mid2Lo << 32) + b00Lo;
+
+ *productHi = pHi;
+ return pLo;
+}
+
+static inline uint64
+shiftright128(const uint64 lo, const uint64 hi, const uint32 dist)
+{
+ /* We don't need to handle the case dist >= 64 here (see above). */
+ Assert(dist < 64);
+#if !defined(RYU_32_BIT_PLATFORM)
+ Assert(dist > 0);
+ return (hi << (64 - dist)) | (lo >> dist);
+#else
+ /* Avoid a 64-bit shift by taking advantage of the range of shift values. */
+ Assert(dist >= 32);
+ return (hi << (64 - dist)) | ((uint32) (lo >> 32) >> (dist - 32));
+#endif
+}
+
+#endif /* // defined(HAS_64_BIT_INTRINSICS) */
+
+#ifdef RYU_32_BIT_PLATFORM
+
+/* Returns the high 64 bits of the 128-bit product of a and b. */
+static inline uint64
+umulh(const uint64 a, const uint64 b)
+{
+ /*
+ * Reuse the umul128 implementation. Optimizers will likely eliminate the
+ * instructions used to compute the low part of the product.
+ */
+ uint64 hi;
+
+ umul128(a, b, &hi);
+ return hi;
+}
+
+/*----
+ * On 32-bit platforms, compilers typically generate calls to library
+ * functions for 64-bit divisions, even if the divisor is a constant.
+ *
+ * E.g.:
+ * https://bugs.llvm.org/show_bug.cgi?id=37932
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17958
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37443
+ *
+ * The functions here perform division-by-constant using multiplications
+ * in the same way as 64-bit compilers would do.
+ *
+ * NB:
+ * The multipliers and shift values are the ones generated by clang x64
+ * for expressions like x/5, x/10, etc.
+ *----
+ */
+
+static inline uint64
+div5(const uint64 x)
+{
+ return umulh(x, UINT64CONST(0xCCCCCCCCCCCCCCCD)) >> 2;
+}
+
+static inline uint64
+div10(const uint64 x)
+{
+ return umulh(x, UINT64CONST(0xCCCCCCCCCCCCCCCD)) >> 3;
+}
+
+static inline uint64
+div100(const uint64 x)
+{
+ return umulh(x >> 2, UINT64CONST(0x28F5C28F5C28F5C3)) >> 2;
+}
+
+static inline uint64
+div1e8(const uint64 x)
+{
+ return umulh(x, UINT64CONST(0xABCC77118461CEFD)) >> 26;
+}
+
+#else /* RYU_32_BIT_PLATFORM */
+
+static inline uint64
+div5(const uint64 x)
+{
+ return x / 5;
+}
+
+static inline uint64
+div10(const uint64 x)
+{
+ return x / 10;
+}
+
+static inline uint64
+div100(const uint64 x)
+{
+ return x / 100;
+}
+
+static inline uint64
+div1e8(const uint64 x)
+{
+ return x / 100000000;
+}
+
+#endif /* RYU_32_BIT_PLATFORM */
+
+#endif /* RYU_D2S_INTRINSICS_H */
diff --git a/src/common/digit_table.h b/src/common/digit_table.h
new file mode 100644
index 0000000000..483aa17142
--- /dev/null
+++ b/src/common/digit_table.h
@@ -0,0 +1,21 @@
+#ifndef RYU_DIGIT_TABLE_H
+#define RYU_DIGIT_TABLE_H
+
+/*
+ * A table of all two-digit numbers. This is used to speed up decimal digit
+ * generation by copying pairs of digits into the final output.
+ */
+static const char DIGIT_TABLE[200] = {
+ '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',
+ '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',
+ '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
+ '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',
+ '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',
+ '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
+ '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',
+ '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',
+ '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
+ '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9'
+};
+
+#endif /* RYU_DIGIT_TABLE_H */
diff --git a/src/common/f2s.c b/src/common/f2s.c
new file mode 100644
index 0000000000..4f36e1a596
--- /dev/null
+++ b/src/common/f2s.c
@@ -0,0 +1,804 @@
+/*---------------------------------------------------------------------------
+ *
+ * Ryu floating-point output for single precision.
+ *
+ * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/f2s.c
+ *
+ * This is a modification of code taken from github.com/ulfjack/ryu under the
+ * terms of the Boost license (not the Apache license). The original copyright
+ * notice follows:
+ *
+ * Copyright 2018 Ulf Adams
+ *
+ * The contents of this file may be used under the terms of the Apache
+ * License, Version 2.0.
+ *
+ * (See accompanying file LICENSE-Apache or copy at
+ * http://www.apache.org/licenses/LICENSE-2.0)
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * Boost Software License, Version 1.0.
+ *
+ * (See accompanying file LICENSE-Boost or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Unless required by applicable law or agreed to in writing, this software is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
+
+#include "common/shortest_dec.h"
+
+#include "ryu_common.h"
+#include "digit_table.h"
+
+#define FLOAT_MANTISSA_BITS 23
+#define FLOAT_EXPONENT_BITS 8
+#define FLOAT_BIAS 127
+
+/*
+ * This table is generated (by the upstream) by PrintFloatLookupTable,
+ * and modified (by us) to add UINT64CONST.
+ */
+#define FLOAT_POW5_INV_BITCOUNT 59
+static const uint64 FLOAT_POW5_INV_SPLIT[31] = {
+ UINT64CONST(576460752303423489), UINT64CONST(461168601842738791), UINT64CONST(368934881474191033), UINT64CONST(295147905179352826),
+ UINT64CONST(472236648286964522), UINT64CONST(377789318629571618), UINT64CONST(302231454903657294), UINT64CONST(483570327845851670),
+ UINT64CONST(386856262276681336), UINT64CONST(309485009821345069), UINT64CONST(495176015714152110), UINT64CONST(396140812571321688),
+ UINT64CONST(316912650057057351), UINT64CONST(507060240091291761), UINT64CONST(405648192073033409), UINT64CONST(324518553658426727),
+ UINT64CONST(519229685853482763), UINT64CONST(415383748682786211), UINT64CONST(332306998946228969), UINT64CONST(531691198313966350),
+ UINT64CONST(425352958651173080), UINT64CONST(340282366920938464), UINT64CONST(544451787073501542), UINT64CONST(435561429658801234),
+ UINT64CONST(348449143727040987), UINT64CONST(557518629963265579), UINT64CONST(446014903970612463), UINT64CONST(356811923176489971),
+ UINT64CONST(570899077082383953), UINT64CONST(456719261665907162), UINT64CONST(365375409332725730)
+};
+#define FLOAT_POW5_BITCOUNT 61
+static const uint64 FLOAT_POW5_SPLIT[47] = {
+ UINT64CONST(1152921504606846976), UINT64CONST(1441151880758558720), UINT64CONST(1801439850948198400), UINT64CONST(2251799813685248000),
+ UINT64CONST(1407374883553280000), UINT64CONST(1759218604441600000), UINT64CONST(2199023255552000000), UINT64CONST(1374389534720000000),
+ UINT64CONST(1717986918400000000), UINT64CONST(2147483648000000000), UINT64CONST(1342177280000000000), UINT64CONST(1677721600000000000),
+ UINT64CONST(2097152000000000000), UINT64CONST(1310720000000000000), UINT64CONST(1638400000000000000), UINT64CONST(2048000000000000000),
+ UINT64CONST(1280000000000000000), UINT64CONST(1600000000000000000), UINT64CONST(2000000000000000000), UINT64CONST(1250000000000000000),
+ UINT64CONST(1562500000000000000), UINT64CONST(1953125000000000000), UINT64CONST(1220703125000000000), UINT64CONST(1525878906250000000),
+ UINT64CONST(1907348632812500000), UINT64CONST(1192092895507812500), UINT64CONST(1490116119384765625), UINT64CONST(1862645149230957031),
+ UINT64CONST(1164153218269348144), UINT64CONST(1455191522836685180), UINT64CONST(1818989403545856475), UINT64CONST(2273736754432320594),
+ UINT64CONST(1421085471520200371), UINT64CONST(1776356839400250464), UINT64CONST(2220446049250313080), UINT64CONST(1387778780781445675),
+ UINT64CONST(1734723475976807094), UINT64CONST(2168404344971008868), UINT64CONST(1355252715606880542), UINT64CONST(1694065894508600678),
+ UINT64CONST(2117582368135750847), UINT64CONST(1323488980084844279), UINT64CONST(1654361225106055349), UINT64CONST(2067951531382569187),
+ UINT64CONST(1292469707114105741), UINT64CONST(1615587133892632177), UINT64CONST(2019483917365790221)
+};
+
+static inline uint32
+pow5Factor(uint32 value)
+{
+ uint32 count = 0;
+
+ for (;;)
+ {
+ Assert(value != 0);
+ const uint32 q = value / 5;
+ const uint32 r = value % 5;
+
+ if (r != 0)
+ break;
+
+ value = q;
+ ++count;
+ }
+ return count;
+}
+
+/* Returns true if value is divisible by 5^p. */
+static inline bool
+multipleOfPowerOf5(const uint32 value, const uint32 p)
+{
+ return pow5Factor(value) >= p;
+}
+
+/* Returns true if value is divisible by 2^p. */
+static inline bool
+multipleOfPowerOf2(const uint32 value, const uint32 p)
+{
+ /* return __builtin_ctz(value) >= p; */
+ return (value & ((1u << p) - 1)) == 0;
+}
+
+/*
+ * It seems to be slightly faster to avoid uint128_t here, although the
+ * generated code for uint128_t looks slightly nicer.
+ */
+static inline uint32
+mulShift(const uint32 m, const uint64 factor, const int32 shift)
+{
+ /*
+ * The casts here help MSVC to avoid calls to the __allmul library
+ * function.
+ */
+ const uint32 factorLo = (uint32) (factor);
+ const uint32 factorHi = (uint32) (factor >> 32);
+ const uint64 bits0 = (uint64) m * factorLo;
+ const uint64 bits1 = (uint64) m * factorHi;
+
+ Assert(shift > 32);
+
+#ifdef RYU_32_BIT_PLATFORM
+
+ /*
+ * On 32-bit platforms we can avoid a 64-bit shift-right since we only
+ * need the upper 32 bits of the result and the shift value is > 32.
+ */
+ const uint32 bits0Hi = (uint32) (bits0 >> 32);
+ uint32 bits1Lo = (uint32) (bits1);
+ uint32 bits1Hi = (uint32) (bits1 >> 32);
+
+ bits1Lo += bits0Hi;
+ bits1Hi += (bits1Lo < bits0Hi);
+
+ const int32 s = shift - 32;
+
+ return (bits1Hi << (32 - s)) | (bits1Lo >> s);
+
+#else /* RYU_32_BIT_PLATFORM */
+
+ const uint64 sum = (bits0 >> 32) + bits1;
+ const uint64 shiftedSum = sum >> (shift - 32);
+
+ Assert(shiftedSum <= UINT32_MAX);
+ return (uint32) shiftedSum;
+
+#endif /* RYU_32_BIT_PLATFORM */
+}
+
+static inline uint32
+mulPow5InvDivPow2(const uint32 m, const uint32 q, const int32 j)
+{
+ return mulShift(m, FLOAT_POW5_INV_SPLIT[q], j);
+}
+
+static inline uint32
+mulPow5divPow2(const uint32 m, const uint32 i, const int32 j)
+{
+ return mulShift(m, FLOAT_POW5_SPLIT[i], j);
+}
+
+static inline uint32
+decimalLength(const uint32 v)
+{
+ /* Function precondition: v is not a 10-digit number. */
+ /* (9 digits are sufficient for round-tripping.) */
+ Assert(v < 1000000000);
+ if (v >= 100000000)
+ {
+ return 9;
+ }
+ if (v >= 10000000)
+ {
+ return 8;
+ }
+ if (v >= 1000000)
+ {
+ return 7;
+ }
+ if (v >= 100000)
+ {
+ return 6;
+ }
+ if (v >= 10000)
+ {
+ return 5;
+ }
+ if (v >= 1000)
+ {
+ return 4;
+ }
+ if (v >= 100)
+ {
+ return 3;
+ }
+ if (v >= 10)
+ {
+ return 2;
+ }
+ return 1;
+}
+
+/* A floating decimal representing m * 10^e. */
+typedef struct floating_decimal_32
+{
+ uint32 mantissa;
+ int32 exponent;
+} floating_decimal_32;
+
+static inline floating_decimal_32
+f2d(const uint32 ieeeMantissa, const uint32 ieeeExponent)
+{
+ int32 e2;
+ uint32 m2;
+
+ if (ieeeExponent == 0)
+ {
+ /* We subtract 2 so that the bounds computation has 2 additional bits. */
+ e2 = 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2;
+ m2 = ieeeMantissa;
+ }
+ else
+ {
+ e2 = ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2;
+ m2 = (1u << FLOAT_MANTISSA_BITS) | ieeeMantissa;
+ }
+
+#if STRICTLY_SHORTEST
+ const bool even = (m2 & 1) == 0;
+ const bool acceptBounds = even;
+#else
+ const bool acceptBounds = false;
+#endif
+
+ /* Step 2: Determine the interval of legal decimal representations. */
+ const uint32 mv = 4 * m2;
+ const uint32 mp = 4 * m2 + 2;
+
+ /* Implicit bool -> int conversion. True is 1, false is 0. */
+ const uint32 mmShift = ieeeMantissa != 0 || ieeeExponent <= 1;
+ const uint32 mm = 4 * m2 - 1 - mmShift;
+
+ /* Step 3: Convert to a decimal power base using 64-bit arithmetic. */
+ uint32 vr,
+ vp,
+ vm;
+ int32 e10;
+ bool vmIsTrailingZeros = false;
+ bool vrIsTrailingZeros = false;
+ uint8 lastRemovedDigit = 0;
+
+ if (e2 >= 0)
+ {
+ const uint32 q = log10Pow2(e2);
+
+ e10 = q;
+
+ const int32 k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q) - 1;
+ const int32 i = -e2 + q + k;
+
+ vr = mulPow5InvDivPow2(mv, q, i);
+ vp = mulPow5InvDivPow2(mp, q, i);
+ vm = mulPow5InvDivPow2(mm, q, i);
+
+ if (q != 0 && (vp - 1) / 10 <= vm / 10)
+ {
+ /*
+ * We need to know one removed digit even if we are not going to
+ * loop below. We could use q = X - 1 above, except that would
+ * require 33 bits for the result, and we've found that 32-bit
+ * arithmetic is faster even on 64-bit machines.
+ */
+ const int32 l = FLOAT_POW5_INV_BITCOUNT + pow5bits(q - 1) - 1;
+
+ lastRemovedDigit = (uint8) (mulPow5InvDivPow2(mv, q - 1, -e2 + q - 1 + l) % 10);
+ }
+ if (q <= 9)
+ {
+ /*
+ * The largest power of 5 that fits in 24 bits is 5^10, but q <= 9
+ * seems to be safe as well.
+ *
+ * Only one of mp, mv, and mm can be a multiple of 5, if any.
+ */
+ if (mv % 5 == 0)
+ {
+ vrIsTrailingZeros = multipleOfPowerOf5(mv, q);
+ }
+ else if (acceptBounds)
+ {
+ vmIsTrailingZeros = multipleOfPowerOf5(mm, q);
+ }
+ else
+ {
+ vp -= multipleOfPowerOf5(mp, q);
+ }
+ }
+ }
+ else
+ {
+ const uint32 q = log10Pow5(-e2);
+
+ e10 = q + e2;
+
+ const int32 i = -e2 - q;
+ const int32 k = pow5bits(i) - FLOAT_POW5_BITCOUNT;
+ int32 j = q - k;
+
+ vr = mulPow5divPow2(mv, i, j);
+ vp = mulPow5divPow2(mp, i, j);
+ vm = mulPow5divPow2(mm, i, j);
+
+ if (q != 0 && (vp - 1) / 10 <= vm / 10)
+ {
+ j = q - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT);
+ lastRemovedDigit = (uint8) (mulPow5divPow2(mv, i + 1, j) % 10);
+ }
+ if (q <= 1)
+ {
+ /*
+ * {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q
+ * trailing 0 bits.
+ */
+ /* mv = 4 * m2, so it always has at least two trailing 0 bits. */
+ vrIsTrailingZeros = true;
+ if (acceptBounds)
+ {
+ /*
+ * mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff
+ * mmShift == 1.
+ */
+ vmIsTrailingZeros = mmShift == 1;
+ }
+ else
+ {
+ /*
+ * mp = mv + 2, so it always has at least one trailing 0 bit.
+ */
+ --vp;
+ }
+ }
+ else if (q < 31)
+ {
+ /* TODO(ulfjack):Use a tighter bound here. */
+ vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1);
+ }
+ }
+
+ /*
+ * Step 4: Find the shortest decimal representation in the interval of
+ * legal representations.
+ */
+ uint32 removed = 0;
+ uint32 output;
+
+ if (vmIsTrailingZeros || vrIsTrailingZeros)
+ {
+ /* General case, which happens rarely (~4.0%). */
+ while (vp / 10 > vm / 10)
+ {
+ vmIsTrailingZeros &= vm - (vm / 10) * 10 == 0;
+ vrIsTrailingZeros &= lastRemovedDigit == 0;
+ lastRemovedDigit = (uint8) (vr % 10);
+ vr /= 10;
+ vp /= 10;
+ vm /= 10;
+ ++removed;
+ }
+ if (vmIsTrailingZeros)
+ {
+ while (vm % 10 == 0)
+ {
+ vrIsTrailingZeros &= lastRemovedDigit == 0;
+ lastRemovedDigit = (uint8) (vr % 10);
+ vr /= 10;
+ vp /= 10;
+ vm /= 10;
+ ++removed;
+ }
+ }
+
+ if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0)
+ {
+ /* Round even if the exact number is .....50..0. */
+ lastRemovedDigit = 4;
+ }
+
+ /*
+ * We need to take vr + 1 if vr is outside bounds or we need to round
+ * up.
+ */
+ output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5);
+ }
+ else
+ {
+ /*
+ * Specialized for the common case (~96.0%). Percentages below are
+ * relative to this.
+ *
+ * Loop iterations below (approximately): 0: 13.6%, 1: 70.7%, 2:
+ * 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01%
+ */
+ while (vp / 10 > vm / 10)
+ {
+ lastRemovedDigit = (uint8) (vr % 10);
+ vr /= 10;
+ vp /= 10;
+ vm /= 10;
+ ++removed;
+ }
+
+ /*
+ * We need to take vr + 1 if vr is outside bounds or we need to round
+ * up.
+ */
+ output = vr + (vr == vm || lastRemovedDigit >= 5);
+ }
+
+ const int32 exp = e10 + removed;
+
+ floating_decimal_32 fd;
+
+ fd.exponent = exp;
+ fd.mantissa = output;
+ return fd;
+}
+
+static inline int
+to_chars_f(const floating_decimal_32 v, const uint32 olength, char *const result)
+{
+ /* Step 5: Print the decimal representation. */
+ int index = 0;
+
+ uint32 output = v.mantissa;
+ int32 exp = v.exponent;
+
+ /*----
+ * On entry, mantissa * 10^exp is the result to be output.
+ * Caller has already done the - sign if needed.
+ *
+ * We want to insert the point somewhere depending on the output length
+ * and exponent, which might mean adding zeros:
+ *
+ * exp | format
+ * 1+ | ddddddddd000000
+ * 0 | ddddddddd
+ * -1 .. -len+1 | dddddddd.d to d.ddddddddd
+ * -len ... | 0.ddddddddd to 0.000dddddd
+ */
+ uint32 i = 0;
+ int32 nexp = exp + olength;
+
+ if (nexp <= 0)
+ {
+ /* -nexp is number of 0s to add after '.' */
+ Assert(nexp >= -3);
+ /* 0.000ddddd */
+ index = 2 - nexp;
+ /* copy 8 bytes rather than 5 to let compiler optimize */
+ memcpy(result, "0.000000", 8);
+ }
+ else if (exp < 0)
+ {
+ /*
+ * dddd.dddd; leave space at the start and move the '.' in after
+ */
+ index = 1;
+ }
+ else
+ {
+ /*
+ * We can save some code later by pre-filling with zeros. We know
+ * that there can be no more than 6 output digits in this form,
+ * otherwise we would not choose fixed-point output. memset 8
+ * rather than 6 bytes to let the compiler optimize it.
+ */
+ Assert(exp < 6 && exp + olength <= 6);
+ memset(result, '0', 8);
+ }
+
+ while (output >= 10000)
+ {
+ const uint32 c = output - 10000 * (output / 10000);
+ const uint32 c0 = (c % 100) << 1;
+ const uint32 c1 = (c / 100) << 1;
+
+ output /= 10000;
+
+ memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2);
+ memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2);
+ i += 4;
+ }
+ if (output >= 100)
+ {
+ const uint32 c = (output % 100) << 1;
+
+ output /= 100;
+ memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2);
+ i += 2;
+ }
+ if (output >= 10)
+ {
+ const uint32 c = output << 1;
+
+ memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2);
+ }
+ else
+ {
+ result[index] = (char) ('0' + output);
+ }
+
+ if (index == 1)
+ {
+ /*
+ * nexp is 1..6 here, representing the number of digits before the
+ * point. A value of 7+ is not possible because we switch to
+ * scientific notation when the display exponent reaches 6.
+ */
+ Assert(nexp < 7);
+ /* gcc only seems to want to optimize memmove for small 2^n */
+ if (nexp & 4)
+ {
+ memmove(result + index - 1, result + index, 4);
+ index += 4;
+ }
+ if (nexp & 2)
+ {
+ memmove(result + index - 1, result + index, 2);
+ index += 2;
+ }
+ if (nexp & 1)
+ {
+ result[index - 1] = result[index];
+ }
+ result[nexp] = '.';
+ index = olength + 1;
+ }
+ else if (exp >= 0)
+ {
+ /* we supplied the trailing zeros earlier, now just set the length. */
+ index = olength + exp;
+ }
+ else
+ {
+ index = olength + (2 - nexp);
+ }
+
+ return index;
+}
+
+static inline int
+to_chars(const floating_decimal_32 v, const bool sign, char *const result)
+{
+ /* Step 5: Print the decimal representation. */
+ int index = 0;
+
+ uint32 output = v.mantissa;
+ uint32 olength = decimalLength(output);
+ int32 exp = v.exponent + olength - 1;
+
+ if (sign)
+ result[index++] = '-';
+
+ /*
+ * The thresholds for fixed-point output are chosen to match printf
+ * defaults. Beware that both the code of to_chars_f and the value
+ * of FLOAT_SHORTEST_DECIMAL_LEN are sensitive to these thresholds.
+ */
+ if (exp >= -4 && exp < 6)
+ return to_chars_f(v, olength, result + index) + sign;
+
+ /*
+ * If v.exponent is exactly 0, we might have reached here via the small
+ * integer fast path, in which case v.mantissa might contain trailing
+ * (decimal) zeros. For scientific notation we need to move these zeros
+ * into the exponent. (For fixed point this doesn't matter, which is why
+ * we do this here rather than above.)
+ *
+ * Since we already calculated the display exponent (exp) above based on
+ * the old decimal length, that value does not change here. Instead, we
+ * just reduce the display length for each digit removed.
+ *
+ * If we didn't get here via the fast path, the raw exponent will not
+ * usually be 0, and there will be no trailing zeros, so we pay no more
+ * than one div10/multiply extra cost. We claw back half of that by
+ * checking for divisibility by 2 before dividing by 10.
+ */
+ if (v.exponent == 0)
+ {
+ while ((output & 1) == 0)
+ {
+ const uint32 q = output / 10;
+ const uint32 r = output - 10 * q;
+
+ if (r != 0)
+ break;
+ output = q;
+ --olength;
+ }
+ }
+
+ /*----
+ * Print the decimal digits.
+ * The following code is equivalent to:
+ *
+ * for (uint32 i = 0; i < olength - 1; ++i) {
+ * const uint32 c = output % 10; output /= 10;
+ * result[index + olength - i] = (char) ('0' + c);
+ * }
+ * result[index] = '0' + output % 10;
+ */
+ uint32 i = 0;
+
+ while (output >= 10000)
+ {
+ const uint32 c = output - 10000 * (output / 10000);
+ const uint32 c0 = (c % 100) << 1;
+ const uint32 c1 = (c / 100) << 1;
+
+ output /= 10000;
+
+ memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2);
+ memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2);
+ i += 4;
+ }
+ if (output >= 100)
+ {
+ const uint32 c = (output % 100) << 1;
+
+ output /= 100;
+ memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2);
+ i += 2;
+ }
+ if (output >= 10)
+ {
+ const uint32 c = output << 1;
+
+ /*
+ * We can't use memcpy here: the decimal dot goes between these two
+ * digits.
+ */
+ result[index + olength - i] = DIGIT_TABLE[c + 1];
+ result[index] = DIGIT_TABLE[c];
+ }
+ else
+ {
+ result[index] = (char) ('0' + output);
+ }
+
+ /* Print decimal point if needed. */
+ if (olength > 1)
+ {
+ result[index + 1] = '.';
+ index += olength + 1;
+ }
+ else
+ {
+ ++index;
+ }
+
+ /* Print the exponent. */
+ result[index++] = 'e';
+ if (exp < 0)
+ {
+ result[index++] = '-';
+ exp = -exp;
+ }
+ else
+ result[index++] = '+';
+
+ memcpy(result + index, DIGIT_TABLE + 2 * exp, 2);
+ index += 2;
+
+ return index;
+}
+
+static inline bool
+f2d_small_int(const uint32 ieeeMantissa,
+ const uint32 ieeeExponent,
+ floating_decimal_32 *v)
+{
+ const int32 e2 = (int32) ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS;
+
+ /*
+ * Avoid using multiple "return false;" here since it tends to provoke the
+ * compiler into inlining multiple copies of f2d, which is undesirable.
+ */
+
+ if (e2 >= -FLOAT_MANTISSA_BITS && e2 <= 0)
+ {
+ /*----
+ * Since 2^23 <= m2 < 2^24 and 0 <= -e2 <= 23:
+ * 1 <= f = m2 / 2^-e2 < 2^24.
+ *
+ * Test if the lower -e2 bits of the significand are 0, i.e. whether
+ * the fraction is 0. We can use ieeeMantissa here, since the implied
+ * 1 bit can never be tested by this; the implied 1 can only be part
+ * of a fraction if e2 < -FLOAT_MANTISSA_BITS which we already
+ * checked. (e.g. 0.5 gives ieeeMantissa == 0 and e2 == -24)
+ */
+ const uint32 mask = (1U << -e2) - 1;
+ const uint32 fraction = ieeeMantissa & mask;
+
+ if (fraction == 0)
+ {
+ /*----
+ * f is an integer in the range [1, 2^24).
+ * Note: mantissa might contain trailing (decimal) 0's.
+ * Note: since 2^24 < 10^9, there is no need to adjust
+ * decimalLength().
+ */
+ const uint32 m2 = (1U << FLOAT_MANTISSA_BITS) | ieeeMantissa;
+
+ v->mantissa = m2 >> -e2;
+ v->exponent = 0;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/*
+ * Store the shortest decimal representation of the given float as an
+ * UNTERMINATED string in the caller's supplied buffer (which must be at least
+ * FLOAT_SHORTEST_DECIMAL_LEN-1 bytes long).
+ *
+ * Returns the number of bytes stored.
+ */
+int
+float_to_shortest_decimal_bufn(float f, char *result)
+{
+ /*
+ * Step 1: Decode the floating-point number, and unify normalized and
+ * subnormal cases.
+ */
+ const uint32 bits = float_to_bits(f);
+
+ /* Decode bits into sign, mantissa, and exponent. */
+ const bool ieeeSign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0;
+ const uint32 ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1);
+ const uint32 ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u << FLOAT_EXPONENT_BITS) - 1);
+
+ /* Case distinction; exit early for the easy cases. */
+ if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0))
+ {
+ return copy_special_str(result, ieeeSign, ieeeExponent, ieeeMantissa);
+ }
+
+ floating_decimal_32 v;
+ const bool isSmallInt = f2d_small_int(ieeeMantissa, ieeeExponent, &v);
+
+ if (!isSmallInt)
+ {
+ v = f2d(ieeeMantissa, ieeeExponent);
+ }
+
+ return to_chars(v, ieeeSign, result);
+}
+
+/*
+ * Store the shortest decimal representation of the given float as a
+ * null-terminated string in the caller's supplied buffer (which must be at
+ * least FLOAT_SHORTEST_DECIMAL_LEN bytes long).
+ *
+ * Returns the string length.
+ */
+int
+float_to_shortest_decimal_buf(float f, char *result)
+{
+ const int index = float_to_shortest_decimal_bufn(f, result);
+
+ /* Terminate the string. */
+ Assert(index < FLOAT_SHORTEST_DECIMAL_LEN);
+ result[index] = '\0';
+ return index;
+}
+
+/*
+ * Return the shortest decimal representation as a null-terminated palloc'd
+ * string (outside the backend, uses malloc() instead).
+ *
+ * Caller is responsible for freeing the result.
+ */
+char *
+float_to_shortest_decimal(float f)
+{
+ char *const result = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN);
+
+ float_to_shortest_decimal_buf(f, result);
+ return result;
+}
diff --git a/src/common/ryu_common.h b/src/common/ryu_common.h
new file mode 100644
index 0000000000..14639aff9c
--- /dev/null
+++ b/src/common/ryu_common.h
@@ -0,0 +1,133 @@
+/*---------------------------------------------------------------------------
+ *
+ * Common routines for Ryu floating-point output.
+ *
+ * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/ryu_common.h
+ *
+ * This is a modification of code taken from github.com/ulfjack/ryu under the
+ * terms of the Boost license (not the Apache license). The original copyright
+ * notice follows:
+ *
+ * Copyright 2018 Ulf Adams
+ *
+ * The contents of this file may be used under the terms of the Apache
+ * License, Version 2.0.
+ *
+ * (See accompanying file LICENSE-Apache or copy at
+ * http://www.apache.org/licenses/LICENSE-2.0)
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * Boost Software License, Version 1.0.
+ *
+ * (See accompanying file LICENSE-Boost or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Unless required by applicable law or agreed to in writing, this software is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.
+ *
+ *---------------------------------------------------------------------------
+ */
+#ifndef RYU_COMMON_H
+#define RYU_COMMON_H
+
+/*
+ * Upstream Ryu's output is always the shortest possible. But we adjust that
+ * slightly to improve portability: we avoid outputting the exact midpoint
+ * value between two representable floats, since that relies on the reader
+ * getting the round-to-even rule correct, which seems to be the common
+ * failure mode.
+ *
+ * Defining this to 1 would restore the upstream behavior.
+ */
+#define STRICTLY_SHORTEST 0
+
+#if SIZEOF_SIZE_T < 8
+#define RYU_32_BIT_PLATFORM
+#endif
+
+/* Returns e == 0 ? 1 : ceil(log_2(5^e)). */
+static inline uint32
+pow5bits(const int32 e)
+{
+ /*
+ * This approximation works up to the point that the multiplication
+ * overflows at e = 3529.
+ *
+ * If the multiplication were done in 64 bits, it would fail at 5^4004
+ * which is just greater than 2^9297.
+ */
+ Assert(e >= 0);
+ Assert(e <= 3528);
+ return ((((uint32) e) * 1217359) >> 19) + 1;
+}
+
+/* Returns floor(log_10(2^e)). */
+static inline int32
+log10Pow2(const int32 e)
+{
+ /*
+ * The first value this approximation fails for is 2^1651 which is just
+ * greater than 10^297.
+ */
+ Assert(e >= 0);
+ Assert(e <= 1650);
+ return (int32) ((((uint32) e) * 78913) >> 18);
+}
+
+/* Returns floor(log_10(5^e)). */
+static inline int32
+log10Pow5(const int32 e)
+{
+ /*
+ * The first value this approximation fails for is 5^2621 which is just
+ * greater than 10^1832.
+ */
+ Assert(e >= 0);
+ Assert(e <= 2620);
+ return (int32) ((((uint32) e) * 732923) >> 20);
+}
+
+static inline int
+copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa)
+{
+ if (mantissa)
+ {
+ memcpy(result, "NaN", 3);
+ return 3;
+ }
+ if (sign)
+ {
+ result[0] = '-';
+ }
+ if (exponent)
+ {
+ memcpy(result + sign, "Infinity", 8);
+ return sign + 8;
+ }
+ result[sign] = '0';
+ return sign + 1;
+}
+
+static inline uint32
+float_to_bits(const float f)
+{
+ uint32 bits = 0;
+
+ memcpy(&bits, &f, sizeof(float));
+ return bits;
+}
+
+static inline uint64
+double_to_bits(const double d)
+{
+ uint64 bits = 0;
+
+ memcpy(&bits, &d, sizeof(double));
+ return bits;
+}
+
+#endif /* RYU_COMMON_H */
diff --git a/src/include/common/shortest_dec.h b/src/include/common/shortest_dec.h
new file mode 100644
index 0000000000..4c3dcd37cf
--- /dev/null
+++ b/src/include/common/shortest_dec.h
@@ -0,0 +1,63 @@
+/*---------------------------------------------------------------------------
+ *
+ * Ryu floating-point output.
+ *
+ * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/include/common/shortest_dec.h
+ *
+ * This is a modification of code taken from github.com/ulfjack/ryu under the
+ * terms of the Boost license (not the Apache license). The original copyright
+ * notice follows:
+ *
+ * Copyright 2018 Ulf Adams
+ *
+ * The contents of this file may be used under the terms of the Apache
+ * License, Version 2.0.
+ *
+ * (See accompanying file LICENSE-Apache or copy at
+ * http://www.apache.org/licenses/LICENSE-2.0)
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * Boost Software License, Version 1.0.
+ *
+ * (See accompanying file LICENSE-Boost or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Unless required by applicable law or agreed to in writing, this software is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.
+ *
+ *---------------------------------------------------------------------------
+ */
+#ifndef SHORTEST_DEC_H
+#define SHORTEST_DEC_H
+
+/*----
+ * The length of 25 comes from:
+ *
+ * Case 1: -9.9999999999999999e-299 = 24 bytes, plus 1 for null
+ *
+ * Case 2: -0.00099999999999999999 = 23 bytes, plus 1 for null
+ */
+#define DOUBLE_SHORTEST_DECIMAL_LEN 25
+
+int double_to_shortest_decimal_bufn(double f, char *result);
+int double_to_shortest_decimal_buf(double f, char *result);
+char *double_to_shortest_decimal(double f);
+
+/*
+ * The length of 16 comes from:
+ *
+ * Case 1: -9.99999999e+29 = 15 bytes, plus 1 for null
+ *
+ * Case 2: -0.000999999999 = 15 bytes, plus 1 for null
+ */
+#define FLOAT_SHORTEST_DECIMAL_LEN 16
+
+int float_to_shortest_decimal_bufn(float f, char *result);
+int float_to_shortest_decimal_buf(float f, char *result);
+char *float_to_shortest_decimal(float f);
+
+#endif /* SHORTEST_DEC_H */
diff --git a/src/test/regress/expected/aggregates.out b/src/test/regress/expected/aggregates.out
index 918db6cb67..129c1e5075 100644
--- a/src/test/regress/expected/aggregates.out
+++ b/src/test/regress/expected/aggregates.out
@@ -1,6 +1,8 @@
--
-- AGGREGATES
--
+-- avoid bit-exact output here because operations may not be bit-exact.
+SET extra_float_digits = 0;
SELECT avg(four) AS avg_1 FROM onek;
avg_1
--------------------
diff --git a/src/test/regress/expected/circle.out b/src/test/regress/expected/circle.out
index 2ed74cc6aa..756c7e37ef 100644
--- a/src/test/regress/expected/circle.out
+++ b/src/test/regress/expected/circle.out
@@ -1,6 +1,8 @@
--
-- CIRCLE
--
+-- avoid bit-exact output here because operations may not be bit-exact.
+SET extra_float_digits = 0;
CREATE TABLE CIRCLE_TBL (f1 circle);
INSERT INTO CIRCLE_TBL VALUES ('<(5,1),3>');
INSERT INTO CIRCLE_TBL VALUES ('<(1,2),100>');
diff --git a/src/test/regress/expected/float4-misrounded-input.out b/src/test/regress/expected/float4-misrounded-input.out
index 9898d92928..54de939a6e 100644
--- a/src/test/regress/expected/float4-misrounded-input.out
+++ b/src/test/regress/expected/float4-misrounded-input.out
@@ -142,22 +142,22 @@ SELECT 'nan'::numeric::float4;
(1 row)
SELECT '' AS five, * FROM FLOAT4_TBL;
- five | f1
-------+-------------
- | 0
- | 1004.3
- | -34.84
- | 1.23457e+20
- | 1.23457e-20
+ five | f1
+------+---------------
+ | 0
+ | 1004.3
+ | -34.84
+ | 1.2345679e+20
+ | 1.2345679e-20
(5 rows)
SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <> '1004.3';
- four | f1
-------+-------------
- | 0
- | -34.84
- | 1.23457e+20
- | 1.23457e-20
+ four | f1
+------+---------------
+ | 0
+ | -34.84
+ | 1.2345679e+20
+ | 1.2345679e-20
(4 rows)
SELECT '' AS one, f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3';
@@ -167,110 +167,110 @@ SELECT '' AS one, f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3';
(1 row)
SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE '1004.3' > f.f1;
- three | f1
--------+-------------
- | 0
- | -34.84
- | 1.23457e-20
+ three | f1
+-------+---------------
+ | 0
+ | -34.84
+ | 1.2345679e-20
(3 rows)
SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE f.f1 < '1004.3';
- three | f1
--------+-------------
- | 0
- | -34.84
- | 1.23457e-20
+ three | f1
+-------+---------------
+ | 0
+ | -34.84
+ | 1.2345679e-20
(3 rows)
SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE '1004.3' >= f.f1;
- four | f1
-------+-------------
- | 0
- | 1004.3
- | -34.84
- | 1.23457e-20
+ four | f1
+------+---------------
+ | 0
+ | 1004.3
+ | -34.84
+ | 1.2345679e-20
(4 rows)
SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <= '1004.3';
- four | f1
-------+-------------
- | 0
- | 1004.3
- | -34.84
- | 1.23457e-20
+ four | f1
+------+---------------
+ | 0
+ | 1004.3
+ | -34.84
+ | 1.2345679e-20
(4 rows)
SELECT '' AS three, f.f1, f.f1 * '-10' AS x FROM FLOAT4_TBL f
WHERE f.f1 > '0.0';
- three | f1 | x
--------+-------------+--------------
- | 1004.3 | -10043
- | 1.23457e+20 | -1.23457e+21
- | 1.23457e-20 | -1.23457e-19
+ three | f1 | x
+-------+---------------+----------------
+ | 1004.3 | -10043
+ | 1.2345679e+20 | -1.2345678e+21
+ | 1.2345679e-20 | -1.2345678e-19
(3 rows)
SELECT '' AS three, f.f1, f.f1 + '-10' AS x FROM FLOAT4_TBL f
WHERE f.f1 > '0.0';
- three | f1 | x
--------+-------------+-------------
- | 1004.3 | 994.3
- | 1.23457e+20 | 1.23457e+20
- | 1.23457e-20 | -10
+ three | f1 | x
+-------+---------------+---------------
+ | 1004.3 | 994.3
+ | 1.2345679e+20 | 1.2345679e+20
+ | 1.2345679e-20 | -10
(3 rows)
SELECT '' AS three, f.f1, f.f1 / '-10' AS x FROM FLOAT4_TBL f
WHERE f.f1 > '0.0';
- three | f1 | x
--------+-------------+--------------
- | 1004.3 | -100.43
- | 1.23457e+20 | -1.23457e+19
- | 1.23457e-20 | -1.23457e-21
+ three | f1 | x
+-------+---------------+----------------
+ | 1004.3 | -100.43
+ | 1.2345679e+20 | -1.2345679e+19
+ | 1.2345679e-20 | -1.2345679e-21
(3 rows)
SELECT '' AS three, f.f1, f.f1 - '-10' AS x FROM FLOAT4_TBL f
WHERE f.f1 > '0.0';
- three | f1 | x
--------+-------------+-------------
- | 1004.3 | 1014.3
- | 1.23457e+20 | 1.23457e+20
- | 1.23457e-20 | 10
+ three | f1 | x
+-------+---------------+---------------
+ | 1004.3 | 1014.3
+ | 1.2345679e+20 | 1.2345679e+20
+ | 1.2345679e-20 | 10
(3 rows)
-- test divide by zero
SELECT '' AS bad, f.f1 / '0.0' from FLOAT4_TBL f;
ERROR: division by zero
SELECT '' AS five, * FROM FLOAT4_TBL;
- five | f1
-------+-------------
- | 0
- | 1004.3
- | -34.84
- | 1.23457e+20
- | 1.23457e-20
+ five | f1
+------+---------------
+ | 0
+ | 1004.3
+ | -34.84
+ | 1.2345679e+20
+ | 1.2345679e-20
(5 rows)
-- test the unary float4abs operator
SELECT '' AS five, f.f1, @f.f1 AS abs_f1 FROM FLOAT4_TBL f;
- five | f1 | abs_f1
-------+-------------+-------------
- | 0 | 0
- | 1004.3 | 1004.3
- | -34.84 | 34.84
- | 1.23457e+20 | 1.23457e+20
- | 1.23457e-20 | 1.23457e-20
+ five | f1 | abs_f1
+------+---------------+---------------
+ | 0 | 0
+ | 1004.3 | 1004.3
+ | -34.84 | 34.84
+ | 1.2345679e+20 | 1.2345679e+20
+ | 1.2345679e-20 | 1.2345679e-20
(5 rows)
UPDATE FLOAT4_TBL
SET f1 = FLOAT4_TBL.f1 * '-1'
WHERE FLOAT4_TBL.f1 > '0.0';
SELECT '' AS five, * FROM FLOAT4_TBL;
- five | f1
-------+--------------
- | 0
- | -34.84
- | -1004.3
- | -1.23457e+20
- | -1.23457e-20
+ five | f1
+------+----------------
+ | 0
+ | -34.84
+ | -1004.3
+ | -1.2345679e+20
+ | -1.2345679e-20
(5 rows)
-- test edge-case coercions to integer
@@ -434,3 +434,507 @@ SELECT float4send('1.1754944e-38'::float4);
\x00800000
(1 row)
+-- test output (and round-trip safety) of various values.
+-- To ensure we're testing what we think we're testing, start with
+-- float values specified by bit patterns (as a useful side effect,
+-- this means we'll fail on non-IEEE platforms).
+create type xfloat4;
+create function xfloat4in(cstring) returns xfloat4 immutable strict
+ language internal as 'int4in';
+NOTICE: return type xfloat4 is only a shell
+create function xfloat4out(xfloat4) returns cstring immutable strict
+ language internal as 'int4out';
+NOTICE: argument type xfloat4 is only a shell
+create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4);
+create cast (xfloat4 as float4) without function;
+create cast (float4 as xfloat4) without function;
+create cast (xfloat4 as integer) without function;
+create cast (integer as xfloat4) without function;
+-- float4: seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
+-- we don't care to assume the platform's strtod() handles subnormals
+-- correctly; those are "use at your own risk". However we do test
+-- subnormal outputs, since those are under our control.
+with testdata(bits) as (values
+ -- small subnormals
+ (x'00000001'),
+ (x'00000002'), (x'00000003'),
+ (x'00000010'), (x'00000011'), (x'00000100'), (x'00000101'),
+ (x'00004000'), (x'00004001'), (x'00080000'), (x'00080001'),
+ -- stress values
+ (x'0053c4f4'), -- 7693e-42
+ (x'006c85c4'), -- 996622e-44
+ (x'0041ca76'), -- 60419369e-46
+ (x'004b7678'), -- 6930161142e-48
+ -- taken from upstream testsuite
+ (x'00000007'),
+ (x'00424fe2'),
+ -- borderline between subnormal and normal
+ (x'007ffff0'), (x'007ffff1'), (x'007ffffe'), (x'007fffff'))
+select float4send(flt) as ibits,
+ flt
+ from (select bits::integer::xfloat4::float4 as flt
+ from testdata
+ offset 0) s;
+ ibits | flt
+------------+---------------
+ \x00000001 | 1e-45
+ \x00000002 | 3e-45
+ \x00000003 | 4e-45
+ \x00000010 | 2.2e-44
+ \x00000011 | 2.4e-44
+ \x00000100 | 3.59e-43
+ \x00000101 | 3.6e-43
+ \x00004000 | 2.2959e-41
+ \x00004001 | 2.296e-41
+ \x00080000 | 7.34684e-40
+ \x00080001 | 7.34685e-40
+ \x0053c4f4 | 7.693e-39
+ \x006c85c4 | 9.96622e-39
+ \x0041ca76 | 6.041937e-39
+ \x004b7678 | 6.930161e-39
+ \x00000007 | 1e-44
+ \x00424fe2 | 6.0898e-39
+ \x007ffff0 | 1.1754921e-38
+ \x007ffff1 | 1.1754922e-38
+ \x007ffffe | 1.1754941e-38
+ \x007fffff | 1.1754942e-38
+(21 rows)
+
+with testdata(bits) as (values
+ (x'00000000'),
+ -- smallest normal values
+ (x'00800000'), (x'00800001'), (x'00800004'), (x'00800005'),
+ (x'00800006'),
+ -- small normal values chosen for short vs. long output
+ (x'008002f1'), (x'008002f2'), (x'008002f3'),
+ (x'00800e17'), (x'00800e18'), (x'00800e19'),
+ -- assorted values (random mantissae)
+ (x'01000001'), (x'01102843'), (x'01a52c98'),
+ (x'0219c229'), (x'02e4464d'), (x'037343c1'), (x'03a91b36'),
+ (x'047ada65'), (x'0496fe87'), (x'0550844f'), (x'05999da3'),
+ (x'060ea5e2'), (x'06e63c45'), (x'07f1e548'), (x'0fc5282b'),
+ (x'1f850283'), (x'2874a9d6'),
+ -- values around 5e-08
+ (x'3356bf94'), (x'3356bf95'), (x'3356bf96'),
+ -- around 1e-07
+ (x'33d6bf94'), (x'33d6bf95'), (x'33d6bf96'),
+ -- around 3e-07 .. 1e-04
+ (x'34a10faf'), (x'34a10fb0'), (x'34a10fb1'),
+ (x'350637bc'), (x'350637bd'), (x'350637be'),
+ (x'35719786'), (x'35719787'), (x'35719788'),
+ (x'358637bc'), (x'358637bd'), (x'358637be'),
+ (x'36a7c5ab'), (x'36a7c5ac'), (x'36a7c5ad'),
+ (x'3727c5ab'), (x'3727c5ac'), (x'3727c5ad'),
+ -- format crossover at 1e-04
+ (x'38d1b714'), (x'38d1b715'), (x'38d1b716'),
+ (x'38d1b717'), (x'38d1b718'), (x'38d1b719'),
+ (x'38d1b71a'), (x'38d1b71b'), (x'38d1b71c'),
+ (x'38d1b71d'),
+ --
+ (x'38dffffe'), (x'38dfffff'), (x'38e00000'),
+ (x'38efffff'), (x'38f00000'), (x'38f00001'),
+ (x'3a83126e'), (x'3a83126f'), (x'3a831270'),
+ (x'3c23d709'), (x'3c23d70a'), (x'3c23d70b'),
+ (x'3dcccccc'), (x'3dcccccd'), (x'3dccccce'),
+ -- chosen to need 9 digits for 3dcccd70
+ (x'3dcccd6f'), (x'3dcccd70'), (x'3dcccd71'),
+ --
+ (x'3effffff'), (x'3f000000'), (x'3f000001'),
+ (x'3f333332'), (x'3f333333'), (x'3f333334'),
+ -- approach 1.0 with increasing numbers of 9s
+ (x'3f666665'), (x'3f666666'), (x'3f666667'),
+ (x'3f7d70a3'), (x'3f7d70a4'), (x'3f7d70a5'),
+ (x'3f7fbe76'), (x'3f7fbe77'), (x'3f7fbe78'),
+ (x'3f7ff971'), (x'3f7ff972'), (x'3f7ff973'),
+ (x'3f7fff57'), (x'3f7fff58'), (x'3f7fff59'),
+ (x'3f7fffee'), (x'3f7fffef'),
+ -- values very close to 1
+ (x'3f7ffff0'), (x'3f7ffff1'), (x'3f7ffff2'),
+ (x'3f7ffff3'), (x'3f7ffff4'), (x'3f7ffff5'),
+ (x'3f7ffff6'), (x'3f7ffff7'), (x'3f7ffff8'),
+ (x'3f7ffff9'), (x'3f7ffffa'), (x'3f7ffffb'),
+ (x'3f7ffffc'), (x'3f7ffffd'), (x'3f7ffffe'),
+ (x'3f7fffff'),
+ (x'3f800000'),
+ (x'3f800001'), (x'3f800002'), (x'3f800003'),
+ (x'3f800004'), (x'3f800005'), (x'3f800006'),
+ (x'3f800007'), (x'3f800008'), (x'3f800009'),
+ -- values 1 to 1.1
+ (x'3f80000f'), (x'3f800010'), (x'3f800011'),
+ (x'3f800012'), (x'3f800013'), (x'3f800014'),
+ (x'3f800017'), (x'3f800018'), (x'3f800019'),
+ (x'3f80001a'), (x'3f80001b'), (x'3f80001c'),
+ (x'3f800029'), (x'3f80002a'), (x'3f80002b'),
+ (x'3f800053'), (x'3f800054'), (x'3f800055'),
+ (x'3f800346'), (x'3f800347'), (x'3f800348'),
+ (x'3f8020c4'), (x'3f8020c5'), (x'3f8020c6'),
+ (x'3f8147ad'), (x'3f8147ae'), (x'3f8147af'),
+ (x'3f8ccccc'), (x'3f8ccccd'), (x'3f8cccce'),
+ --
+ (x'3fc90fdb'), -- pi/2
+ (x'402df854'), -- e
+ (x'40490fdb'), -- pi
+ --
+ (x'409fffff'), (x'40a00000'), (x'40a00001'),
+ (x'40afffff'), (x'40b00000'), (x'40b00001'),
+ (x'411fffff'), (x'41200000'), (x'41200001'),
+ (x'42c7ffff'), (x'42c80000'), (x'42c80001'),
+ (x'4479ffff'), (x'447a0000'), (x'447a0001'),
+ (x'461c3fff'), (x'461c4000'), (x'461c4001'),
+ (x'47c34fff'), (x'47c35000'), (x'47c35001'),
+ (x'497423ff'), (x'49742400'), (x'49742401'),
+ (x'4b18967f'), (x'4b189680'), (x'4b189681'),
+ (x'4cbebc1f'), (x'4cbebc20'), (x'4cbebc21'),
+ (x'4e6e6b27'), (x'4e6e6b28'), (x'4e6e6b29'),
+ (x'501502f8'), (x'501502f9'), (x'501502fa'),
+ (x'51ba43b6'), (x'51ba43b7'), (x'51ba43b8'),
+ -- stress values
+ (x'1f6c1e4a'), -- 5e-20
+ (x'59be6cea'), -- 67e14
+ (x'5d5ab6c4'), -- 985e15
+ (x'2cc4a9bd'), -- 55895e-16
+ (x'15ae43fd'), -- 7038531e-32
+ (x'2cf757ca'), -- 702990899e-20
+ (x'665ba998'), -- 25933168707e13
+ (x'743c3324'), -- 596428896559e20
+ -- exercise fixed-point memmoves
+ (x'47f1205a'),
+ (x'4640e6ae'),
+ (x'449a5225'),
+ (x'42f6e9d5'),
+ (x'414587dd'),
+ (x'3f9e064b'),
+ -- these cases come from the upstream's testsuite
+ -- BoundaryRoundEven
+ (x'4c000004'),
+ (x'50061c46'),
+ (x'510006a8'),
+ -- ExactValueRoundEven
+ (x'48951f84'),
+ (x'45fd1840'),
+ -- LotsOfTrailingZeros
+ (x'39800000'),
+ (x'3b200000'),
+ (x'3b900000'),
+ (x'3bd00000'),
+ -- Regression
+ (x'63800000'),
+ (x'4b000000'),
+ (x'4b800000'),
+ (x'4c000001'),
+ (x'4c800b0d'),
+ (x'00d24584'),
+ (x'800000b0'),
+ (x'00d90b88'),
+ (x'45803f34'),
+ (x'4f9f24f7'),
+ (x'3a8722c3'),
+ (x'5c800041'),
+ (x'15ae43fd'),
+ (x'5d4cccfb'),
+ (x'4c800001'),
+ (x'57800ed8'),
+ (x'5f000000'),
+ (x'700000f0'),
+ (x'5f23e9ac'),
+ (x'5e9502f9'),
+ (x'5e8012b1'),
+ (x'3c000028'),
+ (x'60cde861'),
+ (x'03aa2a50'),
+ (x'43480000'),
+ (x'4c000000'),
+ -- LooksLikePow5
+ (x'5D1502F9'),
+ (x'5D9502F9'),
+ (x'5E1502F9'),
+ -- OutputLength
+ (x'3f99999a'),
+ (x'3f9d70a4'),
+ (x'3f9df3b6'),
+ (x'3f9e0419'),
+ (x'3f9e0610'),
+ (x'3f9e064b'),
+ (x'3f9e0651'),
+ (x'03d20cfe')
+)
+select float4send(flt) as ibits,
+ flt,
+ flt::text::float4 as r_flt,
+ float4send(flt::text::float4) as obits,
+ float4send(flt::text::float4) = float4send(flt) as correct
+ from (select bits::integer::xfloat4::float4 as flt
+ from testdata
+ offset 0) s;
+ ibits | flt | r_flt | obits | correct
+------------+----------------+----------------+------------+---------
+ \x00000000 | 0 | 0 | \x00000000 | t
+ \x00800000 | 1.1754944e-38 | 1.1754944e-38 | \x00800000 | t
+ \x00800001 | 1.1754945e-38 | 1.1754945e-38 | \x00800001 | t
+ \x00800004 | 1.1754949e-38 | 1.1754949e-38 | \x00800004 | t
+ \x00800005 | 1.175495e-38 | 1.175495e-38 | \x00800005 | t
+ \x00800006 | 1.1754952e-38 | 1.1754952e-38 | \x00800006 | t
+ \x008002f1 | 1.1755999e-38 | 1.1755999e-38 | \x008002f1 | t
+ \x008002f2 | 1.1756e-38 | 1.1756e-38 | \x008002f2 | t
+ \x008002f3 | 1.1756001e-38 | 1.1756001e-38 | \x008002f3 | t
+ \x00800e17 | 1.1759998e-38 | 1.1759998e-38 | \x00800e17 | t
+ \x00800e18 | 1.176e-38 | 1.176e-38 | \x00800e18 | t
+ \x00800e19 | 1.1760001e-38 | 1.1760001e-38 | \x00800e19 | t
+ \x01000001 | 2.350989e-38 | 2.350989e-38 | \x01000001 | t
+ \x01102843 | 2.647751e-38 | 2.647751e-38 | \x01102843 | t
+ \x01a52c98 | 6.0675416e-38 | 6.0675416e-38 | \x01a52c98 | t
+ \x0219c229 | 1.1296386e-37 | 1.1296386e-37 | \x0219c229 | t
+ \x02e4464d | 3.354194e-37 | 3.354194e-37 | \x02e4464d | t
+ \x037343c1 | 7.148906e-37 | 7.148906e-37 | \x037343c1 | t
+ \x03a91b36 | 9.939175e-37 | 9.939175e-37 | \x03a91b36 | t
+ \x047ada65 | 2.948764e-36 | 2.948764e-36 | \x047ada65 | t
+ \x0496fe87 | 3.5498577e-36 | 3.5498577e-36 | \x0496fe87 | t
+ \x0550844f | 9.804414e-36 | 9.804414e-36 | \x0550844f | t
+ \x05999da3 | 1.4445957e-35 | 1.4445957e-35 | \x05999da3 | t
+ \x060ea5e2 | 2.6829103e-35 | 2.6829103e-35 | \x060ea5e2 | t
+ \x06e63c45 | 8.660494e-35 | 8.660494e-35 | \x06e63c45 | t
+ \x07f1e548 | 3.639641e-34 | 3.639641e-34 | \x07f1e548 | t
+ \x0fc5282b | 1.9441172e-29 | 1.9441172e-29 | \x0fc5282b | t
+ \x1f850283 | 5.6331846e-20 | 5.6331846e-20 | \x1f850283 | t
+ \x2874a9d6 | 1.3581548e-14 | 1.3581548e-14 | \x2874a9d6 | t
+ \x3356bf94 | 4.9999997e-08 | 4.9999997e-08 | \x3356bf94 | t
+ \x3356bf95 | 5e-08 | 5e-08 | \x3356bf95 | t
+ \x3356bf96 | 5.0000004e-08 | 5.0000004e-08 | \x3356bf96 | t
+ \x33d6bf94 | 9.9999994e-08 | 9.9999994e-08 | \x33d6bf94 | t
+ \x33d6bf95 | 1e-07 | 1e-07 | \x33d6bf95 | t
+ \x33d6bf96 | 1.0000001e-07 | 1.0000001e-07 | \x33d6bf96 | t
+ \x34a10faf | 2.9999998e-07 | 2.9999998e-07 | \x34a10faf | t
+ \x34a10fb0 | 3e-07 | 3e-07 | \x34a10fb0 | t
+ \x34a10fb1 | 3.0000004e-07 | 3.0000004e-07 | \x34a10fb1 | t
+ \x350637bc | 4.9999994e-07 | 4.9999994e-07 | \x350637bc | t
+ \x350637bd | 5e-07 | 5e-07 | \x350637bd | t
+ \x350637be | 5.0000006e-07 | 5.0000006e-07 | \x350637be | t
+ \x35719786 | 8.999999e-07 | 8.999999e-07 | \x35719786 | t
+ \x35719787 | 9e-07 | 9e-07 | \x35719787 | t
+ \x35719788 | 9.0000003e-07 | 9.0000003e-07 | \x35719788 | t
+ \x358637bc | 9.999999e-07 | 9.999999e-07 | \x358637bc | t
+ \x358637bd | 1e-06 | 1e-06 | \x358637bd | t
+ \x358637be | 1.0000001e-06 | 1.0000001e-06 | \x358637be | t
+ \x36a7c5ab | 4.9999994e-06 | 4.9999994e-06 | \x36a7c5ab | t
+ \x36a7c5ac | 5e-06 | 5e-06 | \x36a7c5ac | t
+ \x36a7c5ad | 5.0000003e-06 | 5.0000003e-06 | \x36a7c5ad | t
+ \x3727c5ab | 9.999999e-06 | 9.999999e-06 | \x3727c5ab | t
+ \x3727c5ac | 1e-05 | 1e-05 | \x3727c5ac | t
+ \x3727c5ad | 1.0000001e-05 | 1.0000001e-05 | \x3727c5ad | t
+ \x38d1b714 | 9.9999976e-05 | 9.9999976e-05 | \x38d1b714 | t
+ \x38d1b715 | 9.999998e-05 | 9.999998e-05 | \x38d1b715 | t
+ \x38d1b716 | 9.999999e-05 | 9.999999e-05 | \x38d1b716 | t
+ \x38d1b717 | 0.0001 | 0.0001 | \x38d1b717 | t
+ \x38d1b718 | 0.000100000005 | 0.000100000005 | \x38d1b718 | t
+ \x38d1b719 | 0.00010000001 | 0.00010000001 | \x38d1b719 | t
+ \x38d1b71a | 0.00010000002 | 0.00010000002 | \x38d1b71a | t
+ \x38d1b71b | 0.00010000003 | 0.00010000003 | \x38d1b71b | t
+ \x38d1b71c | 0.000100000034 | 0.000100000034 | \x38d1b71c | t
+ \x38d1b71d | 0.00010000004 | 0.00010000004 | \x38d1b71d | t
+ \x38dffffe | 0.00010681151 | 0.00010681151 | \x38dffffe | t
+ \x38dfffff | 0.000106811516 | 0.000106811516 | \x38dfffff | t
+ \x38e00000 | 0.00010681152 | 0.00010681152 | \x38e00000 | t
+ \x38efffff | 0.00011444091 | 0.00011444091 | \x38efffff | t
+ \x38f00000 | 0.00011444092 | 0.00011444092 | \x38f00000 | t
+ \x38f00001 | 0.000114440925 | 0.000114440925 | \x38f00001 | t
+ \x3a83126e | 0.0009999999 | 0.0009999999 | \x3a83126e | t
+ \x3a83126f | 0.001 | 0.001 | \x3a83126f | t
+ \x3a831270 | 0.0010000002 | 0.0010000002 | \x3a831270 | t
+ \x3c23d709 | 0.009999999 | 0.009999999 | \x3c23d709 | t
+ \x3c23d70a | 0.01 | 0.01 | \x3c23d70a | t
+ \x3c23d70b | 0.010000001 | 0.010000001 | \x3c23d70b | t
+ \x3dcccccc | 0.099999994 | 0.099999994 | \x3dcccccc | t
+ \x3dcccccd | 0.1 | 0.1 | \x3dcccccd | t
+ \x3dccccce | 0.10000001 | 0.10000001 | \x3dccccce | t
+ \x3dcccd6f | 0.10000121 | 0.10000121 | \x3dcccd6f | t
+ \x3dcccd70 | 0.100001216 | 0.100001216 | \x3dcccd70 | t
+ \x3dcccd71 | 0.10000122 | 0.10000122 | \x3dcccd71 | t
+ \x3effffff | 0.49999997 | 0.49999997 | \x3effffff | t
+ \x3f000000 | 0.5 | 0.5 | \x3f000000 | t
+ \x3f000001 | 0.50000006 | 0.50000006 | \x3f000001 | t
+ \x3f333332 | 0.6999999 | 0.6999999 | \x3f333332 | t
+ \x3f333333 | 0.7 | 0.7 | \x3f333333 | t
+ \x3f333334 | 0.70000005 | 0.70000005 | \x3f333334 | t
+ \x3f666665 | 0.8999999 | 0.8999999 | \x3f666665 | t
+ \x3f666666 | 0.9 | 0.9 | \x3f666666 | t
+ \x3f666667 | 0.90000004 | 0.90000004 | \x3f666667 | t
+ \x3f7d70a3 | 0.98999995 | 0.98999995 | \x3f7d70a3 | t
+ \x3f7d70a4 | 0.99 | 0.99 | \x3f7d70a4 | t
+ \x3f7d70a5 | 0.99000007 | 0.99000007 | \x3f7d70a5 | t
+ \x3f7fbe76 | 0.99899995 | 0.99899995 | \x3f7fbe76 | t
+ \x3f7fbe77 | 0.999 | 0.999 | \x3f7fbe77 | t
+ \x3f7fbe78 | 0.9990001 | 0.9990001 | \x3f7fbe78 | t
+ \x3f7ff971 | 0.9998999 | 0.9998999 | \x3f7ff971 | t
+ \x3f7ff972 | 0.9999 | 0.9999 | \x3f7ff972 | t
+ \x3f7ff973 | 0.99990004 | 0.99990004 | \x3f7ff973 | t
+ \x3f7fff57 | 0.9999899 | 0.9999899 | \x3f7fff57 | t
+ \x3f7fff58 | 0.99999 | 0.99999 | \x3f7fff58 | t
+ \x3f7fff59 | 0.99999005 | 0.99999005 | \x3f7fff59 | t
+ \x3f7fffee | 0.9999989 | 0.9999989 | \x3f7fffee | t
+ \x3f7fffef | 0.999999 | 0.999999 | \x3f7fffef | t
+ \x3f7ffff0 | 0.99999905 | 0.99999905 | \x3f7ffff0 | t
+ \x3f7ffff1 | 0.9999991 | 0.9999991 | \x3f7ffff1 | t
+ \x3f7ffff2 | 0.99999917 | 0.99999917 | \x3f7ffff2 | t
+ \x3f7ffff3 | 0.9999992 | 0.9999992 | \x3f7ffff3 | t
+ \x3f7ffff4 | 0.9999993 | 0.9999993 | \x3f7ffff4 | t
+ \x3f7ffff5 | 0.99999934 | 0.99999934 | \x3f7ffff5 | t
+ \x3f7ffff6 | 0.9999994 | 0.9999994 | \x3f7ffff6 | t
+ \x3f7ffff7 | 0.99999946 | 0.99999946 | \x3f7ffff7 | t
+ \x3f7ffff8 | 0.9999995 | 0.9999995 | \x3f7ffff8 | t
+ \x3f7ffff9 | 0.9999996 | 0.9999996 | \x3f7ffff9 | t
+ \x3f7ffffa | 0.99999964 | 0.99999964 | \x3f7ffffa | t
+ \x3f7ffffb | 0.9999997 | 0.9999997 | \x3f7ffffb | t
+ \x3f7ffffc | 0.99999976 | 0.99999976 | \x3f7ffffc | t
+ \x3f7ffffd | 0.9999998 | 0.9999998 | \x3f7ffffd | t
+ \x3f7ffffe | 0.9999999 | 0.9999999 | \x3f7ffffe | t
+ \x3f7fffff | 0.99999994 | 0.99999994 | \x3f7fffff | t
+ \x3f800000 | 1 | 1 | \x3f800000 | t
+ \x3f800001 | 1.0000001 | 1.0000001 | \x3f800001 | t
+ \x3f800002 | 1.0000002 | 1.0000002 | \x3f800002 | t
+ \x3f800003 | 1.0000004 | 1.0000004 | \x3f800003 | t
+ \x3f800004 | 1.0000005 | 1.0000005 | \x3f800004 | t
+ \x3f800005 | 1.0000006 | 1.0000006 | \x3f800005 | t
+ \x3f800006 | 1.0000007 | 1.0000007 | \x3f800006 | t
+ \x3f800007 | 1.0000008 | 1.0000008 | \x3f800007 | t
+ \x3f800008 | 1.000001 | 1.000001 | \x3f800008 | t
+ \x3f800009 | 1.0000011 | 1.0000011 | \x3f800009 | t
+ \x3f80000f | 1.0000018 | 1.0000018 | \x3f80000f | t
+ \x3f800010 | 1.0000019 | 1.0000019 | \x3f800010 | t
+ \x3f800011 | 1.000002 | 1.000002 | \x3f800011 | t
+ \x3f800012 | 1.0000021 | 1.0000021 | \x3f800012 | t
+ \x3f800013 | 1.0000023 | 1.0000023 | \x3f800013 | t
+ \x3f800014 | 1.0000024 | 1.0000024 | \x3f800014 | t
+ \x3f800017 | 1.0000027 | 1.0000027 | \x3f800017 | t
+ \x3f800018 | 1.0000029 | 1.0000029 | \x3f800018 | t
+ \x3f800019 | 1.000003 | 1.000003 | \x3f800019 | t
+ \x3f80001a | 1.0000031 | 1.0000031 | \x3f80001a | t
+ \x3f80001b | 1.0000032 | 1.0000032 | \x3f80001b | t
+ \x3f80001c | 1.0000033 | 1.0000033 | \x3f80001c | t
+ \x3f800029 | 1.0000049 | 1.0000049 | \x3f800029 | t
+ \x3f80002a | 1.000005 | 1.000005 | \x3f80002a | t
+ \x3f80002b | 1.0000051 | 1.0000051 | \x3f80002b | t
+ \x3f800053 | 1.0000099 | 1.0000099 | \x3f800053 | t
+ \x3f800054 | 1.00001 | 1.00001 | \x3f800054 | t
+ \x3f800055 | 1.0000101 | 1.0000101 | \x3f800055 | t
+ \x3f800346 | 1.0000999 | 1.0000999 | \x3f800346 | t
+ \x3f800347 | 1.0001 | 1.0001 | \x3f800347 | t
+ \x3f800348 | 1.0001001 | 1.0001001 | \x3f800348 | t
+ \x3f8020c4 | 1.0009999 | 1.0009999 | \x3f8020c4 | t
+ \x3f8020c5 | 1.001 | 1.001 | \x3f8020c5 | t
+ \x3f8020c6 | 1.0010002 | 1.0010002 | \x3f8020c6 | t
+ \x3f8147ad | 1.0099999 | 1.0099999 | \x3f8147ad | t
+ \x3f8147ae | 1.01 | 1.01 | \x3f8147ae | t
+ \x3f8147af | 1.0100001 | 1.0100001 | \x3f8147af | t
+ \x3f8ccccc | 1.0999999 | 1.0999999 | \x3f8ccccc | t
+ \x3f8ccccd | 1.1 | 1.1 | \x3f8ccccd | t
+ \x3f8cccce | 1.1000001 | 1.1000001 | \x3f8cccce | t
+ \x3fc90fdb | 1.5707964 | 1.5707964 | \x3fc90fdb | t
+ \x402df854 | 2.7182817 | 2.7182817 | \x402df854 | t
+ \x40490fdb | 3.1415927 | 3.1415927 | \x40490fdb | t
+ \x409fffff | 4.9999995 | 4.9999995 | \x409fffff | t
+ \x40a00000 | 5 | 5 | \x40a00000 | t
+ \x40a00001 | 5.0000005 | 5.0000005 | \x40a00001 | t
+ \x40afffff | 5.4999995 | 5.4999995 | \x40afffff | t
+ \x40b00000 | 5.5 | 5.5 | \x40b00000 | t
+ \x40b00001 | 5.5000005 | 5.5000005 | \x40b00001 | t
+ \x411fffff | 9.999999 | 9.999999 | \x411fffff | t
+ \x41200000 | 10 | 10 | \x41200000 | t
+ \x41200001 | 10.000001 | 10.000001 | \x41200001 | t
+ \x42c7ffff | 99.99999 | 99.99999 | \x42c7ffff | t
+ \x42c80000 | 100 | 100 | \x42c80000 | t
+ \x42c80001 | 100.00001 | 100.00001 | \x42c80001 | t
+ \x4479ffff | 999.99994 | 999.99994 | \x4479ffff | t
+ \x447a0000 | 1000 | 1000 | \x447a0000 | t
+ \x447a0001 | 1000.00006 | 1000.00006 | \x447a0001 | t
+ \x461c3fff | 9999.999 | 9999.999 | \x461c3fff | t
+ \x461c4000 | 10000 | 10000 | \x461c4000 | t
+ \x461c4001 | 10000.001 | 10000.001 | \x461c4001 | t
+ \x47c34fff | 99999.99 | 99999.99 | \x47c34fff | t
+ \x47c35000 | 100000 | 100000 | \x47c35000 | t
+ \x47c35001 | 100000.01 | 100000.01 | \x47c35001 | t
+ \x497423ff | 999999.94 | 999999.94 | \x497423ff | t
+ \x49742400 | 1e+06 | 1e+06 | \x49742400 | t
+ \x49742401 | 1.00000006e+06 | 1.00000006e+06 | \x49742401 | t
+ \x4b18967f | 9.999999e+06 | 9.999999e+06 | \x4b18967f | t
+ \x4b189680 | 1e+07 | 1e+07 | \x4b189680 | t
+ \x4b189681 | 1.0000001e+07 | 1.0000001e+07 | \x4b189681 | t
+ \x4cbebc1f | 9.999999e+07 | 9.999999e+07 | \x4cbebc1f | t
+ \x4cbebc20 | 1e+08 | 1e+08 | \x4cbebc20 | t
+ \x4cbebc21 | 1.0000001e+08 | 1.0000001e+08 | \x4cbebc21 | t
+ \x4e6e6b27 | 9.9999994e+08 | 9.9999994e+08 | \x4e6e6b27 | t
+ \x4e6e6b28 | 1e+09 | 1e+09 | \x4e6e6b28 | t
+ \x4e6e6b29 | 1.00000006e+09 | 1.00000006e+09 | \x4e6e6b29 | t
+ \x501502f8 | 9.999999e+09 | 9.999999e+09 | \x501502f8 | t
+ \x501502f9 | 1e+10 | 1e+10 | \x501502f9 | t
+ \x501502fa | 1.0000001e+10 | 1.0000001e+10 | \x501502fa | t
+ \x51ba43b6 | 9.999999e+10 | 9.999999e+10 | \x51ba43b6 | t
+ \x51ba43b7 | 1e+11 | 1e+11 | \x51ba43b7 | t
+ \x51ba43b8 | 1.0000001e+11 | 1.0000001e+11 | \x51ba43b8 | t
+ \x1f6c1e4a | 5e-20 | 5e-20 | \x1f6c1e4a | t
+ \x59be6cea | 6.7e+15 | 6.7e+15 | \x59be6cea | t
+ \x5d5ab6c4 | 9.85e+17 | 9.85e+17 | \x5d5ab6c4 | t
+ \x2cc4a9bd | 5.5895e-12 | 5.5895e-12 | \x2cc4a9bd | t
+ \x15ae43fd | 7.038531e-26 | 7.0385313e-26 | \x15ae43fe | f
+ \x2cf757ca | 7.0299088e-12 | 7.0299088e-12 | \x2cf757ca | t
+ \x665ba998 | 2.5933168e+23 | 2.5933168e+23 | \x665ba998 | t
+ \x743c3324 | 5.9642887e+31 | 5.9642887e+31 | \x743c3324 | t
+ \x47f1205a | 123456.7 | 123456.7 | \x47f1205a | t
+ \x4640e6ae | 12345.67 | 12345.67 | \x4640e6ae | t
+ \x449a5225 | 1234.567 | 1234.567 | \x449a5225 | t
+ \x42f6e9d5 | 123.4567 | 123.4567 | \x42f6e9d5 | t
+ \x414587dd | 12.34567 | 12.34567 | \x414587dd | t
+ \x3f9e064b | 1.234567 | 1.234567 | \x3f9e064b | t
+ \x4c000004 | 3.3554448e+07 | 3.3554448e+07 | \x4c000004 | t
+ \x50061c46 | 8.999999e+09 | 8.999999e+09 | \x50061c46 | t
+ \x510006a8 | 3.4366718e+10 | 3.4366718e+10 | \x510006a8 | t
+ \x48951f84 | 305404.12 | 305404.12 | \x48951f84 | t
+ \x45fd1840 | 8099.0312 | 8099.0312 | \x45fd1840 | t
+ \x39800000 | 0.00024414062 | 0.00024414062 | \x39800000 | t
+ \x3b200000 | 0.0024414062 | 0.0024414062 | \x3b200000 | t
+ \x3b900000 | 0.0043945312 | 0.0043945312 | \x3b900000 | t
+ \x3bd00000 | 0.0063476562 | 0.0063476562 | \x3bd00000 | t
+ \x63800000 | 4.7223665e+21 | 4.7223665e+21 | \x63800000 | t
+ \x4b000000 | 8.388608e+06 | 8.388608e+06 | \x4b000000 | t
+ \x4b800000 | 1.6777216e+07 | 1.6777216e+07 | \x4b800000 | t
+ \x4c000001 | 3.3554436e+07 | 3.3554436e+07 | \x4c000001 | t
+ \x4c800b0d | 6.7131496e+07 | 6.7131496e+07 | \x4c800b0d | t
+ \x00d24584 | 1.9310392e-38 | 1.9310392e-38 | \x00d24584 | t
+ \x800000b0 | -2.47e-43 | -2.47e-43 | \x800000b0 | t
+ \x00d90b88 | 1.993244e-38 | 1.993244e-38 | \x00d90b88 | t
+ \x45803f34 | 4103.9004 | 4103.9004 | \x45803f34 | t
+ \x4f9f24f7 | 5.3399997e+09 | 5.3399997e+09 | \x4f9f24f7 | t
+ \x3a8722c3 | 0.0010310042 | 0.0010310042 | \x3a8722c3 | t
+ \x5c800041 | 2.882326e+17 | 2.882326e+17 | \x5c800041 | t
+ \x15ae43fd | 7.038531e-26 | 7.0385313e-26 | \x15ae43fe | f
+ \x5d4cccfb | 9.223404e+17 | 9.223404e+17 | \x5d4cccfb | t
+ \x4c800001 | 6.710887e+07 | 6.710887e+07 | \x4c800001 | t
+ \x57800ed8 | 2.816025e+14 | 2.816025e+14 | \x57800ed8 | t
+ \x5f000000 | 9.223372e+18 | 9.223372e+18 | \x5f000000 | t
+ \x700000f0 | 1.5846086e+29 | 1.5846086e+29 | \x700000f0 | t
+ \x5f23e9ac | 1.1811161e+19 | 1.1811161e+19 | \x5f23e9ac | t
+ \x5e9502f9 | 5.368709e+18 | 5.368709e+18 | \x5e9502f9 | t
+ \x5e8012b1 | 4.6143166e+18 | 4.6143166e+18 | \x5e8012b1 | t
+ \x3c000028 | 0.007812537 | 0.007812537 | \x3c000028 | t
+ \x60cde861 | 1.18697725e+20 | 1.18697725e+20 | \x60cde861 | t
+ \x03aa2a50 | 1.00014165e-36 | 1.00014165e-36 | \x03aa2a50 | t
+ \x43480000 | 200 | 200 | \x43480000 | t
+ \x4c000000 | 3.3554432e+07 | 3.3554432e+07 | \x4c000000 | t
+ \x5d1502f9 | 6.7108864e+17 | 6.7108864e+17 | \x5d1502f9 | t
+ \x5d9502f9 | 1.3421773e+18 | 1.3421773e+18 | \x5d9502f9 | t
+ \x5e1502f9 | 2.6843546e+18 | 2.6843546e+18 | \x5e1502f9 | t
+ \x3f99999a | 1.2 | 1.2 | \x3f99999a | t
+ \x3f9d70a4 | 1.23 | 1.23 | \x3f9d70a4 | t
+ \x3f9df3b6 | 1.234 | 1.234 | \x3f9df3b6 | t
+ \x3f9e0419 | 1.2345 | 1.2345 | \x3f9e0419 | t
+ \x3f9e0610 | 1.23456 | 1.23456 | \x3f9e0610 | t
+ \x3f9e064b | 1.234567 | 1.234567 | \x3f9e064b | t
+ \x3f9e0651 | 1.2345678 | 1.2345678 | \x3f9e0651 | t
+ \x03d20cfe | 1.23456735e-36 | 1.23456735e-36 | \x03d20cfe | t
+(262 rows)
+
+-- clean up, lest opr_sanity complain
+\set VERBOSITY terse
+drop type xfloat4 cascade;
+NOTICE: drop cascades to 6 other objects
+\set VERBOSITY default
+--
diff --git a/src/test/regress/expected/float4.out b/src/test/regress/expected/float4.out
index 9b8b4d4280..dff1921944 100644
--- a/src/test/regress/expected/float4.out
+++ b/src/test/regress/expected/float4.out
@@ -142,22 +142,22 @@ SELECT 'nan'::numeric::float4;
(1 row)
SELECT '' AS five, * FROM FLOAT4_TBL;
- five | f1
-------+-------------
- | 0
- | 1004.3
- | -34.84
- | 1.23457e+20
- | 1.23457e-20
+ five | f1
+------+---------------
+ | 0
+ | 1004.3
+ | -34.84
+ | 1.2345679e+20
+ | 1.2345679e-20
(5 rows)
SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <> '1004.3';
- four | f1
-------+-------------
- | 0
- | -34.84
- | 1.23457e+20
- | 1.23457e-20
+ four | f1
+------+---------------
+ | 0
+ | -34.84
+ | 1.2345679e+20
+ | 1.2345679e-20
(4 rows)
SELECT '' AS one, f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3';
@@ -167,110 +167,110 @@ SELECT '' AS one, f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3';
(1 row)
SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE '1004.3' > f.f1;
- three | f1
--------+-------------
- | 0
- | -34.84
- | 1.23457e-20
+ three | f1
+-------+---------------
+ | 0
+ | -34.84
+ | 1.2345679e-20
(3 rows)
SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE f.f1 < '1004.3';
- three | f1
--------+-------------
- | 0
- | -34.84
- | 1.23457e-20
+ three | f1
+-------+---------------
+ | 0
+ | -34.84
+ | 1.2345679e-20
(3 rows)
SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE '1004.3' >= f.f1;
- four | f1
-------+-------------
- | 0
- | 1004.3
- | -34.84
- | 1.23457e-20
+ four | f1
+------+---------------
+ | 0
+ | 1004.3
+ | -34.84
+ | 1.2345679e-20
(4 rows)
SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <= '1004.3';
- four | f1
-------+-------------
- | 0
- | 1004.3
- | -34.84
- | 1.23457e-20
+ four | f1
+------+---------------
+ | 0
+ | 1004.3
+ | -34.84
+ | 1.2345679e-20
(4 rows)
SELECT '' AS three, f.f1, f.f1 * '-10' AS x FROM FLOAT4_TBL f
WHERE f.f1 > '0.0';
- three | f1 | x
--------+-------------+--------------
- | 1004.3 | -10043
- | 1.23457e+20 | -1.23457e+21
- | 1.23457e-20 | -1.23457e-19
+ three | f1 | x
+-------+---------------+----------------
+ | 1004.3 | -10043
+ | 1.2345679e+20 | -1.2345678e+21
+ | 1.2345679e-20 | -1.2345678e-19
(3 rows)
SELECT '' AS three, f.f1, f.f1 + '-10' AS x FROM FLOAT4_TBL f
WHERE f.f1 > '0.0';
- three | f1 | x
--------+-------------+-------------
- | 1004.3 | 994.3
- | 1.23457e+20 | 1.23457e+20
- | 1.23457e-20 | -10
+ three | f1 | x
+-------+---------------+---------------
+ | 1004.3 | 994.3
+ | 1.2345679e+20 | 1.2345679e+20
+ | 1.2345679e-20 | -10
(3 rows)
SELECT '' AS three, f.f1, f.f1 / '-10' AS x FROM FLOAT4_TBL f
WHERE f.f1 > '0.0';
- three | f1 | x
--------+-------------+--------------
- | 1004.3 | -100.43
- | 1.23457e+20 | -1.23457e+19
- | 1.23457e-20 | -1.23457e-21
+ three | f1 | x
+-------+---------------+----------------
+ | 1004.3 | -100.43
+ | 1.2345679e+20 | -1.2345679e+19
+ | 1.2345679e-20 | -1.2345679e-21
(3 rows)
SELECT '' AS three, f.f1, f.f1 - '-10' AS x FROM FLOAT4_TBL f
WHERE f.f1 > '0.0';
- three | f1 | x
--------+-------------+-------------
- | 1004.3 | 1014.3
- | 1.23457e+20 | 1.23457e+20
- | 1.23457e-20 | 10
+ three | f1 | x
+-------+---------------+---------------
+ | 1004.3 | 1014.3
+ | 1.2345679e+20 | 1.2345679e+20
+ | 1.2345679e-20 | 10
(3 rows)
-- test divide by zero
SELECT '' AS bad, f.f1 / '0.0' from FLOAT4_TBL f;
ERROR: division by zero
SELECT '' AS five, * FROM FLOAT4_TBL;
- five | f1
-------+-------------
- | 0
- | 1004.3
- | -34.84
- | 1.23457e+20
- | 1.23457e-20
+ five | f1
+------+---------------
+ | 0
+ | 1004.3
+ | -34.84
+ | 1.2345679e+20
+ | 1.2345679e-20
(5 rows)
-- test the unary float4abs operator
SELECT '' AS five, f.f1, @f.f1 AS abs_f1 FROM FLOAT4_TBL f;
- five | f1 | abs_f1
-------+-------------+-------------
- | 0 | 0
- | 1004.3 | 1004.3
- | -34.84 | 34.84
- | 1.23457e+20 | 1.23457e+20
- | 1.23457e-20 | 1.23457e-20
+ five | f1 | abs_f1
+------+---------------+---------------
+ | 0 | 0
+ | 1004.3 | 1004.3
+ | -34.84 | 34.84
+ | 1.2345679e+20 | 1.2345679e+20
+ | 1.2345679e-20 | 1.2345679e-20
(5 rows)
UPDATE FLOAT4_TBL
SET f1 = FLOAT4_TBL.f1 * '-1'
WHERE FLOAT4_TBL.f1 > '0.0';
SELECT '' AS five, * FROM FLOAT4_TBL;
- five | f1
-------+--------------
- | 0
- | -34.84
- | -1004.3
- | -1.23457e+20
- | -1.23457e-20
+ five | f1
+------+----------------
+ | 0
+ | -34.84
+ | -1004.3
+ | -1.2345679e+20
+ | -1.2345679e-20
(5 rows)
-- test edge-case coercions to integer
@@ -434,3 +434,507 @@ SELECT float4send('1.1754944e-38'::float4);
\x00800000
(1 row)
+-- test output (and round-trip safety) of various values.
+-- To ensure we're testing what we think we're testing, start with
+-- float values specified by bit patterns (as a useful side effect,
+-- this means we'll fail on non-IEEE platforms).
+create type xfloat4;
+create function xfloat4in(cstring) returns xfloat4 immutable strict
+ language internal as 'int4in';
+NOTICE: return type xfloat4 is only a shell
+create function xfloat4out(xfloat4) returns cstring immutable strict
+ language internal as 'int4out';
+NOTICE: argument type xfloat4 is only a shell
+create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4);
+create cast (xfloat4 as float4) without function;
+create cast (float4 as xfloat4) without function;
+create cast (xfloat4 as integer) without function;
+create cast (integer as xfloat4) without function;
+-- float4: seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
+-- we don't care to assume the platform's strtod() handles subnormals
+-- correctly; those are "use at your own risk". However we do test
+-- subnormal outputs, since those are under our control.
+with testdata(bits) as (values
+ -- small subnormals
+ (x'00000001'),
+ (x'00000002'), (x'00000003'),
+ (x'00000010'), (x'00000011'), (x'00000100'), (x'00000101'),
+ (x'00004000'), (x'00004001'), (x'00080000'), (x'00080001'),
+ -- stress values
+ (x'0053c4f4'), -- 7693e-42
+ (x'006c85c4'), -- 996622e-44
+ (x'0041ca76'), -- 60419369e-46
+ (x'004b7678'), -- 6930161142e-48
+ -- taken from upstream testsuite
+ (x'00000007'),
+ (x'00424fe2'),
+ -- borderline between subnormal and normal
+ (x'007ffff0'), (x'007ffff1'), (x'007ffffe'), (x'007fffff'))
+select float4send(flt) as ibits,
+ flt
+ from (select bits::integer::xfloat4::float4 as flt
+ from testdata
+ offset 0) s;
+ ibits | flt
+------------+---------------
+ \x00000001 | 1e-45
+ \x00000002 | 3e-45
+ \x00000003 | 4e-45
+ \x00000010 | 2.2e-44
+ \x00000011 | 2.4e-44
+ \x00000100 | 3.59e-43
+ \x00000101 | 3.6e-43
+ \x00004000 | 2.2959e-41
+ \x00004001 | 2.296e-41
+ \x00080000 | 7.34684e-40
+ \x00080001 | 7.34685e-40
+ \x0053c4f4 | 7.693e-39
+ \x006c85c4 | 9.96622e-39
+ \x0041ca76 | 6.041937e-39
+ \x004b7678 | 6.930161e-39
+ \x00000007 | 1e-44
+ \x00424fe2 | 6.0898e-39
+ \x007ffff0 | 1.1754921e-38
+ \x007ffff1 | 1.1754922e-38
+ \x007ffffe | 1.1754941e-38
+ \x007fffff | 1.1754942e-38
+(21 rows)
+
+with testdata(bits) as (values
+ (x'00000000'),
+ -- smallest normal values
+ (x'00800000'), (x'00800001'), (x'00800004'), (x'00800005'),
+ (x'00800006'),
+ -- small normal values chosen for short vs. long output
+ (x'008002f1'), (x'008002f2'), (x'008002f3'),
+ (x'00800e17'), (x'00800e18'), (x'00800e19'),
+ -- assorted values (random mantissae)
+ (x'01000001'), (x'01102843'), (x'01a52c98'),
+ (x'0219c229'), (x'02e4464d'), (x'037343c1'), (x'03a91b36'),
+ (x'047ada65'), (x'0496fe87'), (x'0550844f'), (x'05999da3'),
+ (x'060ea5e2'), (x'06e63c45'), (x'07f1e548'), (x'0fc5282b'),
+ (x'1f850283'), (x'2874a9d6'),
+ -- values around 5e-08
+ (x'3356bf94'), (x'3356bf95'), (x'3356bf96'),
+ -- around 1e-07
+ (x'33d6bf94'), (x'33d6bf95'), (x'33d6bf96'),
+ -- around 3e-07 .. 1e-04
+ (x'34a10faf'), (x'34a10fb0'), (x'34a10fb1'),
+ (x'350637bc'), (x'350637bd'), (x'350637be'),
+ (x'35719786'), (x'35719787'), (x'35719788'),
+ (x'358637bc'), (x'358637bd'), (x'358637be'),
+ (x'36a7c5ab'), (x'36a7c5ac'), (x'36a7c5ad'),
+ (x'3727c5ab'), (x'3727c5ac'), (x'3727c5ad'),
+ -- format crossover at 1e-04
+ (x'38d1b714'), (x'38d1b715'), (x'38d1b716'),
+ (x'38d1b717'), (x'38d1b718'), (x'38d1b719'),
+ (x'38d1b71a'), (x'38d1b71b'), (x'38d1b71c'),
+ (x'38d1b71d'),
+ --
+ (x'38dffffe'), (x'38dfffff'), (x'38e00000'),
+ (x'38efffff'), (x'38f00000'), (x'38f00001'),
+ (x'3a83126e'), (x'3a83126f'), (x'3a831270'),
+ (x'3c23d709'), (x'3c23d70a'), (x'3c23d70b'),
+ (x'3dcccccc'), (x'3dcccccd'), (x'3dccccce'),
+ -- chosen to need 9 digits for 3dcccd70
+ (x'3dcccd6f'), (x'3dcccd70'), (x'3dcccd71'),
+ --
+ (x'3effffff'), (x'3f000000'), (x'3f000001'),
+ (x'3f333332'), (x'3f333333'), (x'3f333334'),
+ -- approach 1.0 with increasing numbers of 9s
+ (x'3f666665'), (x'3f666666'), (x'3f666667'),
+ (x'3f7d70a3'), (x'3f7d70a4'), (x'3f7d70a5'),
+ (x'3f7fbe76'), (x'3f7fbe77'), (x'3f7fbe78'),
+ (x'3f7ff971'), (x'3f7ff972'), (x'3f7ff973'),
+ (x'3f7fff57'), (x'3f7fff58'), (x'3f7fff59'),
+ (x'3f7fffee'), (x'3f7fffef'),
+ -- values very close to 1
+ (x'3f7ffff0'), (x'3f7ffff1'), (x'3f7ffff2'),
+ (x'3f7ffff3'), (x'3f7ffff4'), (x'3f7ffff5'),
+ (x'3f7ffff6'), (x'3f7ffff7'), (x'3f7ffff8'),
+ (x'3f7ffff9'), (x'3f7ffffa'), (x'3f7ffffb'),
+ (x'3f7ffffc'), (x'3f7ffffd'), (x'3f7ffffe'),
+ (x'3f7fffff'),
+ (x'3f800000'),
+ (x'3f800001'), (x'3f800002'), (x'3f800003'),
+ (x'3f800004'), (x'3f800005'), (x'3f800006'),
+ (x'3f800007'), (x'3f800008'), (x'3f800009'),
+ -- values 1 to 1.1
+ (x'3f80000f'), (x'3f800010'), (x'3f800011'),
+ (x'3f800012'), (x'3f800013'), (x'3f800014'),
+ (x'3f800017'), (x'3f800018'), (x'3f800019'),
+ (x'3f80001a'), (x'3f80001b'), (x'3f80001c'),
+ (x'3f800029'), (x'3f80002a'), (x'3f80002b'),
+ (x'3f800053'), (x'3f800054'), (x'3f800055'),
+ (x'3f800346'), (x'3f800347'), (x'3f800348'),
+ (x'3f8020c4'), (x'3f8020c5'), (x'3f8020c6'),
+ (x'3f8147ad'), (x'3f8147ae'), (x'3f8147af'),
+ (x'3f8ccccc'), (x'3f8ccccd'), (x'3f8cccce'),
+ --
+ (x'3fc90fdb'), -- pi/2
+ (x'402df854'), -- e
+ (x'40490fdb'), -- pi
+ --
+ (x'409fffff'), (x'40a00000'), (x'40a00001'),
+ (x'40afffff'), (x'40b00000'), (x'40b00001'),
+ (x'411fffff'), (x'41200000'), (x'41200001'),
+ (x'42c7ffff'), (x'42c80000'), (x'42c80001'),
+ (x'4479ffff'), (x'447a0000'), (x'447a0001'),
+ (x'461c3fff'), (x'461c4000'), (x'461c4001'),
+ (x'47c34fff'), (x'47c35000'), (x'47c35001'),
+ (x'497423ff'), (x'49742400'), (x'49742401'),
+ (x'4b18967f'), (x'4b189680'), (x'4b189681'),
+ (x'4cbebc1f'), (x'4cbebc20'), (x'4cbebc21'),
+ (x'4e6e6b27'), (x'4e6e6b28'), (x'4e6e6b29'),
+ (x'501502f8'), (x'501502f9'), (x'501502fa'),
+ (x'51ba43b6'), (x'51ba43b7'), (x'51ba43b8'),
+ -- stress values
+ (x'1f6c1e4a'), -- 5e-20
+ (x'59be6cea'), -- 67e14
+ (x'5d5ab6c4'), -- 985e15
+ (x'2cc4a9bd'), -- 55895e-16
+ (x'15ae43fd'), -- 7038531e-32
+ (x'2cf757ca'), -- 702990899e-20
+ (x'665ba998'), -- 25933168707e13
+ (x'743c3324'), -- 596428896559e20
+ -- exercise fixed-point memmoves
+ (x'47f1205a'),
+ (x'4640e6ae'),
+ (x'449a5225'),
+ (x'42f6e9d5'),
+ (x'414587dd'),
+ (x'3f9e064b'),
+ -- these cases come from the upstream's testsuite
+ -- BoundaryRoundEven
+ (x'4c000004'),
+ (x'50061c46'),
+ (x'510006a8'),
+ -- ExactValueRoundEven
+ (x'48951f84'),
+ (x'45fd1840'),
+ -- LotsOfTrailingZeros
+ (x'39800000'),
+ (x'3b200000'),
+ (x'3b900000'),
+ (x'3bd00000'),
+ -- Regression
+ (x'63800000'),
+ (x'4b000000'),
+ (x'4b800000'),
+ (x'4c000001'),
+ (x'4c800b0d'),
+ (x'00d24584'),
+ (x'800000b0'),
+ (x'00d90b88'),
+ (x'45803f34'),
+ (x'4f9f24f7'),
+ (x'3a8722c3'),
+ (x'5c800041'),
+ (x'15ae43fd'),
+ (x'5d4cccfb'),
+ (x'4c800001'),
+ (x'57800ed8'),
+ (x'5f000000'),
+ (x'700000f0'),
+ (x'5f23e9ac'),
+ (x'5e9502f9'),
+ (x'5e8012b1'),
+ (x'3c000028'),
+ (x'60cde861'),
+ (x'03aa2a50'),
+ (x'43480000'),
+ (x'4c000000'),
+ -- LooksLikePow5
+ (x'5D1502F9'),
+ (x'5D9502F9'),
+ (x'5E1502F9'),
+ -- OutputLength
+ (x'3f99999a'),
+ (x'3f9d70a4'),
+ (x'3f9df3b6'),
+ (x'3f9e0419'),
+ (x'3f9e0610'),
+ (x'3f9e064b'),
+ (x'3f9e0651'),
+ (x'03d20cfe')
+)
+select float4send(flt) as ibits,
+ flt,
+ flt::text::float4 as r_flt,
+ float4send(flt::text::float4) as obits,
+ float4send(flt::text::float4) = float4send(flt) as correct
+ from (select bits::integer::xfloat4::float4 as flt
+ from testdata
+ offset 0) s;
+ ibits | flt | r_flt | obits | correct
+------------+----------------+----------------+------------+---------
+ \x00000000 | 0 | 0 | \x00000000 | t
+ \x00800000 | 1.1754944e-38 | 1.1754944e-38 | \x00800000 | t
+ \x00800001 | 1.1754945e-38 | 1.1754945e-38 | \x00800001 | t
+ \x00800004 | 1.1754949e-38 | 1.1754949e-38 | \x00800004 | t
+ \x00800005 | 1.175495e-38 | 1.175495e-38 | \x00800005 | t
+ \x00800006 | 1.1754952e-38 | 1.1754952e-38 | \x00800006 | t
+ \x008002f1 | 1.1755999e-38 | 1.1755999e-38 | \x008002f1 | t
+ \x008002f2 | 1.1756e-38 | 1.1756e-38 | \x008002f2 | t
+ \x008002f3 | 1.1756001e-38 | 1.1756001e-38 | \x008002f3 | t
+ \x00800e17 | 1.1759998e-38 | 1.1759998e-38 | \x00800e17 | t
+ \x00800e18 | 1.176e-38 | 1.176e-38 | \x00800e18 | t
+ \x00800e19 | 1.1760001e-38 | 1.1760001e-38 | \x00800e19 | t
+ \x01000001 | 2.350989e-38 | 2.350989e-38 | \x01000001 | t
+ \x01102843 | 2.647751e-38 | 2.647751e-38 | \x01102843 | t
+ \x01a52c98 | 6.0675416e-38 | 6.0675416e-38 | \x01a52c98 | t
+ \x0219c229 | 1.1296386e-37 | 1.1296386e-37 | \x0219c229 | t
+ \x02e4464d | 3.354194e-37 | 3.354194e-37 | \x02e4464d | t
+ \x037343c1 | 7.148906e-37 | 7.148906e-37 | \x037343c1 | t
+ \x03a91b36 | 9.939175e-37 | 9.939175e-37 | \x03a91b36 | t
+ \x047ada65 | 2.948764e-36 | 2.948764e-36 | \x047ada65 | t
+ \x0496fe87 | 3.5498577e-36 | 3.5498577e-36 | \x0496fe87 | t
+ \x0550844f | 9.804414e-36 | 9.804414e-36 | \x0550844f | t
+ \x05999da3 | 1.4445957e-35 | 1.4445957e-35 | \x05999da3 | t
+ \x060ea5e2 | 2.6829103e-35 | 2.6829103e-35 | \x060ea5e2 | t
+ \x06e63c45 | 8.660494e-35 | 8.660494e-35 | \x06e63c45 | t
+ \x07f1e548 | 3.639641e-34 | 3.639641e-34 | \x07f1e548 | t
+ \x0fc5282b | 1.9441172e-29 | 1.9441172e-29 | \x0fc5282b | t
+ \x1f850283 | 5.6331846e-20 | 5.6331846e-20 | \x1f850283 | t
+ \x2874a9d6 | 1.3581548e-14 | 1.3581548e-14 | \x2874a9d6 | t
+ \x3356bf94 | 4.9999997e-08 | 4.9999997e-08 | \x3356bf94 | t
+ \x3356bf95 | 5e-08 | 5e-08 | \x3356bf95 | t
+ \x3356bf96 | 5.0000004e-08 | 5.0000004e-08 | \x3356bf96 | t
+ \x33d6bf94 | 9.9999994e-08 | 9.9999994e-08 | \x33d6bf94 | t
+ \x33d6bf95 | 1e-07 | 1e-07 | \x33d6bf95 | t
+ \x33d6bf96 | 1.0000001e-07 | 1.0000001e-07 | \x33d6bf96 | t
+ \x34a10faf | 2.9999998e-07 | 2.9999998e-07 | \x34a10faf | t
+ \x34a10fb0 | 3e-07 | 3e-07 | \x34a10fb0 | t
+ \x34a10fb1 | 3.0000004e-07 | 3.0000004e-07 | \x34a10fb1 | t
+ \x350637bc | 4.9999994e-07 | 4.9999994e-07 | \x350637bc | t
+ \x350637bd | 5e-07 | 5e-07 | \x350637bd | t
+ \x350637be | 5.0000006e-07 | 5.0000006e-07 | \x350637be | t
+ \x35719786 | 8.999999e-07 | 8.999999e-07 | \x35719786 | t
+ \x35719787 | 9e-07 | 9e-07 | \x35719787 | t
+ \x35719788 | 9.0000003e-07 | 9.0000003e-07 | \x35719788 | t
+ \x358637bc | 9.999999e-07 | 9.999999e-07 | \x358637bc | t
+ \x358637bd | 1e-06 | 1e-06 | \x358637bd | t
+ \x358637be | 1.0000001e-06 | 1.0000001e-06 | \x358637be | t
+ \x36a7c5ab | 4.9999994e-06 | 4.9999994e-06 | \x36a7c5ab | t
+ \x36a7c5ac | 5e-06 | 5e-06 | \x36a7c5ac | t
+ \x36a7c5ad | 5.0000003e-06 | 5.0000003e-06 | \x36a7c5ad | t
+ \x3727c5ab | 9.999999e-06 | 9.999999e-06 | \x3727c5ab | t
+ \x3727c5ac | 1e-05 | 1e-05 | \x3727c5ac | t
+ \x3727c5ad | 1.0000001e-05 | 1.0000001e-05 | \x3727c5ad | t
+ \x38d1b714 | 9.9999976e-05 | 9.9999976e-05 | \x38d1b714 | t
+ \x38d1b715 | 9.999998e-05 | 9.999998e-05 | \x38d1b715 | t
+ \x38d1b716 | 9.999999e-05 | 9.999999e-05 | \x38d1b716 | t
+ \x38d1b717 | 0.0001 | 0.0001 | \x38d1b717 | t
+ \x38d1b718 | 0.000100000005 | 0.000100000005 | \x38d1b718 | t
+ \x38d1b719 | 0.00010000001 | 0.00010000001 | \x38d1b719 | t
+ \x38d1b71a | 0.00010000002 | 0.00010000002 | \x38d1b71a | t
+ \x38d1b71b | 0.00010000003 | 0.00010000003 | \x38d1b71b | t
+ \x38d1b71c | 0.000100000034 | 0.000100000034 | \x38d1b71c | t
+ \x38d1b71d | 0.00010000004 | 0.00010000004 | \x38d1b71d | t
+ \x38dffffe | 0.00010681151 | 0.00010681151 | \x38dffffe | t
+ \x38dfffff | 0.000106811516 | 0.000106811516 | \x38dfffff | t
+ \x38e00000 | 0.00010681152 | 0.00010681152 | \x38e00000 | t
+ \x38efffff | 0.00011444091 | 0.00011444091 | \x38efffff | t
+ \x38f00000 | 0.00011444092 | 0.00011444092 | \x38f00000 | t
+ \x38f00001 | 0.000114440925 | 0.000114440925 | \x38f00001 | t
+ \x3a83126e | 0.0009999999 | 0.0009999999 | \x3a83126e | t
+ \x3a83126f | 0.001 | 0.001 | \x3a83126f | t
+ \x3a831270 | 0.0010000002 | 0.0010000002 | \x3a831270 | t
+ \x3c23d709 | 0.009999999 | 0.009999999 | \x3c23d709 | t
+ \x3c23d70a | 0.01 | 0.01 | \x3c23d70a | t
+ \x3c23d70b | 0.010000001 | 0.010000001 | \x3c23d70b | t
+ \x3dcccccc | 0.099999994 | 0.099999994 | \x3dcccccc | t
+ \x3dcccccd | 0.1 | 0.1 | \x3dcccccd | t
+ \x3dccccce | 0.10000001 | 0.10000001 | \x3dccccce | t
+ \x3dcccd6f | 0.10000121 | 0.10000121 | \x3dcccd6f | t
+ \x3dcccd70 | 0.100001216 | 0.100001216 | \x3dcccd70 | t
+ \x3dcccd71 | 0.10000122 | 0.10000122 | \x3dcccd71 | t
+ \x3effffff | 0.49999997 | 0.49999997 | \x3effffff | t
+ \x3f000000 | 0.5 | 0.5 | \x3f000000 | t
+ \x3f000001 | 0.50000006 | 0.50000006 | \x3f000001 | t
+ \x3f333332 | 0.6999999 | 0.6999999 | \x3f333332 | t
+ \x3f333333 | 0.7 | 0.7 | \x3f333333 | t
+ \x3f333334 | 0.70000005 | 0.70000005 | \x3f333334 | t
+ \x3f666665 | 0.8999999 | 0.8999999 | \x3f666665 | t
+ \x3f666666 | 0.9 | 0.9 | \x3f666666 | t
+ \x3f666667 | 0.90000004 | 0.90000004 | \x3f666667 | t
+ \x3f7d70a3 | 0.98999995 | 0.98999995 | \x3f7d70a3 | t
+ \x3f7d70a4 | 0.99 | 0.99 | \x3f7d70a4 | t
+ \x3f7d70a5 | 0.99000007 | 0.99000007 | \x3f7d70a5 | t
+ \x3f7fbe76 | 0.99899995 | 0.99899995 | \x3f7fbe76 | t
+ \x3f7fbe77 | 0.999 | 0.999 | \x3f7fbe77 | t
+ \x3f7fbe78 | 0.9990001 | 0.9990001 | \x3f7fbe78 | t
+ \x3f7ff971 | 0.9998999 | 0.9998999 | \x3f7ff971 | t
+ \x3f7ff972 | 0.9999 | 0.9999 | \x3f7ff972 | t
+ \x3f7ff973 | 0.99990004 | 0.99990004 | \x3f7ff973 | t
+ \x3f7fff57 | 0.9999899 | 0.9999899 | \x3f7fff57 | t
+ \x3f7fff58 | 0.99999 | 0.99999 | \x3f7fff58 | t
+ \x3f7fff59 | 0.99999005 | 0.99999005 | \x3f7fff59 | t
+ \x3f7fffee | 0.9999989 | 0.9999989 | \x3f7fffee | t
+ \x3f7fffef | 0.999999 | 0.999999 | \x3f7fffef | t
+ \x3f7ffff0 | 0.99999905 | 0.99999905 | \x3f7ffff0 | t
+ \x3f7ffff1 | 0.9999991 | 0.9999991 | \x3f7ffff1 | t
+ \x3f7ffff2 | 0.99999917 | 0.99999917 | \x3f7ffff2 | t
+ \x3f7ffff3 | 0.9999992 | 0.9999992 | \x3f7ffff3 | t
+ \x3f7ffff4 | 0.9999993 | 0.9999993 | \x3f7ffff4 | t
+ \x3f7ffff5 | 0.99999934 | 0.99999934 | \x3f7ffff5 | t
+ \x3f7ffff6 | 0.9999994 | 0.9999994 | \x3f7ffff6 | t
+ \x3f7ffff7 | 0.99999946 | 0.99999946 | \x3f7ffff7 | t
+ \x3f7ffff8 | 0.9999995 | 0.9999995 | \x3f7ffff8 | t
+ \x3f7ffff9 | 0.9999996 | 0.9999996 | \x3f7ffff9 | t
+ \x3f7ffffa | 0.99999964 | 0.99999964 | \x3f7ffffa | t
+ \x3f7ffffb | 0.9999997 | 0.9999997 | \x3f7ffffb | t
+ \x3f7ffffc | 0.99999976 | 0.99999976 | \x3f7ffffc | t
+ \x3f7ffffd | 0.9999998 | 0.9999998 | \x3f7ffffd | t
+ \x3f7ffffe | 0.9999999 | 0.9999999 | \x3f7ffffe | t
+ \x3f7fffff | 0.99999994 | 0.99999994 | \x3f7fffff | t
+ \x3f800000 | 1 | 1 | \x3f800000 | t
+ \x3f800001 | 1.0000001 | 1.0000001 | \x3f800001 | t
+ \x3f800002 | 1.0000002 | 1.0000002 | \x3f800002 | t
+ \x3f800003 | 1.0000004 | 1.0000004 | \x3f800003 | t
+ \x3f800004 | 1.0000005 | 1.0000005 | \x3f800004 | t
+ \x3f800005 | 1.0000006 | 1.0000006 | \x3f800005 | t
+ \x3f800006 | 1.0000007 | 1.0000007 | \x3f800006 | t
+ \x3f800007 | 1.0000008 | 1.0000008 | \x3f800007 | t
+ \x3f800008 | 1.000001 | 1.000001 | \x3f800008 | t
+ \x3f800009 | 1.0000011 | 1.0000011 | \x3f800009 | t
+ \x3f80000f | 1.0000018 | 1.0000018 | \x3f80000f | t
+ \x3f800010 | 1.0000019 | 1.0000019 | \x3f800010 | t
+ \x3f800011 | 1.000002 | 1.000002 | \x3f800011 | t
+ \x3f800012 | 1.0000021 | 1.0000021 | \x3f800012 | t
+ \x3f800013 | 1.0000023 | 1.0000023 | \x3f800013 | t
+ \x3f800014 | 1.0000024 | 1.0000024 | \x3f800014 | t
+ \x3f800017 | 1.0000027 | 1.0000027 | \x3f800017 | t
+ \x3f800018 | 1.0000029 | 1.0000029 | \x3f800018 | t
+ \x3f800019 | 1.000003 | 1.000003 | \x3f800019 | t
+ \x3f80001a | 1.0000031 | 1.0000031 | \x3f80001a | t
+ \x3f80001b | 1.0000032 | 1.0000032 | \x3f80001b | t
+ \x3f80001c | 1.0000033 | 1.0000033 | \x3f80001c | t
+ \x3f800029 | 1.0000049 | 1.0000049 | \x3f800029 | t
+ \x3f80002a | 1.000005 | 1.000005 | \x3f80002a | t
+ \x3f80002b | 1.0000051 | 1.0000051 | \x3f80002b | t
+ \x3f800053 | 1.0000099 | 1.0000099 | \x3f800053 | t
+ \x3f800054 | 1.00001 | 1.00001 | \x3f800054 | t
+ \x3f800055 | 1.0000101 | 1.0000101 | \x3f800055 | t
+ \x3f800346 | 1.0000999 | 1.0000999 | \x3f800346 | t
+ \x3f800347 | 1.0001 | 1.0001 | \x3f800347 | t
+ \x3f800348 | 1.0001001 | 1.0001001 | \x3f800348 | t
+ \x3f8020c4 | 1.0009999 | 1.0009999 | \x3f8020c4 | t
+ \x3f8020c5 | 1.001 | 1.001 | \x3f8020c5 | t
+ \x3f8020c6 | 1.0010002 | 1.0010002 | \x3f8020c6 | t
+ \x3f8147ad | 1.0099999 | 1.0099999 | \x3f8147ad | t
+ \x3f8147ae | 1.01 | 1.01 | \x3f8147ae | t
+ \x3f8147af | 1.0100001 | 1.0100001 | \x3f8147af | t
+ \x3f8ccccc | 1.0999999 | 1.0999999 | \x3f8ccccc | t
+ \x3f8ccccd | 1.1 | 1.1 | \x3f8ccccd | t
+ \x3f8cccce | 1.1000001 | 1.1000001 | \x3f8cccce | t
+ \x3fc90fdb | 1.5707964 | 1.5707964 | \x3fc90fdb | t
+ \x402df854 | 2.7182817 | 2.7182817 | \x402df854 | t
+ \x40490fdb | 3.1415927 | 3.1415927 | \x40490fdb | t
+ \x409fffff | 4.9999995 | 4.9999995 | \x409fffff | t
+ \x40a00000 | 5 | 5 | \x40a00000 | t
+ \x40a00001 | 5.0000005 | 5.0000005 | \x40a00001 | t
+ \x40afffff | 5.4999995 | 5.4999995 | \x40afffff | t
+ \x40b00000 | 5.5 | 5.5 | \x40b00000 | t
+ \x40b00001 | 5.5000005 | 5.5000005 | \x40b00001 | t
+ \x411fffff | 9.999999 | 9.999999 | \x411fffff | t
+ \x41200000 | 10 | 10 | \x41200000 | t
+ \x41200001 | 10.000001 | 10.000001 | \x41200001 | t
+ \x42c7ffff | 99.99999 | 99.99999 | \x42c7ffff | t
+ \x42c80000 | 100 | 100 | \x42c80000 | t
+ \x42c80001 | 100.00001 | 100.00001 | \x42c80001 | t
+ \x4479ffff | 999.99994 | 999.99994 | \x4479ffff | t
+ \x447a0000 | 1000 | 1000 | \x447a0000 | t
+ \x447a0001 | 1000.00006 | 1000.00006 | \x447a0001 | t
+ \x461c3fff | 9999.999 | 9999.999 | \x461c3fff | t
+ \x461c4000 | 10000 | 10000 | \x461c4000 | t
+ \x461c4001 | 10000.001 | 10000.001 | \x461c4001 | t
+ \x47c34fff | 99999.99 | 99999.99 | \x47c34fff | t
+ \x47c35000 | 100000 | 100000 | \x47c35000 | t
+ \x47c35001 | 100000.01 | 100000.01 | \x47c35001 | t
+ \x497423ff | 999999.94 | 999999.94 | \x497423ff | t
+ \x49742400 | 1e+06 | 1e+06 | \x49742400 | t
+ \x49742401 | 1.00000006e+06 | 1.00000006e+06 | \x49742401 | t
+ \x4b18967f | 9.999999e+06 | 9.999999e+06 | \x4b18967f | t
+ \x4b189680 | 1e+07 | 1e+07 | \x4b189680 | t
+ \x4b189681 | 1.0000001e+07 | 1.0000001e+07 | \x4b189681 | t
+ \x4cbebc1f | 9.999999e+07 | 9.999999e+07 | \x4cbebc1f | t
+ \x4cbebc20 | 1e+08 | 1e+08 | \x4cbebc20 | t
+ \x4cbebc21 | 1.0000001e+08 | 1.0000001e+08 | \x4cbebc21 | t
+ \x4e6e6b27 | 9.9999994e+08 | 9.9999994e+08 | \x4e6e6b27 | t
+ \x4e6e6b28 | 1e+09 | 1e+09 | \x4e6e6b28 | t
+ \x4e6e6b29 | 1.00000006e+09 | 1.00000006e+09 | \x4e6e6b29 | t
+ \x501502f8 | 9.999999e+09 | 9.999999e+09 | \x501502f8 | t
+ \x501502f9 | 1e+10 | 1e+10 | \x501502f9 | t
+ \x501502fa | 1.0000001e+10 | 1.0000001e+10 | \x501502fa | t
+ \x51ba43b6 | 9.999999e+10 | 9.999999e+10 | \x51ba43b6 | t
+ \x51ba43b7 | 1e+11 | 1e+11 | \x51ba43b7 | t
+ \x51ba43b8 | 1.0000001e+11 | 1.0000001e+11 | \x51ba43b8 | t
+ \x1f6c1e4a | 5e-20 | 5e-20 | \x1f6c1e4a | t
+ \x59be6cea | 6.7e+15 | 6.7e+15 | \x59be6cea | t
+ \x5d5ab6c4 | 9.85e+17 | 9.85e+17 | \x5d5ab6c4 | t
+ \x2cc4a9bd | 5.5895e-12 | 5.5895e-12 | \x2cc4a9bd | t
+ \x15ae43fd | 7.038531e-26 | 7.038531e-26 | \x15ae43fd | t
+ \x2cf757ca | 7.0299088e-12 | 7.0299088e-12 | \x2cf757ca | t
+ \x665ba998 | 2.5933168e+23 | 2.5933168e+23 | \x665ba998 | t
+ \x743c3324 | 5.9642887e+31 | 5.9642887e+31 | \x743c3324 | t
+ \x47f1205a | 123456.7 | 123456.7 | \x47f1205a | t
+ \x4640e6ae | 12345.67 | 12345.67 | \x4640e6ae | t
+ \x449a5225 | 1234.567 | 1234.567 | \x449a5225 | t
+ \x42f6e9d5 | 123.4567 | 123.4567 | \x42f6e9d5 | t
+ \x414587dd | 12.34567 | 12.34567 | \x414587dd | t
+ \x3f9e064b | 1.234567 | 1.234567 | \x3f9e064b | t
+ \x4c000004 | 3.3554448e+07 | 3.3554448e+07 | \x4c000004 | t
+ \x50061c46 | 8.999999e+09 | 8.999999e+09 | \x50061c46 | t
+ \x510006a8 | 3.4366718e+10 | 3.4366718e+10 | \x510006a8 | t
+ \x48951f84 | 305404.12 | 305404.12 | \x48951f84 | t
+ \x45fd1840 | 8099.0312 | 8099.0312 | \x45fd1840 | t
+ \x39800000 | 0.00024414062 | 0.00024414062 | \x39800000 | t
+ \x3b200000 | 0.0024414062 | 0.0024414062 | \x3b200000 | t
+ \x3b900000 | 0.0043945312 | 0.0043945312 | \x3b900000 | t
+ \x3bd00000 | 0.0063476562 | 0.0063476562 | \x3bd00000 | t
+ \x63800000 | 4.7223665e+21 | 4.7223665e+21 | \x63800000 | t
+ \x4b000000 | 8.388608e+06 | 8.388608e+06 | \x4b000000 | t
+ \x4b800000 | 1.6777216e+07 | 1.6777216e+07 | \x4b800000 | t
+ \x4c000001 | 3.3554436e+07 | 3.3554436e+07 | \x4c000001 | t
+ \x4c800b0d | 6.7131496e+07 | 6.7131496e+07 | \x4c800b0d | t
+ \x00d24584 | 1.9310392e-38 | 1.9310392e-38 | \x00d24584 | t
+ \x800000b0 | -2.47e-43 | -2.47e-43 | \x800000b0 | t
+ \x00d90b88 | 1.993244e-38 | 1.993244e-38 | \x00d90b88 | t
+ \x45803f34 | 4103.9004 | 4103.9004 | \x45803f34 | t
+ \x4f9f24f7 | 5.3399997e+09 | 5.3399997e+09 | \x4f9f24f7 | t
+ \x3a8722c3 | 0.0010310042 | 0.0010310042 | \x3a8722c3 | t
+ \x5c800041 | 2.882326e+17 | 2.882326e+17 | \x5c800041 | t
+ \x15ae43fd | 7.038531e-26 | 7.038531e-26 | \x15ae43fd | t
+ \x5d4cccfb | 9.223404e+17 | 9.223404e+17 | \x5d4cccfb | t
+ \x4c800001 | 6.710887e+07 | 6.710887e+07 | \x4c800001 | t
+ \x57800ed8 | 2.816025e+14 | 2.816025e+14 | \x57800ed8 | t
+ \x5f000000 | 9.223372e+18 | 9.223372e+18 | \x5f000000 | t
+ \x700000f0 | 1.5846086e+29 | 1.5846086e+29 | \x700000f0 | t
+ \x5f23e9ac | 1.1811161e+19 | 1.1811161e+19 | \x5f23e9ac | t
+ \x5e9502f9 | 5.368709e+18 | 5.368709e+18 | \x5e9502f9 | t
+ \x5e8012b1 | 4.6143166e+18 | 4.6143166e+18 | \x5e8012b1 | t
+ \x3c000028 | 0.007812537 | 0.007812537 | \x3c000028 | t
+ \x60cde861 | 1.18697725e+20 | 1.18697725e+20 | \x60cde861 | t
+ \x03aa2a50 | 1.00014165e-36 | 1.00014165e-36 | \x03aa2a50 | t
+ \x43480000 | 200 | 200 | \x43480000 | t
+ \x4c000000 | 3.3554432e+07 | 3.3554432e+07 | \x4c000000 | t
+ \x5d1502f9 | 6.7108864e+17 | 6.7108864e+17 | \x5d1502f9 | t
+ \x5d9502f9 | 1.3421773e+18 | 1.3421773e+18 | \x5d9502f9 | t
+ \x5e1502f9 | 2.6843546e+18 | 2.6843546e+18 | \x5e1502f9 | t
+ \x3f99999a | 1.2 | 1.2 | \x3f99999a | t
+ \x3f9d70a4 | 1.23 | 1.23 | \x3f9d70a4 | t
+ \x3f9df3b6 | 1.234 | 1.234 | \x3f9df3b6 | t
+ \x3f9e0419 | 1.2345 | 1.2345 | \x3f9e0419 | t
+ \x3f9e0610 | 1.23456 | 1.23456 | \x3f9e0610 | t
+ \x3f9e064b | 1.234567 | 1.234567 | \x3f9e064b | t
+ \x3f9e0651 | 1.2345678 | 1.2345678 | \x3f9e0651 | t
+ \x03d20cfe | 1.23456735e-36 | 1.23456735e-36 | \x03d20cfe | t
+(262 rows)
+
+-- clean up, lest opr_sanity complain
+\set VERBOSITY terse
+drop type xfloat4 cascade;
+NOTICE: drop cascades to 6 other objects
+\set VERBOSITY default
+--
diff --git a/src/test/regress/expected/float8-small-is-zero.out b/src/test/regress/expected/float8-small-is-zero.out
index 1c3bbae6b8..f67c22e9fa 100644
--- a/src/test/regress/expected/float8-small-is-zero.out
+++ b/src/test/regress/expected/float8-small-is-zero.out
@@ -28,6 +28,13 @@ SELECT '-10e-400'::float8;
-0
(1 row)
+-- test smallest normalized input
+SELECT float8send('2.2250738585072014E-308'::float8);
+ float8send
+--------------------
+ \x0010000000000000
+(1 row)
+
-- bad input
INSERT INTO FLOAT8_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type double precision: ""
@@ -213,7 +220,7 @@ SELECT '' AS three, f.f1, f.f1 / '-10' AS x
WHERE f.f1 > '0.0';
three | f1 | x
-------+----------------------+-----------------------
- | 1004.3 | -100.43
+ | 1004.3 | -100.42999999999999
| 1.2345678901234e+200 | -1.2345678901234e+199
| 1.2345678901234e-200 | -1.2345678901234e-201
(3 rows)
@@ -230,9 +237,9 @@ SELECT '' AS three, f.f1, f.f1 - '-10' AS x
SELECT '' AS one, f.f1 ^ '2.0' AS square_f1
FROM FLOAT8_TBL f where f.f1 = '1004.3';
- one | square_f1
------+------------
- | 1008618.49
+ one | square_f1
+-----+--------------------
+ | 1008618.4899999999
(1 row)
-- absolute value
@@ -314,6 +321,8 @@ select sign(f1) as sign_f1 from float8_tbl f;
1
(5 rows)
+-- avoid bit-exact output here because operations may not be bit-exact.
+SET extra_float_digits = 0;
-- square root
SELECT sqrt(float8 '64') AS eight;
eight
@@ -449,6 +458,7 @@ SELECT '' AS five, * FROM FLOAT8_TBL;
| -1.2345678901234e-200
(5 rows)
+RESET extra_float_digits;
-- test for over- and underflow
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
ERROR: "10e400" is out of range for type double precision
@@ -528,7 +538,6 @@ SELECT '-9223372036854775808.5'::float8::int8;
SELECT '-9223372036854780000'::float8::int8;
ERROR: bigint out of range
-- test exact cases for trigonometric functions in degrees
-SET extra_float_digits = 3;
SELECT x,
sind(x),
sind(x) IN (-1,-0.5,0,0.5,1) AS sind_exact
@@ -630,4 +639,432 @@ FROM (SELECT 10*cosd(a), 10*sind(a)
10 | 0 | 0 | t
(5 rows)
-RESET extra_float_digits;
+--
+-- test output (and round-trip safety) of various values.
+-- To ensure we're testing what we think we're testing, start with
+-- float values specified by bit patterns (as a useful side effect,
+-- this means we'll fail on non-IEEE platforms).
+create type xfloat8;
+create function xfloat8in(cstring) returns xfloat8 immutable strict
+ language internal as 'int8in';
+NOTICE: return type xfloat8 is only a shell
+create function xfloat8out(xfloat8) returns cstring immutable strict
+ language internal as 'int8out';
+NOTICE: argument type xfloat8 is only a shell
+create type xfloat8 (input = xfloat8in, output = xfloat8out, like = float8);
+create cast (xfloat8 as float8) without function;
+create cast (float8 as xfloat8) without function;
+create cast (xfloat8 as bigint) without function;
+create cast (bigint as xfloat8) without function;
+-- float8: seeeeeee eeeeeeee eeeeeeee mmmmmmmm mmmmmmmm(x4)
+-- we don't care to assume the platform's strtod() handles subnormals
+-- correctly; those are "use at your own risk". However we do test
+-- subnormal outputs, since those are under our control.
+with testdata(bits) as (values
+ -- small subnormals
+ (x'0000000000000001'),
+ (x'0000000000000002'), (x'0000000000000003'),
+ (x'0000000000001000'), (x'0000000100000000'),
+ (x'0000010000000000'), (x'0000010100000000'),
+ (x'0000400000000000'), (x'0000400100000000'),
+ (x'0000800000000000'), (x'0000800000000001'),
+ -- these values taken from upstream testsuite
+ (x'00000000000f4240'),
+ (x'00000000016e3600'),
+ (x'0000008cdcdea440'),
+ -- borderline between subnormal and normal
+ (x'000ffffffffffff0'), (x'000ffffffffffff1'),
+ (x'000ffffffffffffe'), (x'000fffffffffffff'))
+select float8send(flt) as ibits,
+ flt
+ from (select bits::bigint::xfloat8::float8 as flt
+ from testdata
+ offset 0) s;
+ ibits | flt
+--------------------+-------------------------
+ \x0000000000000001 | 5e-324
+ \x0000000000000002 | 1e-323
+ \x0000000000000003 | 1.5e-323
+ \x0000000000001000 | 2.0237e-320
+ \x0000000100000000 | 2.121995791e-314
+ \x0000010000000000 | 5.43230922487e-312
+ \x0000010100000000 | 5.45352918278e-312
+ \x0000400000000000 | 3.4766779039175e-310
+ \x0000400100000000 | 3.4768901034966e-310
+ \x0000800000000000 | 6.953355807835e-310
+ \x0000800000000001 | 6.95335580783505e-310
+ \x00000000000f4240 | 4.940656e-318
+ \x00000000016e3600 | 1.18575755e-316
+ \x0000008cdcdea440 | 2.989102097996e-312
+ \x000ffffffffffff0 | 2.2250738585071935e-308
+ \x000ffffffffffff1 | 2.225073858507194e-308
+ \x000ffffffffffffe | 2.2250738585072004e-308
+ \x000fffffffffffff | 2.225073858507201e-308
+(18 rows)
+
+-- round-trip tests
+with testdata(bits) as (values
+ (x'0000000000000000'),
+ -- smallest normal values
+ (x'0010000000000000'), (x'0010000000000001'),
+ (x'0010000000000002'), (x'0018000000000000'),
+ --
+ (x'3ddb7cdfd9d7bdba'), (x'3ddb7cdfd9d7bdbb'), (x'3ddb7cdfd9d7bdbc'),
+ (x'3e112e0be826d694'), (x'3e112e0be826d695'), (x'3e112e0be826d696'),
+ (x'3e45798ee2308c39'), (x'3e45798ee2308c3a'), (x'3e45798ee2308c3b'),
+ (x'3e7ad7f29abcaf47'), (x'3e7ad7f29abcaf48'), (x'3e7ad7f29abcaf49'),
+ (x'3eb0c6f7a0b5ed8c'), (x'3eb0c6f7a0b5ed8d'), (x'3eb0c6f7a0b5ed8e'),
+ (x'3ee4f8b588e368ef'), (x'3ee4f8b588e368f0'), (x'3ee4f8b588e368f1'),
+ (x'3f1a36e2eb1c432c'), (x'3f1a36e2eb1c432d'), (x'3f1a36e2eb1c432e'),
+ (x'3f50624dd2f1a9fb'), (x'3f50624dd2f1a9fc'), (x'3f50624dd2f1a9fd'),
+ (x'3f847ae147ae147a'), (x'3f847ae147ae147b'), (x'3f847ae147ae147c'),
+ (x'3fb9999999999999'), (x'3fb999999999999a'), (x'3fb999999999999b'),
+ -- values very close to 1
+ (x'3feffffffffffff0'), (x'3feffffffffffff1'), (x'3feffffffffffff2'),
+ (x'3feffffffffffff3'), (x'3feffffffffffff4'), (x'3feffffffffffff5'),
+ (x'3feffffffffffff6'), (x'3feffffffffffff7'), (x'3feffffffffffff8'),
+ (x'3feffffffffffff9'), (x'3feffffffffffffa'), (x'3feffffffffffffb'),
+ (x'3feffffffffffffc'), (x'3feffffffffffffd'), (x'3feffffffffffffe'),
+ (x'3fefffffffffffff'),
+ (x'3ff0000000000000'),
+ (x'3ff0000000000001'), (x'3ff0000000000002'), (x'3ff0000000000003'),
+ (x'3ff0000000000004'), (x'3ff0000000000005'), (x'3ff0000000000006'),
+ (x'3ff0000000000007'), (x'3ff0000000000008'), (x'3ff0000000000009'),
+ --
+ (x'3ff921fb54442d18'),
+ (x'4005bf0a8b14576a'),
+ (x'400921fb54442d18'),
+ --
+ (x'4023ffffffffffff'), (x'4024000000000000'), (x'4024000000000001'),
+ (x'4058ffffffffffff'), (x'4059000000000000'), (x'4059000000000001'),
+ (x'408f3fffffffffff'), (x'408f400000000000'), (x'408f400000000001'),
+ (x'40c387ffffffffff'), (x'40c3880000000000'), (x'40c3880000000001'),
+ (x'40f869ffffffffff'), (x'40f86a0000000000'), (x'40f86a0000000001'),
+ (x'412e847fffffffff'), (x'412e848000000000'), (x'412e848000000001'),
+ (x'416312cfffffffff'), (x'416312d000000000'), (x'416312d000000001'),
+ (x'4197d783ffffffff'), (x'4197d78400000000'), (x'4197d78400000001'),
+ (x'41cdcd64ffffffff'), (x'41cdcd6500000000'), (x'41cdcd6500000001'),
+ (x'4202a05f1fffffff'), (x'4202a05f20000000'), (x'4202a05f20000001'),
+ (x'42374876e7ffffff'), (x'42374876e8000000'), (x'42374876e8000001'),
+ (x'426d1a94a1ffffff'), (x'426d1a94a2000000'), (x'426d1a94a2000001'),
+ (x'42a2309ce53fffff'), (x'42a2309ce5400000'), (x'42a2309ce5400001'),
+ (x'42d6bcc41e8fffff'), (x'42d6bcc41e900000'), (x'42d6bcc41e900001'),
+ (x'430c6bf52633ffff'), (x'430c6bf526340000'), (x'430c6bf526340001'),
+ (x'4341c37937e07fff'), (x'4341c37937e08000'), (x'4341c37937e08001'),
+ (x'4376345785d89fff'), (x'4376345785d8a000'), (x'4376345785d8a001'),
+ (x'43abc16d674ec7ff'), (x'43abc16d674ec800'), (x'43abc16d674ec801'),
+ (x'43e158e460913cff'), (x'43e158e460913d00'), (x'43e158e460913d01'),
+ (x'4415af1d78b58c3f'), (x'4415af1d78b58c40'), (x'4415af1d78b58c41'),
+ (x'444b1ae4d6e2ef4f'), (x'444b1ae4d6e2ef50'), (x'444b1ae4d6e2ef51'),
+ (x'4480f0cf064dd591'), (x'4480f0cf064dd592'), (x'4480f0cf064dd593'),
+ (x'44b52d02c7e14af5'), (x'44b52d02c7e14af6'), (x'44b52d02c7e14af7'),
+ (x'44ea784379d99db3'), (x'44ea784379d99db4'), (x'44ea784379d99db5'),
+ (x'45208b2a2c280290'), (x'45208b2a2c280291'), (x'45208b2a2c280292'),
+ --
+ (x'7feffffffffffffe'), (x'7fefffffffffffff'),
+ -- round to even tests (+ve)
+ (x'4350000000000002'),
+ (x'4350000000002e06'),
+ (x'4352000000000003'),
+ (x'4352000000000004'),
+ (x'4358000000000003'),
+ (x'4358000000000004'),
+ (x'435f000000000020'),
+ -- round to even tests (-ve)
+ (x'c350000000000002'),
+ (x'c350000000002e06'),
+ (x'c352000000000003'),
+ (x'c352000000000004'),
+ (x'c358000000000003'),
+ (x'c358000000000004'),
+ (x'c35f000000000020'),
+ -- exercise fixed-point memmoves
+ (x'42dc12218377de66'),
+ (x'42a674e79c5fe51f'),
+ (x'4271f71fb04cb74c'),
+ (x'423cbe991a145879'),
+ (x'4206fee0e1a9e061'),
+ (x'41d26580b487e6b4'),
+ (x'419d6f34540ca453'),
+ (x'41678c29dcd6e9dc'),
+ (x'4132d687e3df217d'),
+ (x'40fe240c9fcb68c8'),
+ (x'40c81cd6e63c53d3'),
+ (x'40934a4584fd0fdc'),
+ (x'405edd3c07fb4c93'),
+ (x'4028b0fcd32f7076'),
+ (x'3ff3c0ca428c59f8'),
+ -- these cases come from the upstream's testsuite
+ -- LotsOfTrailingZeros)
+ (x'3e60000000000000'),
+ -- Regression
+ (x'c352bd2668e077c4'),
+ (x'434018601510c000'),
+ (x'43d055dc36f24000'),
+ (x'43e052961c6f8000'),
+ (x'3ff3c0ca2a5b1d5d'),
+ -- LooksLikePow5
+ (x'4830f0cf064dd592'),
+ (x'4840f0cf064dd592'),
+ (x'4850f0cf064dd592'),
+ -- OutputLength
+ (x'3ff3333333333333'),
+ (x'3ff3ae147ae147ae'),
+ (x'3ff3be76c8b43958'),
+ (x'3ff3c083126e978d'),
+ (x'3ff3c0c1fc8f3238'),
+ (x'3ff3c0c9539b8887'),
+ (x'3ff3c0ca2a5b1d5d'),
+ (x'3ff3c0ca4283de1b'),
+ (x'3ff3c0ca43db770a'),
+ (x'3ff3c0ca428abd53'),
+ (x'3ff3c0ca428c1d2b'),
+ (x'3ff3c0ca428c51f2'),
+ (x'3ff3c0ca428c58fc'),
+ (x'3ff3c0ca428c59dd'),
+ (x'3ff3c0ca428c59f8'),
+ (x'3ff3c0ca428c59fb'),
+ -- 32-bit chunking
+ (x'40112e0be8047a7d'),
+ (x'40112e0be815a889'),
+ (x'40112e0be826d695'),
+ (x'40112e0be83804a1'),
+ (x'40112e0be84932ad'),
+ -- MinMaxShift
+ (x'0040000000000000'),
+ (x'007fffffffffffff'),
+ (x'0290000000000000'),
+ (x'029fffffffffffff'),
+ (x'4350000000000000'),
+ (x'435fffffffffffff'),
+ (x'1330000000000000'),
+ (x'133fffffffffffff'),
+ (x'3a6fa7161a4d6e0c')
+)
+select float8send(flt) as ibits,
+ flt,
+ flt::text::float8 as r_flt,
+ float8send(flt::text::float8) as obits,
+ float8send(flt::text::float8) = float8send(flt) as correct
+ from (select bits::bigint::xfloat8::float8 as flt
+ from testdata
+ offset 0) s;
+ ibits | flt | r_flt | obits | correct
+--------------------+-------------------------+-------------------------+--------------------+---------
+ \x0000000000000000 | 0 | 0 | \x0000000000000000 | t
+ \x0010000000000000 | 2.2250738585072014e-308 | 2.2250738585072014e-308 | \x0010000000000000 | t
+ \x0010000000000001 | 2.225073858507202e-308 | 2.225073858507202e-308 | \x0010000000000001 | t
+ \x0010000000000002 | 2.2250738585072024e-308 | 2.2250738585072024e-308 | \x0010000000000002 | t
+ \x0018000000000000 | 3.337610787760802e-308 | 3.337610787760802e-308 | \x0018000000000000 | t
+ \x3ddb7cdfd9d7bdba | 9.999999999999999e-11 | 9.999999999999999e-11 | \x3ddb7cdfd9d7bdba | t
+ \x3ddb7cdfd9d7bdbb | 1e-10 | 1e-10 | \x3ddb7cdfd9d7bdbb | t
+ \x3ddb7cdfd9d7bdbc | 1.0000000000000002e-10 | 1.0000000000000002e-10 | \x3ddb7cdfd9d7bdbc | t
+ \x3e112e0be826d694 | 9.999999999999999e-10 | 9.999999999999999e-10 | \x3e112e0be826d694 | t
+ \x3e112e0be826d695 | 1e-09 | 1e-09 | \x3e112e0be826d695 | t
+ \x3e112e0be826d696 | 1.0000000000000003e-09 | 1.0000000000000003e-09 | \x3e112e0be826d696 | t
+ \x3e45798ee2308c39 | 9.999999999999999e-09 | 9.999999999999999e-09 | \x3e45798ee2308c39 | t
+ \x3e45798ee2308c3a | 1e-08 | 1e-08 | \x3e45798ee2308c3a | t
+ \x3e45798ee2308c3b | 1.0000000000000002e-08 | 1.0000000000000002e-08 | \x3e45798ee2308c3b | t
+ \x3e7ad7f29abcaf47 | 9.999999999999998e-08 | 9.999999999999998e-08 | \x3e7ad7f29abcaf47 | t
+ \x3e7ad7f29abcaf48 | 1e-07 | 1e-07 | \x3e7ad7f29abcaf48 | t
+ \x3e7ad7f29abcaf49 | 1.0000000000000001e-07 | 1.0000000000000001e-07 | \x3e7ad7f29abcaf49 | t
+ \x3eb0c6f7a0b5ed8c | 9.999999999999997e-07 | 9.999999999999997e-07 | \x3eb0c6f7a0b5ed8c | t
+ \x3eb0c6f7a0b5ed8d | 1e-06 | 1e-06 | \x3eb0c6f7a0b5ed8d | t
+ \x3eb0c6f7a0b5ed8e | 1.0000000000000002e-06 | 1.0000000000000002e-06 | \x3eb0c6f7a0b5ed8e | t
+ \x3ee4f8b588e368ef | 9.999999999999997e-06 | 9.999999999999997e-06 | \x3ee4f8b588e368ef | t
+ \x3ee4f8b588e368f0 | 9.999999999999999e-06 | 9.999999999999999e-06 | \x3ee4f8b588e368f0 | t
+ \x3ee4f8b588e368f1 | 1e-05 | 1e-05 | \x3ee4f8b588e368f1 | t
+ \x3f1a36e2eb1c432c | 9.999999999999999e-05 | 9.999999999999999e-05 | \x3f1a36e2eb1c432c | t
+ \x3f1a36e2eb1c432d | 0.0001 | 0.0001 | \x3f1a36e2eb1c432d | t
+ \x3f1a36e2eb1c432e | 0.00010000000000000002 | 0.00010000000000000002 | \x3f1a36e2eb1c432e | t
+ \x3f50624dd2f1a9fb | 0.0009999999999999998 | 0.0009999999999999998 | \x3f50624dd2f1a9fb | t
+ \x3f50624dd2f1a9fc | 0.001 | 0.001 | \x3f50624dd2f1a9fc | t
+ \x3f50624dd2f1a9fd | 0.0010000000000000002 | 0.0010000000000000002 | \x3f50624dd2f1a9fd | t
+ \x3f847ae147ae147a | 0.009999999999999998 | 0.009999999999999998 | \x3f847ae147ae147a | t
+ \x3f847ae147ae147b | 0.01 | 0.01 | \x3f847ae147ae147b | t
+ \x3f847ae147ae147c | 0.010000000000000002 | 0.010000000000000002 | \x3f847ae147ae147c | t
+ \x3fb9999999999999 | 0.09999999999999999 | 0.09999999999999999 | \x3fb9999999999999 | t
+ \x3fb999999999999a | 0.1 | 0.1 | \x3fb999999999999a | t
+ \x3fb999999999999b | 0.10000000000000002 | 0.10000000000000002 | \x3fb999999999999b | t
+ \x3feffffffffffff0 | 0.9999999999999982 | 0.9999999999999982 | \x3feffffffffffff0 | t
+ \x3feffffffffffff1 | 0.9999999999999983 | 0.9999999999999983 | \x3feffffffffffff1 | t
+ \x3feffffffffffff2 | 0.9999999999999984 | 0.9999999999999984 | \x3feffffffffffff2 | t
+ \x3feffffffffffff3 | 0.9999999999999986 | 0.9999999999999986 | \x3feffffffffffff3 | t
+ \x3feffffffffffff4 | 0.9999999999999987 | 0.9999999999999987 | \x3feffffffffffff4 | t
+ \x3feffffffffffff5 | 0.9999999999999988 | 0.9999999999999988 | \x3feffffffffffff5 | t
+ \x3feffffffffffff6 | 0.9999999999999989 | 0.9999999999999989 | \x3feffffffffffff6 | t
+ \x3feffffffffffff7 | 0.999999999999999 | 0.999999999999999 | \x3feffffffffffff7 | t
+ \x3feffffffffffff8 | 0.9999999999999991 | 0.9999999999999991 | \x3feffffffffffff8 | t
+ \x3feffffffffffff9 | 0.9999999999999992 | 0.9999999999999992 | \x3feffffffffffff9 | t
+ \x3feffffffffffffa | 0.9999999999999993 | 0.9999999999999993 | \x3feffffffffffffa | t
+ \x3feffffffffffffb | 0.9999999999999994 | 0.9999999999999994 | \x3feffffffffffffb | t
+ \x3feffffffffffffc | 0.9999999999999996 | 0.9999999999999996 | \x3feffffffffffffc | t
+ \x3feffffffffffffd | 0.9999999999999997 | 0.9999999999999997 | \x3feffffffffffffd | t
+ \x3feffffffffffffe | 0.9999999999999998 | 0.9999999999999998 | \x3feffffffffffffe | t
+ \x3fefffffffffffff | 0.9999999999999999 | 0.9999999999999999 | \x3fefffffffffffff | t
+ \x3ff0000000000000 | 1 | 1 | \x3ff0000000000000 | t
+ \x3ff0000000000001 | 1.0000000000000002 | 1.0000000000000002 | \x3ff0000000000001 | t
+ \x3ff0000000000002 | 1.0000000000000004 | 1.0000000000000004 | \x3ff0000000000002 | t
+ \x3ff0000000000003 | 1.0000000000000007 | 1.0000000000000007 | \x3ff0000000000003 | t
+ \x3ff0000000000004 | 1.0000000000000009 | 1.0000000000000009 | \x3ff0000000000004 | t
+ \x3ff0000000000005 | 1.000000000000001 | 1.000000000000001 | \x3ff0000000000005 | t
+ \x3ff0000000000006 | 1.0000000000000013 | 1.0000000000000013 | \x3ff0000000000006 | t
+ \x3ff0000000000007 | 1.0000000000000016 | 1.0000000000000016 | \x3ff0000000000007 | t
+ \x3ff0000000000008 | 1.0000000000000018 | 1.0000000000000018 | \x3ff0000000000008 | t
+ \x3ff0000000000009 | 1.000000000000002 | 1.000000000000002 | \x3ff0000000000009 | t
+ \x3ff921fb54442d18 | 1.5707963267948966 | 1.5707963267948966 | \x3ff921fb54442d18 | t
+ \x4005bf0a8b14576a | 2.7182818284590455 | 2.7182818284590455 | \x4005bf0a8b14576a | t
+ \x400921fb54442d18 | 3.141592653589793 | 3.141592653589793 | \x400921fb54442d18 | t
+ \x4023ffffffffffff | 9.999999999999998 | 9.999999999999998 | \x4023ffffffffffff | t
+ \x4024000000000000 | 10 | 10 | \x4024000000000000 | t
+ \x4024000000000001 | 10.000000000000002 | 10.000000000000002 | \x4024000000000001 | t
+ \x4058ffffffffffff | 99.99999999999999 | 99.99999999999999 | \x4058ffffffffffff | t
+ \x4059000000000000 | 100 | 100 | \x4059000000000000 | t
+ \x4059000000000001 | 100.00000000000001 | 100.00000000000001 | \x4059000000000001 | t
+ \x408f3fffffffffff | 999.9999999999999 | 999.9999999999999 | \x408f3fffffffffff | t
+ \x408f400000000000 | 1000 | 1000 | \x408f400000000000 | t
+ \x408f400000000001 | 1000.0000000000001 | 1000.0000000000001 | \x408f400000000001 | t
+ \x40c387ffffffffff | 9999.999999999998 | 9999.999999999998 | \x40c387ffffffffff | t
+ \x40c3880000000000 | 10000 | 10000 | \x40c3880000000000 | t
+ \x40c3880000000001 | 10000.000000000002 | 10000.000000000002 | \x40c3880000000001 | t
+ \x40f869ffffffffff | 99999.99999999999 | 99999.99999999999 | \x40f869ffffffffff | t
+ \x40f86a0000000000 | 100000 | 100000 | \x40f86a0000000000 | t
+ \x40f86a0000000001 | 100000.00000000001 | 100000.00000000001 | \x40f86a0000000001 | t
+ \x412e847fffffffff | 999999.9999999999 | 999999.9999999999 | \x412e847fffffffff | t
+ \x412e848000000000 | 1000000 | 1000000 | \x412e848000000000 | t
+ \x412e848000000001 | 1000000.0000000001 | 1000000.0000000001 | \x412e848000000001 | t
+ \x416312cfffffffff | 9999999.999999998 | 9999999.999999998 | \x416312cfffffffff | t
+ \x416312d000000000 | 10000000 | 10000000 | \x416312d000000000 | t
+ \x416312d000000001 | 10000000.000000002 | 10000000.000000002 | \x416312d000000001 | t
+ \x4197d783ffffffff | 99999999.99999999 | 99999999.99999999 | \x4197d783ffffffff | t
+ \x4197d78400000000 | 100000000 | 100000000 | \x4197d78400000000 | t
+ \x4197d78400000001 | 100000000.00000001 | 100000000.00000001 | \x4197d78400000001 | t
+ \x41cdcd64ffffffff | 999999999.9999999 | 999999999.9999999 | \x41cdcd64ffffffff | t
+ \x41cdcd6500000000 | 1000000000 | 1000000000 | \x41cdcd6500000000 | t
+ \x41cdcd6500000001 | 1000000000.0000001 | 1000000000.0000001 | \x41cdcd6500000001 | t
+ \x4202a05f1fffffff | 9999999999.999998 | 9999999999.999998 | \x4202a05f1fffffff | t
+ \x4202a05f20000000 | 10000000000 | 10000000000 | \x4202a05f20000000 | t
+ \x4202a05f20000001 | 10000000000.000002 | 10000000000.000002 | \x4202a05f20000001 | t
+ \x42374876e7ffffff | 99999999999.99998 | 99999999999.99998 | \x42374876e7ffffff | t
+ \x42374876e8000000 | 100000000000 | 100000000000 | \x42374876e8000000 | t
+ \x42374876e8000001 | 100000000000.00002 | 100000000000.00002 | \x42374876e8000001 | t
+ \x426d1a94a1ffffff | 999999999999.9999 | 999999999999.9999 | \x426d1a94a1ffffff | t
+ \x426d1a94a2000000 | 1000000000000 | 1000000000000 | \x426d1a94a2000000 | t
+ \x426d1a94a2000001 | 1000000000000.0001 | 1000000000000.0001 | \x426d1a94a2000001 | t
+ \x42a2309ce53fffff | 9999999999999.998 | 9999999999999.998 | \x42a2309ce53fffff | t
+ \x42a2309ce5400000 | 10000000000000 | 10000000000000 | \x42a2309ce5400000 | t
+ \x42a2309ce5400001 | 10000000000000.002 | 10000000000000.002 | \x42a2309ce5400001 | t
+ \x42d6bcc41e8fffff | 99999999999999.98 | 99999999999999.98 | \x42d6bcc41e8fffff | t
+ \x42d6bcc41e900000 | 100000000000000 | 100000000000000 | \x42d6bcc41e900000 | t
+ \x42d6bcc41e900001 | 100000000000000.02 | 100000000000000.02 | \x42d6bcc41e900001 | t
+ \x430c6bf52633ffff | 999999999999999.9 | 999999999999999.9 | \x430c6bf52633ffff | t
+ \x430c6bf526340000 | 1e+15 | 1e+15 | \x430c6bf526340000 | t
+ \x430c6bf526340001 | 1.0000000000000001e+15 | 1.0000000000000001e+15 | \x430c6bf526340001 | t
+ \x4341c37937e07fff | 9.999999999999998e+15 | 9.999999999999998e+15 | \x4341c37937e07fff | t
+ \x4341c37937e08000 | 1e+16 | 1e+16 | \x4341c37937e08000 | t
+ \x4341c37937e08001 | 1.0000000000000002e+16 | 1.0000000000000002e+16 | \x4341c37937e08001 | t
+ \x4376345785d89fff | 9.999999999999998e+16 | 9.999999999999998e+16 | \x4376345785d89fff | t
+ \x4376345785d8a000 | 1e+17 | 1e+17 | \x4376345785d8a000 | t
+ \x4376345785d8a001 | 1.0000000000000002e+17 | 1.0000000000000002e+17 | \x4376345785d8a001 | t
+ \x43abc16d674ec7ff | 9.999999999999999e+17 | 9.999999999999999e+17 | \x43abc16d674ec7ff | t
+ \x43abc16d674ec800 | 1e+18 | 1e+18 | \x43abc16d674ec800 | t
+ \x43abc16d674ec801 | 1.0000000000000001e+18 | 1.0000000000000001e+18 | \x43abc16d674ec801 | t
+ \x43e158e460913cff | 9.999999999999998e+18 | 9.999999999999998e+18 | \x43e158e460913cff | t
+ \x43e158e460913d00 | 1e+19 | 1e+19 | \x43e158e460913d00 | t
+ \x43e158e460913d01 | 1.0000000000000002e+19 | 1.0000000000000002e+19 | \x43e158e460913d01 | t
+ \x4415af1d78b58c3f | 9.999999999999998e+19 | 9.999999999999998e+19 | \x4415af1d78b58c3f | t
+ \x4415af1d78b58c40 | 1e+20 | 1e+20 | \x4415af1d78b58c40 | t
+ \x4415af1d78b58c41 | 1.0000000000000002e+20 | 1.0000000000000002e+20 | \x4415af1d78b58c41 | t
+ \x444b1ae4d6e2ef4f | 9.999999999999999e+20 | 9.999999999999999e+20 | \x444b1ae4d6e2ef4f | t
+ \x444b1ae4d6e2ef50 | 1e+21 | 1e+21 | \x444b1ae4d6e2ef50 | t
+ \x444b1ae4d6e2ef51 | 1.0000000000000001e+21 | 1.0000000000000001e+21 | \x444b1ae4d6e2ef51 | t
+ \x4480f0cf064dd591 | 9.999999999999998e+21 | 9.999999999999998e+21 | \x4480f0cf064dd591 | t
+ \x4480f0cf064dd592 | 1e+22 | 1e+22 | \x4480f0cf064dd592 | t
+ \x4480f0cf064dd593 | 1.0000000000000002e+22 | 1.0000000000000002e+22 | \x4480f0cf064dd593 | t
+ \x44b52d02c7e14af5 | 9.999999999999997e+22 | 9.999999999999997e+22 | \x44b52d02c7e14af5 | t
+ \x44b52d02c7e14af6 | 9.999999999999999e+22 | 9.999999999999999e+22 | \x44b52d02c7e14af6 | t
+ \x44b52d02c7e14af7 | 1.0000000000000001e+23 | 1.0000000000000001e+23 | \x44b52d02c7e14af7 | t
+ \x44ea784379d99db3 | 9.999999999999998e+23 | 9.999999999999998e+23 | \x44ea784379d99db3 | t
+ \x44ea784379d99db4 | 1e+24 | 1e+24 | \x44ea784379d99db4 | t
+ \x44ea784379d99db5 | 1.0000000000000001e+24 | 1.0000000000000001e+24 | \x44ea784379d99db5 | t
+ \x45208b2a2c280290 | 9.999999999999999e+24 | 9.999999999999999e+24 | \x45208b2a2c280290 | t
+ \x45208b2a2c280291 | 1e+25 | 1e+25 | \x45208b2a2c280291 | t
+ \x45208b2a2c280292 | 1.0000000000000003e+25 | 1.0000000000000003e+25 | \x45208b2a2c280292 | t
+ \x7feffffffffffffe | 1.7976931348623155e+308 | 1.7976931348623155e+308 | \x7feffffffffffffe | t
+ \x7fefffffffffffff | 1.7976931348623157e+308 | 1.7976931348623157e+308 | \x7fefffffffffffff | t
+ \x4350000000000002 | 1.8014398509481992e+16 | 1.8014398509481992e+16 | \x4350000000000002 | t
+ \x4350000000002e06 | 1.8014398509529112e+16 | 1.8014398509529112e+16 | \x4350000000002e06 | t
+ \x4352000000000003 | 2.0266198323167244e+16 | 2.0266198323167244e+16 | \x4352000000000003 | t
+ \x4352000000000004 | 2.0266198323167248e+16 | 2.0266198323167248e+16 | \x4352000000000004 | t
+ \x4358000000000003 | 2.7021597764222988e+16 | 2.7021597764222988e+16 | \x4358000000000003 | t
+ \x4358000000000004 | 2.7021597764222992e+16 | 2.7021597764222992e+16 | \x4358000000000004 | t
+ \x435f000000000020 | 3.4902897112121472e+16 | 3.4902897112121472e+16 | \x435f000000000020 | t
+ \xc350000000000002 | -1.8014398509481992e+16 | -1.8014398509481992e+16 | \xc350000000000002 | t
+ \xc350000000002e06 | -1.8014398509529112e+16 | -1.8014398509529112e+16 | \xc350000000002e06 | t
+ \xc352000000000003 | -2.0266198323167244e+16 | -2.0266198323167244e+16 | \xc352000000000003 | t
+ \xc352000000000004 | -2.0266198323167248e+16 | -2.0266198323167248e+16 | \xc352000000000004 | t
+ \xc358000000000003 | -2.7021597764222988e+16 | -2.7021597764222988e+16 | \xc358000000000003 | t
+ \xc358000000000004 | -2.7021597764222992e+16 | -2.7021597764222992e+16 | \xc358000000000004 | t
+ \xc35f000000000020 | -3.4902897112121472e+16 | -3.4902897112121472e+16 | \xc35f000000000020 | t
+ \x42dc12218377de66 | 123456789012345.6 | 123456789012345.6 | \x42dc12218377de66 | t
+ \x42a674e79c5fe51f | 12345678901234.56 | 12345678901234.56 | \x42a674e79c5fe51f | t
+ \x4271f71fb04cb74c | 1234567890123.456 | 1234567890123.456 | \x4271f71fb04cb74c | t
+ \x423cbe991a145879 | 123456789012.3456 | 123456789012.3456 | \x423cbe991a145879 | t
+ \x4206fee0e1a9e061 | 12345678901.23456 | 12345678901.23456 | \x4206fee0e1a9e061 | t
+ \x41d26580b487e6b4 | 1234567890.123456 | 1234567890.123456 | \x41d26580b487e6b4 | t
+ \x419d6f34540ca453 | 123456789.0123456 | 123456789.0123456 | \x419d6f34540ca453 | t
+ \x41678c29dcd6e9dc | 12345678.90123456 | 12345678.90123456 | \x41678c29dcd6e9dc | t
+ \x4132d687e3df217d | 1234567.890123456 | 1234567.890123456 | \x4132d687e3df217d | t
+ \x40fe240c9fcb68c8 | 123456.7890123456 | 123456.7890123456 | \x40fe240c9fcb68c8 | t
+ \x40c81cd6e63c53d3 | 12345.67890123456 | 12345.67890123456 | \x40c81cd6e63c53d3 | t
+ \x40934a4584fd0fdc | 1234.567890123456 | 1234.567890123456 | \x40934a4584fd0fdc | t
+ \x405edd3c07fb4c93 | 123.4567890123456 | 123.4567890123456 | \x405edd3c07fb4c93 | t
+ \x4028b0fcd32f7076 | 12.34567890123456 | 12.34567890123456 | \x4028b0fcd32f7076 | t
+ \x3ff3c0ca428c59f8 | 1.234567890123456 | 1.234567890123456 | \x3ff3c0ca428c59f8 | t
+ \x3e60000000000000 | 2.9802322387695312e-08 | 2.9802322387695312e-08 | \x3e60000000000000 | t
+ \xc352bd2668e077c4 | -2.1098088986959632e+16 | -2.1098088986959632e+16 | \xc352bd2668e077c4 | t
+ \x434018601510c000 | 9.0608011534336e+15 | 9.0608011534336e+15 | \x434018601510c000 | t
+ \x43d055dc36f24000 | 4.708356024711512e+18 | 4.708356024711512e+18 | \x43d055dc36f24000 | t
+ \x43e052961c6f8000 | 9.409340012568248e+18 | 9.409340012568248e+18 | \x43e052961c6f8000 | t
+ \x3ff3c0ca2a5b1d5d | 1.2345678 | 1.2345678 | \x3ff3c0ca2a5b1d5d | t
+ \x4830f0cf064dd592 | 5.764607523034235e+39 | 5.764607523034235e+39 | \x4830f0cf064dd592 | t
+ \x4840f0cf064dd592 | 1.152921504606847e+40 | 1.152921504606847e+40 | \x4840f0cf064dd592 | t
+ \x4850f0cf064dd592 | 2.305843009213694e+40 | 2.305843009213694e+40 | \x4850f0cf064dd592 | t
+ \x3ff3333333333333 | 1.2 | 1.2 | \x3ff3333333333333 | t
+ \x3ff3ae147ae147ae | 1.23 | 1.23 | \x3ff3ae147ae147ae | t
+ \x3ff3be76c8b43958 | 1.234 | 1.234 | \x3ff3be76c8b43958 | t
+ \x3ff3c083126e978d | 1.2345 | 1.2345 | \x3ff3c083126e978d | t
+ \x3ff3c0c1fc8f3238 | 1.23456 | 1.23456 | \x3ff3c0c1fc8f3238 | t
+ \x3ff3c0c9539b8887 | 1.234567 | 1.234567 | \x3ff3c0c9539b8887 | t
+ \x3ff3c0ca2a5b1d5d | 1.2345678 | 1.2345678 | \x3ff3c0ca2a5b1d5d | t
+ \x3ff3c0ca4283de1b | 1.23456789 | 1.23456789 | \x3ff3c0ca4283de1b | t
+ \x3ff3c0ca43db770a | 1.234567895 | 1.234567895 | \x3ff3c0ca43db770a | t
+ \x3ff3c0ca428abd53 | 1.2345678901 | 1.2345678901 | \x3ff3c0ca428abd53 | t
+ \x3ff3c0ca428c1d2b | 1.23456789012 | 1.23456789012 | \x3ff3c0ca428c1d2b | t
+ \x3ff3c0ca428c51f2 | 1.234567890123 | 1.234567890123 | \x3ff3c0ca428c51f2 | t
+ \x3ff3c0ca428c58fc | 1.2345678901234 | 1.2345678901234 | \x3ff3c0ca428c58fc | t
+ \x3ff3c0ca428c59dd | 1.23456789012345 | 1.23456789012345 | \x3ff3c0ca428c59dd | t
+ \x3ff3c0ca428c59f8 | 1.234567890123456 | 1.234567890123456 | \x3ff3c0ca428c59f8 | t
+ \x3ff3c0ca428c59fb | 1.2345678901234567 | 1.2345678901234567 | \x3ff3c0ca428c59fb | t
+ \x40112e0be8047a7d | 4.294967294 | 4.294967294 | \x40112e0be8047a7d | t
+ \x40112e0be815a889 | 4.294967295 | 4.294967295 | \x40112e0be815a889 | t
+ \x40112e0be826d695 | 4.294967296 | 4.294967296 | \x40112e0be826d695 | t
+ \x40112e0be83804a1 | 4.294967297 | 4.294967297 | \x40112e0be83804a1 | t
+ \x40112e0be84932ad | 4.294967298 | 4.294967298 | \x40112e0be84932ad | t
+ \x0040000000000000 | 1.7800590868057611e-307 | 1.7800590868057611e-307 | \x0040000000000000 | t
+ \x007fffffffffffff | 2.8480945388892175e-306 | 2.8480945388892175e-306 | \x007fffffffffffff | t
+ \x0290000000000000 | 2.446494580089078e-296 | 2.446494580089078e-296 | \x0290000000000000 | t
+ \x029fffffffffffff | 4.8929891601781557e-296 | 4.8929891601781557e-296 | \x029fffffffffffff | t
+ \x4350000000000000 | 1.8014398509481984e+16 | 1.8014398509481984e+16 | \x4350000000000000 | t
+ \x435fffffffffffff | 3.6028797018963964e+16 | 3.6028797018963964e+16 | \x435fffffffffffff | t
+ \x1330000000000000 | 2.900835519859558e-216 | 2.900835519859558e-216 | \x1330000000000000 | t
+ \x133fffffffffffff | 5.801671039719115e-216 | 5.801671039719115e-216 | \x133fffffffffffff | t
+ \x3a6fa7161a4d6e0c | 3.196104012172126e-27 | 3.196104012172126e-27 | \x3a6fa7161a4d6e0c | t
+(209 rows)
+
+-- clean up, lest opr_sanity complain
+\set VERBOSITY terse
+drop type xfloat8 cascade;
+NOTICE: drop cascades to 6 other objects
+\set VERBOSITY default
+--
diff --git a/src/test/regress/expected/float8.out b/src/test/regress/expected/float8.out
index 75c0bf389b..c3a6f5331f 100644
--- a/src/test/regress/expected/float8.out
+++ b/src/test/regress/expected/float8.out
@@ -24,6 +24,13 @@ SELECT '-10e-400'::float8;
ERROR: "-10e-400" is out of range for type double precision
LINE 1: SELECT '-10e-400'::float8;
^
+-- test smallest normalized input
+SELECT float8send('2.2250738585072014E-308'::float8);
+ float8send
+--------------------
+ \x0010000000000000
+(1 row)
+
-- bad input
INSERT INTO FLOAT8_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type double precision: ""
@@ -209,7 +216,7 @@ SELECT '' AS three, f.f1, f.f1 / '-10' AS x
WHERE f.f1 > '0.0';
three | f1 | x
-------+----------------------+-----------------------
- | 1004.3 | -100.43
+ | 1004.3 | -100.42999999999999
| 1.2345678901234e+200 | -1.2345678901234e+199
| 1.2345678901234e-200 | -1.2345678901234e-201
(3 rows)
@@ -226,9 +233,9 @@ SELECT '' AS three, f.f1, f.f1 - '-10' AS x
SELECT '' AS one, f.f1 ^ '2.0' AS square_f1
FROM FLOAT8_TBL f where f.f1 = '1004.3';
- one | square_f1
------+------------
- | 1008618.49
+ one | square_f1
+-----+--------------------
+ | 1008618.4899999999
(1 row)
-- absolute value
@@ -310,6 +317,8 @@ select sign(f1) as sign_f1 from float8_tbl f;
1
(5 rows)
+-- avoid bit-exact output here because operations may not be bit-exact.
+SET extra_float_digits = 0;
-- square root
SELECT sqrt(float8 '64') AS eight;
eight
@@ -445,6 +454,7 @@ SELECT '' AS five, * FROM FLOAT8_TBL;
| -1.2345678901234e-200
(5 rows)
+RESET extra_float_digits;
-- test for over- and underflow
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
ERROR: "10e400" is out of range for type double precision
@@ -530,7 +540,6 @@ SELECT '-9223372036854775808.5'::float8::int8;
SELECT '-9223372036854780000'::float8::int8;
ERROR: bigint out of range
-- test exact cases for trigonometric functions in degrees
-SET extra_float_digits = 3;
SELECT x,
sind(x),
sind(x) IN (-1,-0.5,0,0.5,1) AS sind_exact
@@ -632,4 +641,432 @@ FROM (SELECT 10*cosd(a), 10*sind(a)
10 | 0 | 0 | t
(5 rows)
-RESET extra_float_digits;
+--
+-- test output (and round-trip safety) of various values.
+-- To ensure we're testing what we think we're testing, start with
+-- float values specified by bit patterns (as a useful side effect,
+-- this means we'll fail on non-IEEE platforms).
+create type xfloat8;
+create function xfloat8in(cstring) returns xfloat8 immutable strict
+ language internal as 'int8in';
+NOTICE: return type xfloat8 is only a shell
+create function xfloat8out(xfloat8) returns cstring immutable strict
+ language internal as 'int8out';
+NOTICE: argument type xfloat8 is only a shell
+create type xfloat8 (input = xfloat8in, output = xfloat8out, like = float8);
+create cast (xfloat8 as float8) without function;
+create cast (float8 as xfloat8) without function;
+create cast (xfloat8 as bigint) without function;
+create cast (bigint as xfloat8) without function;
+-- float8: seeeeeee eeeeeeee eeeeeeee mmmmmmmm mmmmmmmm(x4)
+-- we don't care to assume the platform's strtod() handles subnormals
+-- correctly; those are "use at your own risk". However we do test
+-- subnormal outputs, since those are under our control.
+with testdata(bits) as (values
+ -- small subnormals
+ (x'0000000000000001'),
+ (x'0000000000000002'), (x'0000000000000003'),
+ (x'0000000000001000'), (x'0000000100000000'),
+ (x'0000010000000000'), (x'0000010100000000'),
+ (x'0000400000000000'), (x'0000400100000000'),
+ (x'0000800000000000'), (x'0000800000000001'),
+ -- these values taken from upstream testsuite
+ (x'00000000000f4240'),
+ (x'00000000016e3600'),
+ (x'0000008cdcdea440'),
+ -- borderline between subnormal and normal
+ (x'000ffffffffffff0'), (x'000ffffffffffff1'),
+ (x'000ffffffffffffe'), (x'000fffffffffffff'))
+select float8send(flt) as ibits,
+ flt
+ from (select bits::bigint::xfloat8::float8 as flt
+ from testdata
+ offset 0) s;
+ ibits | flt
+--------------------+-------------------------
+ \x0000000000000001 | 5e-324
+ \x0000000000000002 | 1e-323
+ \x0000000000000003 | 1.5e-323
+ \x0000000000001000 | 2.0237e-320
+ \x0000000100000000 | 2.121995791e-314
+ \x0000010000000000 | 5.43230922487e-312
+ \x0000010100000000 | 5.45352918278e-312
+ \x0000400000000000 | 3.4766779039175e-310
+ \x0000400100000000 | 3.4768901034966e-310
+ \x0000800000000000 | 6.953355807835e-310
+ \x0000800000000001 | 6.95335580783505e-310
+ \x00000000000f4240 | 4.940656e-318
+ \x00000000016e3600 | 1.18575755e-316
+ \x0000008cdcdea440 | 2.989102097996e-312
+ \x000ffffffffffff0 | 2.2250738585071935e-308
+ \x000ffffffffffff1 | 2.225073858507194e-308
+ \x000ffffffffffffe | 2.2250738585072004e-308
+ \x000fffffffffffff | 2.225073858507201e-308
+(18 rows)
+
+-- round-trip tests
+with testdata(bits) as (values
+ (x'0000000000000000'),
+ -- smallest normal values
+ (x'0010000000000000'), (x'0010000000000001'),
+ (x'0010000000000002'), (x'0018000000000000'),
+ --
+ (x'3ddb7cdfd9d7bdba'), (x'3ddb7cdfd9d7bdbb'), (x'3ddb7cdfd9d7bdbc'),
+ (x'3e112e0be826d694'), (x'3e112e0be826d695'), (x'3e112e0be826d696'),
+ (x'3e45798ee2308c39'), (x'3e45798ee2308c3a'), (x'3e45798ee2308c3b'),
+ (x'3e7ad7f29abcaf47'), (x'3e7ad7f29abcaf48'), (x'3e7ad7f29abcaf49'),
+ (x'3eb0c6f7a0b5ed8c'), (x'3eb0c6f7a0b5ed8d'), (x'3eb0c6f7a0b5ed8e'),
+ (x'3ee4f8b588e368ef'), (x'3ee4f8b588e368f0'), (x'3ee4f8b588e368f1'),
+ (x'3f1a36e2eb1c432c'), (x'3f1a36e2eb1c432d'), (x'3f1a36e2eb1c432e'),
+ (x'3f50624dd2f1a9fb'), (x'3f50624dd2f1a9fc'), (x'3f50624dd2f1a9fd'),
+ (x'3f847ae147ae147a'), (x'3f847ae147ae147b'), (x'3f847ae147ae147c'),
+ (x'3fb9999999999999'), (x'3fb999999999999a'), (x'3fb999999999999b'),
+ -- values very close to 1
+ (x'3feffffffffffff0'), (x'3feffffffffffff1'), (x'3feffffffffffff2'),
+ (x'3feffffffffffff3'), (x'3feffffffffffff4'), (x'3feffffffffffff5'),
+ (x'3feffffffffffff6'), (x'3feffffffffffff7'), (x'3feffffffffffff8'),
+ (x'3feffffffffffff9'), (x'3feffffffffffffa'), (x'3feffffffffffffb'),
+ (x'3feffffffffffffc'), (x'3feffffffffffffd'), (x'3feffffffffffffe'),
+ (x'3fefffffffffffff'),
+ (x'3ff0000000000000'),
+ (x'3ff0000000000001'), (x'3ff0000000000002'), (x'3ff0000000000003'),
+ (x'3ff0000000000004'), (x'3ff0000000000005'), (x'3ff0000000000006'),
+ (x'3ff0000000000007'), (x'3ff0000000000008'), (x'3ff0000000000009'),
+ --
+ (x'3ff921fb54442d18'),
+ (x'4005bf0a8b14576a'),
+ (x'400921fb54442d18'),
+ --
+ (x'4023ffffffffffff'), (x'4024000000000000'), (x'4024000000000001'),
+ (x'4058ffffffffffff'), (x'4059000000000000'), (x'4059000000000001'),
+ (x'408f3fffffffffff'), (x'408f400000000000'), (x'408f400000000001'),
+ (x'40c387ffffffffff'), (x'40c3880000000000'), (x'40c3880000000001'),
+ (x'40f869ffffffffff'), (x'40f86a0000000000'), (x'40f86a0000000001'),
+ (x'412e847fffffffff'), (x'412e848000000000'), (x'412e848000000001'),
+ (x'416312cfffffffff'), (x'416312d000000000'), (x'416312d000000001'),
+ (x'4197d783ffffffff'), (x'4197d78400000000'), (x'4197d78400000001'),
+ (x'41cdcd64ffffffff'), (x'41cdcd6500000000'), (x'41cdcd6500000001'),
+ (x'4202a05f1fffffff'), (x'4202a05f20000000'), (x'4202a05f20000001'),
+ (x'42374876e7ffffff'), (x'42374876e8000000'), (x'42374876e8000001'),
+ (x'426d1a94a1ffffff'), (x'426d1a94a2000000'), (x'426d1a94a2000001'),
+ (x'42a2309ce53fffff'), (x'42a2309ce5400000'), (x'42a2309ce5400001'),
+ (x'42d6bcc41e8fffff'), (x'42d6bcc41e900000'), (x'42d6bcc41e900001'),
+ (x'430c6bf52633ffff'), (x'430c6bf526340000'), (x'430c6bf526340001'),
+ (x'4341c37937e07fff'), (x'4341c37937e08000'), (x'4341c37937e08001'),
+ (x'4376345785d89fff'), (x'4376345785d8a000'), (x'4376345785d8a001'),
+ (x'43abc16d674ec7ff'), (x'43abc16d674ec800'), (x'43abc16d674ec801'),
+ (x'43e158e460913cff'), (x'43e158e460913d00'), (x'43e158e460913d01'),
+ (x'4415af1d78b58c3f'), (x'4415af1d78b58c40'), (x'4415af1d78b58c41'),
+ (x'444b1ae4d6e2ef4f'), (x'444b1ae4d6e2ef50'), (x'444b1ae4d6e2ef51'),
+ (x'4480f0cf064dd591'), (x'4480f0cf064dd592'), (x'4480f0cf064dd593'),
+ (x'44b52d02c7e14af5'), (x'44b52d02c7e14af6'), (x'44b52d02c7e14af7'),
+ (x'44ea784379d99db3'), (x'44ea784379d99db4'), (x'44ea784379d99db5'),
+ (x'45208b2a2c280290'), (x'45208b2a2c280291'), (x'45208b2a2c280292'),
+ --
+ (x'7feffffffffffffe'), (x'7fefffffffffffff'),
+ -- round to even tests (+ve)
+ (x'4350000000000002'),
+ (x'4350000000002e06'),
+ (x'4352000000000003'),
+ (x'4352000000000004'),
+ (x'4358000000000003'),
+ (x'4358000000000004'),
+ (x'435f000000000020'),
+ -- round to even tests (-ve)
+ (x'c350000000000002'),
+ (x'c350000000002e06'),
+ (x'c352000000000003'),
+ (x'c352000000000004'),
+ (x'c358000000000003'),
+ (x'c358000000000004'),
+ (x'c35f000000000020'),
+ -- exercise fixed-point memmoves
+ (x'42dc12218377de66'),
+ (x'42a674e79c5fe51f'),
+ (x'4271f71fb04cb74c'),
+ (x'423cbe991a145879'),
+ (x'4206fee0e1a9e061'),
+ (x'41d26580b487e6b4'),
+ (x'419d6f34540ca453'),
+ (x'41678c29dcd6e9dc'),
+ (x'4132d687e3df217d'),
+ (x'40fe240c9fcb68c8'),
+ (x'40c81cd6e63c53d3'),
+ (x'40934a4584fd0fdc'),
+ (x'405edd3c07fb4c93'),
+ (x'4028b0fcd32f7076'),
+ (x'3ff3c0ca428c59f8'),
+ -- these cases come from the upstream's testsuite
+ -- LotsOfTrailingZeros)
+ (x'3e60000000000000'),
+ -- Regression
+ (x'c352bd2668e077c4'),
+ (x'434018601510c000'),
+ (x'43d055dc36f24000'),
+ (x'43e052961c6f8000'),
+ (x'3ff3c0ca2a5b1d5d'),
+ -- LooksLikePow5
+ (x'4830f0cf064dd592'),
+ (x'4840f0cf064dd592'),
+ (x'4850f0cf064dd592'),
+ -- OutputLength
+ (x'3ff3333333333333'),
+ (x'3ff3ae147ae147ae'),
+ (x'3ff3be76c8b43958'),
+ (x'3ff3c083126e978d'),
+ (x'3ff3c0c1fc8f3238'),
+ (x'3ff3c0c9539b8887'),
+ (x'3ff3c0ca2a5b1d5d'),
+ (x'3ff3c0ca4283de1b'),
+ (x'3ff3c0ca43db770a'),
+ (x'3ff3c0ca428abd53'),
+ (x'3ff3c0ca428c1d2b'),
+ (x'3ff3c0ca428c51f2'),
+ (x'3ff3c0ca428c58fc'),
+ (x'3ff3c0ca428c59dd'),
+ (x'3ff3c0ca428c59f8'),
+ (x'3ff3c0ca428c59fb'),
+ -- 32-bit chunking
+ (x'40112e0be8047a7d'),
+ (x'40112e0be815a889'),
+ (x'40112e0be826d695'),
+ (x'40112e0be83804a1'),
+ (x'40112e0be84932ad'),
+ -- MinMaxShift
+ (x'0040000000000000'),
+ (x'007fffffffffffff'),
+ (x'0290000000000000'),
+ (x'029fffffffffffff'),
+ (x'4350000000000000'),
+ (x'435fffffffffffff'),
+ (x'1330000000000000'),
+ (x'133fffffffffffff'),
+ (x'3a6fa7161a4d6e0c')
+)
+select float8send(flt) as ibits,
+ flt,
+ flt::text::float8 as r_flt,
+ float8send(flt::text::float8) as obits,
+ float8send(flt::text::float8) = float8send(flt) as correct
+ from (select bits::bigint::xfloat8::float8 as flt
+ from testdata
+ offset 0) s;
+ ibits | flt | r_flt | obits | correct
+--------------------+-------------------------+-------------------------+--------------------+---------
+ \x0000000000000000 | 0 | 0 | \x0000000000000000 | t
+ \x0010000000000000 | 2.2250738585072014e-308 | 2.2250738585072014e-308 | \x0010000000000000 | t
+ \x0010000000000001 | 2.225073858507202e-308 | 2.225073858507202e-308 | \x0010000000000001 | t
+ \x0010000000000002 | 2.2250738585072024e-308 | 2.2250738585072024e-308 | \x0010000000000002 | t
+ \x0018000000000000 | 3.337610787760802e-308 | 3.337610787760802e-308 | \x0018000000000000 | t
+ \x3ddb7cdfd9d7bdba | 9.999999999999999e-11 | 9.999999999999999e-11 | \x3ddb7cdfd9d7bdba | t
+ \x3ddb7cdfd9d7bdbb | 1e-10 | 1e-10 | \x3ddb7cdfd9d7bdbb | t
+ \x3ddb7cdfd9d7bdbc | 1.0000000000000002e-10 | 1.0000000000000002e-10 | \x3ddb7cdfd9d7bdbc | t
+ \x3e112e0be826d694 | 9.999999999999999e-10 | 9.999999999999999e-10 | \x3e112e0be826d694 | t
+ \x3e112e0be826d695 | 1e-09 | 1e-09 | \x3e112e0be826d695 | t
+ \x3e112e0be826d696 | 1.0000000000000003e-09 | 1.0000000000000003e-09 | \x3e112e0be826d696 | t
+ \x3e45798ee2308c39 | 9.999999999999999e-09 | 9.999999999999999e-09 | \x3e45798ee2308c39 | t
+ \x3e45798ee2308c3a | 1e-08 | 1e-08 | \x3e45798ee2308c3a | t
+ \x3e45798ee2308c3b | 1.0000000000000002e-08 | 1.0000000000000002e-08 | \x3e45798ee2308c3b | t
+ \x3e7ad7f29abcaf47 | 9.999999999999998e-08 | 9.999999999999998e-08 | \x3e7ad7f29abcaf47 | t
+ \x3e7ad7f29abcaf48 | 1e-07 | 1e-07 | \x3e7ad7f29abcaf48 | t
+ \x3e7ad7f29abcaf49 | 1.0000000000000001e-07 | 1.0000000000000001e-07 | \x3e7ad7f29abcaf49 | t
+ \x3eb0c6f7a0b5ed8c | 9.999999999999997e-07 | 9.999999999999997e-07 | \x3eb0c6f7a0b5ed8c | t
+ \x3eb0c6f7a0b5ed8d | 1e-06 | 1e-06 | \x3eb0c6f7a0b5ed8d | t
+ \x3eb0c6f7a0b5ed8e | 1.0000000000000002e-06 | 1.0000000000000002e-06 | \x3eb0c6f7a0b5ed8e | t
+ \x3ee4f8b588e368ef | 9.999999999999997e-06 | 9.999999999999997e-06 | \x3ee4f8b588e368ef | t
+ \x3ee4f8b588e368f0 | 9.999999999999999e-06 | 9.999999999999999e-06 | \x3ee4f8b588e368f0 | t
+ \x3ee4f8b588e368f1 | 1e-05 | 1e-05 | \x3ee4f8b588e368f1 | t
+ \x3f1a36e2eb1c432c | 9.999999999999999e-05 | 9.999999999999999e-05 | \x3f1a36e2eb1c432c | t
+ \x3f1a36e2eb1c432d | 0.0001 | 0.0001 | \x3f1a36e2eb1c432d | t
+ \x3f1a36e2eb1c432e | 0.00010000000000000002 | 0.00010000000000000002 | \x3f1a36e2eb1c432e | t
+ \x3f50624dd2f1a9fb | 0.0009999999999999998 | 0.0009999999999999998 | \x3f50624dd2f1a9fb | t
+ \x3f50624dd2f1a9fc | 0.001 | 0.001 | \x3f50624dd2f1a9fc | t
+ \x3f50624dd2f1a9fd | 0.0010000000000000002 | 0.0010000000000000002 | \x3f50624dd2f1a9fd | t
+ \x3f847ae147ae147a | 0.009999999999999998 | 0.009999999999999998 | \x3f847ae147ae147a | t
+ \x3f847ae147ae147b | 0.01 | 0.01 | \x3f847ae147ae147b | t
+ \x3f847ae147ae147c | 0.010000000000000002 | 0.010000000000000002 | \x3f847ae147ae147c | t
+ \x3fb9999999999999 | 0.09999999999999999 | 0.09999999999999999 | \x3fb9999999999999 | t
+ \x3fb999999999999a | 0.1 | 0.1 | \x3fb999999999999a | t
+ \x3fb999999999999b | 0.10000000000000002 | 0.10000000000000002 | \x3fb999999999999b | t
+ \x3feffffffffffff0 | 0.9999999999999982 | 0.9999999999999982 | \x3feffffffffffff0 | t
+ \x3feffffffffffff1 | 0.9999999999999983 | 0.9999999999999983 | \x3feffffffffffff1 | t
+ \x3feffffffffffff2 | 0.9999999999999984 | 0.9999999999999984 | \x3feffffffffffff2 | t
+ \x3feffffffffffff3 | 0.9999999999999986 | 0.9999999999999986 | \x3feffffffffffff3 | t
+ \x3feffffffffffff4 | 0.9999999999999987 | 0.9999999999999987 | \x3feffffffffffff4 | t
+ \x3feffffffffffff5 | 0.9999999999999988 | 0.9999999999999988 | \x3feffffffffffff5 | t
+ \x3feffffffffffff6 | 0.9999999999999989 | 0.9999999999999989 | \x3feffffffffffff6 | t
+ \x3feffffffffffff7 | 0.999999999999999 | 0.999999999999999 | \x3feffffffffffff7 | t
+ \x3feffffffffffff8 | 0.9999999999999991 | 0.9999999999999991 | \x3feffffffffffff8 | t
+ \x3feffffffffffff9 | 0.9999999999999992 | 0.9999999999999992 | \x3feffffffffffff9 | t
+ \x3feffffffffffffa | 0.9999999999999993 | 0.9999999999999993 | \x3feffffffffffffa | t
+ \x3feffffffffffffb | 0.9999999999999994 | 0.9999999999999994 | \x3feffffffffffffb | t
+ \x3feffffffffffffc | 0.9999999999999996 | 0.9999999999999996 | \x3feffffffffffffc | t
+ \x3feffffffffffffd | 0.9999999999999997 | 0.9999999999999997 | \x3feffffffffffffd | t
+ \x3feffffffffffffe | 0.9999999999999998 | 0.9999999999999998 | \x3feffffffffffffe | t
+ \x3fefffffffffffff | 0.9999999999999999 | 0.9999999999999999 | \x3fefffffffffffff | t
+ \x3ff0000000000000 | 1 | 1 | \x3ff0000000000000 | t
+ \x3ff0000000000001 | 1.0000000000000002 | 1.0000000000000002 | \x3ff0000000000001 | t
+ \x3ff0000000000002 | 1.0000000000000004 | 1.0000000000000004 | \x3ff0000000000002 | t
+ \x3ff0000000000003 | 1.0000000000000007 | 1.0000000000000007 | \x3ff0000000000003 | t
+ \x3ff0000000000004 | 1.0000000000000009 | 1.0000000000000009 | \x3ff0000000000004 | t
+ \x3ff0000000000005 | 1.000000000000001 | 1.000000000000001 | \x3ff0000000000005 | t
+ \x3ff0000000000006 | 1.0000000000000013 | 1.0000000000000013 | \x3ff0000000000006 | t
+ \x3ff0000000000007 | 1.0000000000000016 | 1.0000000000000016 | \x3ff0000000000007 | t
+ \x3ff0000000000008 | 1.0000000000000018 | 1.0000000000000018 | \x3ff0000000000008 | t
+ \x3ff0000000000009 | 1.000000000000002 | 1.000000000000002 | \x3ff0000000000009 | t
+ \x3ff921fb54442d18 | 1.5707963267948966 | 1.5707963267948966 | \x3ff921fb54442d18 | t
+ \x4005bf0a8b14576a | 2.7182818284590455 | 2.7182818284590455 | \x4005bf0a8b14576a | t
+ \x400921fb54442d18 | 3.141592653589793 | 3.141592653589793 | \x400921fb54442d18 | t
+ \x4023ffffffffffff | 9.999999999999998 | 9.999999999999998 | \x4023ffffffffffff | t
+ \x4024000000000000 | 10 | 10 | \x4024000000000000 | t
+ \x4024000000000001 | 10.000000000000002 | 10.000000000000002 | \x4024000000000001 | t
+ \x4058ffffffffffff | 99.99999999999999 | 99.99999999999999 | \x4058ffffffffffff | t
+ \x4059000000000000 | 100 | 100 | \x4059000000000000 | t
+ \x4059000000000001 | 100.00000000000001 | 100.00000000000001 | \x4059000000000001 | t
+ \x408f3fffffffffff | 999.9999999999999 | 999.9999999999999 | \x408f3fffffffffff | t
+ \x408f400000000000 | 1000 | 1000 | \x408f400000000000 | t
+ \x408f400000000001 | 1000.0000000000001 | 1000.0000000000001 | \x408f400000000001 | t
+ \x40c387ffffffffff | 9999.999999999998 | 9999.999999999998 | \x40c387ffffffffff | t
+ \x40c3880000000000 | 10000 | 10000 | \x40c3880000000000 | t
+ \x40c3880000000001 | 10000.000000000002 | 10000.000000000002 | \x40c3880000000001 | t
+ \x40f869ffffffffff | 99999.99999999999 | 99999.99999999999 | \x40f869ffffffffff | t
+ \x40f86a0000000000 | 100000 | 100000 | \x40f86a0000000000 | t
+ \x40f86a0000000001 | 100000.00000000001 | 100000.00000000001 | \x40f86a0000000001 | t
+ \x412e847fffffffff | 999999.9999999999 | 999999.9999999999 | \x412e847fffffffff | t
+ \x412e848000000000 | 1000000 | 1000000 | \x412e848000000000 | t
+ \x412e848000000001 | 1000000.0000000001 | 1000000.0000000001 | \x412e848000000001 | t
+ \x416312cfffffffff | 9999999.999999998 | 9999999.999999998 | \x416312cfffffffff | t
+ \x416312d000000000 | 10000000 | 10000000 | \x416312d000000000 | t
+ \x416312d000000001 | 10000000.000000002 | 10000000.000000002 | \x416312d000000001 | t
+ \x4197d783ffffffff | 99999999.99999999 | 99999999.99999999 | \x4197d783ffffffff | t
+ \x4197d78400000000 | 100000000 | 100000000 | \x4197d78400000000 | t
+ \x4197d78400000001 | 100000000.00000001 | 100000000.00000001 | \x4197d78400000001 | t
+ \x41cdcd64ffffffff | 999999999.9999999 | 999999999.9999999 | \x41cdcd64ffffffff | t
+ \x41cdcd6500000000 | 1000000000 | 1000000000 | \x41cdcd6500000000 | t
+ \x41cdcd6500000001 | 1000000000.0000001 | 1000000000.0000001 | \x41cdcd6500000001 | t
+ \x4202a05f1fffffff | 9999999999.999998 | 9999999999.999998 | \x4202a05f1fffffff | t
+ \x4202a05f20000000 | 10000000000 | 10000000000 | \x4202a05f20000000 | t
+ \x4202a05f20000001 | 10000000000.000002 | 10000000000.000002 | \x4202a05f20000001 | t
+ \x42374876e7ffffff | 99999999999.99998 | 99999999999.99998 | \x42374876e7ffffff | t
+ \x42374876e8000000 | 100000000000 | 100000000000 | \x42374876e8000000 | t
+ \x42374876e8000001 | 100000000000.00002 | 100000000000.00002 | \x42374876e8000001 | t
+ \x426d1a94a1ffffff | 999999999999.9999 | 999999999999.9999 | \x426d1a94a1ffffff | t
+ \x426d1a94a2000000 | 1000000000000 | 1000000000000 | \x426d1a94a2000000 | t
+ \x426d1a94a2000001 | 1000000000000.0001 | 1000000000000.0001 | \x426d1a94a2000001 | t
+ \x42a2309ce53fffff | 9999999999999.998 | 9999999999999.998 | \x42a2309ce53fffff | t
+ \x42a2309ce5400000 | 10000000000000 | 10000000000000 | \x42a2309ce5400000 | t
+ \x42a2309ce5400001 | 10000000000000.002 | 10000000000000.002 | \x42a2309ce5400001 | t
+ \x42d6bcc41e8fffff | 99999999999999.98 | 99999999999999.98 | \x42d6bcc41e8fffff | t
+ \x42d6bcc41e900000 | 100000000000000 | 100000000000000 | \x42d6bcc41e900000 | t
+ \x42d6bcc41e900001 | 100000000000000.02 | 100000000000000.02 | \x42d6bcc41e900001 | t
+ \x430c6bf52633ffff | 999999999999999.9 | 999999999999999.9 | \x430c6bf52633ffff | t
+ \x430c6bf526340000 | 1e+15 | 1e+15 | \x430c6bf526340000 | t
+ \x430c6bf526340001 | 1.0000000000000001e+15 | 1.0000000000000001e+15 | \x430c6bf526340001 | t
+ \x4341c37937e07fff | 9.999999999999998e+15 | 9.999999999999998e+15 | \x4341c37937e07fff | t
+ \x4341c37937e08000 | 1e+16 | 1e+16 | \x4341c37937e08000 | t
+ \x4341c37937e08001 | 1.0000000000000002e+16 | 1.0000000000000002e+16 | \x4341c37937e08001 | t
+ \x4376345785d89fff | 9.999999999999998e+16 | 9.999999999999998e+16 | \x4376345785d89fff | t
+ \x4376345785d8a000 | 1e+17 | 1e+17 | \x4376345785d8a000 | t
+ \x4376345785d8a001 | 1.0000000000000002e+17 | 1.0000000000000002e+17 | \x4376345785d8a001 | t
+ \x43abc16d674ec7ff | 9.999999999999999e+17 | 9.999999999999999e+17 | \x43abc16d674ec7ff | t
+ \x43abc16d674ec800 | 1e+18 | 1e+18 | \x43abc16d674ec800 | t
+ \x43abc16d674ec801 | 1.0000000000000001e+18 | 1.0000000000000001e+18 | \x43abc16d674ec801 | t
+ \x43e158e460913cff | 9.999999999999998e+18 | 9.999999999999998e+18 | \x43e158e460913cff | t
+ \x43e158e460913d00 | 1e+19 | 1e+19 | \x43e158e460913d00 | t
+ \x43e158e460913d01 | 1.0000000000000002e+19 | 1.0000000000000002e+19 | \x43e158e460913d01 | t
+ \x4415af1d78b58c3f | 9.999999999999998e+19 | 9.999999999999998e+19 | \x4415af1d78b58c3f | t
+ \x4415af1d78b58c40 | 1e+20 | 1e+20 | \x4415af1d78b58c40 | t
+ \x4415af1d78b58c41 | 1.0000000000000002e+20 | 1.0000000000000002e+20 | \x4415af1d78b58c41 | t
+ \x444b1ae4d6e2ef4f | 9.999999999999999e+20 | 9.999999999999999e+20 | \x444b1ae4d6e2ef4f | t
+ \x444b1ae4d6e2ef50 | 1e+21 | 1e+21 | \x444b1ae4d6e2ef50 | t
+ \x444b1ae4d6e2ef51 | 1.0000000000000001e+21 | 1.0000000000000001e+21 | \x444b1ae4d6e2ef51 | t
+ \x4480f0cf064dd591 | 9.999999999999998e+21 | 9.999999999999998e+21 | \x4480f0cf064dd591 | t
+ \x4480f0cf064dd592 | 1e+22 | 1e+22 | \x4480f0cf064dd592 | t
+ \x4480f0cf064dd593 | 1.0000000000000002e+22 | 1.0000000000000002e+22 | \x4480f0cf064dd593 | t
+ \x44b52d02c7e14af5 | 9.999999999999997e+22 | 9.999999999999997e+22 | \x44b52d02c7e14af5 | t
+ \x44b52d02c7e14af6 | 9.999999999999999e+22 | 9.999999999999999e+22 | \x44b52d02c7e14af6 | t
+ \x44b52d02c7e14af7 | 1.0000000000000001e+23 | 1.0000000000000001e+23 | \x44b52d02c7e14af7 | t
+ \x44ea784379d99db3 | 9.999999999999998e+23 | 9.999999999999998e+23 | \x44ea784379d99db3 | t
+ \x44ea784379d99db4 | 1e+24 | 1e+24 | \x44ea784379d99db4 | t
+ \x44ea784379d99db5 | 1.0000000000000001e+24 | 1.0000000000000001e+24 | \x44ea784379d99db5 | t
+ \x45208b2a2c280290 | 9.999999999999999e+24 | 9.999999999999999e+24 | \x45208b2a2c280290 | t
+ \x45208b2a2c280291 | 1e+25 | 1e+25 | \x45208b2a2c280291 | t
+ \x45208b2a2c280292 | 1.0000000000000003e+25 | 1.0000000000000003e+25 | \x45208b2a2c280292 | t
+ \x7feffffffffffffe | 1.7976931348623155e+308 | 1.7976931348623155e+308 | \x7feffffffffffffe | t
+ \x7fefffffffffffff | 1.7976931348623157e+308 | 1.7976931348623157e+308 | \x7fefffffffffffff | t
+ \x4350000000000002 | 1.8014398509481992e+16 | 1.8014398509481992e+16 | \x4350000000000002 | t
+ \x4350000000002e06 | 1.8014398509529112e+16 | 1.8014398509529112e+16 | \x4350000000002e06 | t
+ \x4352000000000003 | 2.0266198323167244e+16 | 2.0266198323167244e+16 | \x4352000000000003 | t
+ \x4352000000000004 | 2.0266198323167248e+16 | 2.0266198323167248e+16 | \x4352000000000004 | t
+ \x4358000000000003 | 2.7021597764222988e+16 | 2.7021597764222988e+16 | \x4358000000000003 | t
+ \x4358000000000004 | 2.7021597764222992e+16 | 2.7021597764222992e+16 | \x4358000000000004 | t
+ \x435f000000000020 | 3.4902897112121472e+16 | 3.4902897112121472e+16 | \x435f000000000020 | t
+ \xc350000000000002 | -1.8014398509481992e+16 | -1.8014398509481992e+16 | \xc350000000000002 | t
+ \xc350000000002e06 | -1.8014398509529112e+16 | -1.8014398509529112e+16 | \xc350000000002e06 | t
+ \xc352000000000003 | -2.0266198323167244e+16 | -2.0266198323167244e+16 | \xc352000000000003 | t
+ \xc352000000000004 | -2.0266198323167248e+16 | -2.0266198323167248e+16 | \xc352000000000004 | t
+ \xc358000000000003 | -2.7021597764222988e+16 | -2.7021597764222988e+16 | \xc358000000000003 | t
+ \xc358000000000004 | -2.7021597764222992e+16 | -2.7021597764222992e+16 | \xc358000000000004 | t
+ \xc35f000000000020 | -3.4902897112121472e+16 | -3.4902897112121472e+16 | \xc35f000000000020 | t
+ \x42dc12218377de66 | 123456789012345.6 | 123456789012345.6 | \x42dc12218377de66 | t
+ \x42a674e79c5fe51f | 12345678901234.56 | 12345678901234.56 | \x42a674e79c5fe51f | t
+ \x4271f71fb04cb74c | 1234567890123.456 | 1234567890123.456 | \x4271f71fb04cb74c | t
+ \x423cbe991a145879 | 123456789012.3456 | 123456789012.3456 | \x423cbe991a145879 | t
+ \x4206fee0e1a9e061 | 12345678901.23456 | 12345678901.23456 | \x4206fee0e1a9e061 | t
+ \x41d26580b487e6b4 | 1234567890.123456 | 1234567890.123456 | \x41d26580b487e6b4 | t
+ \x419d6f34540ca453 | 123456789.0123456 | 123456789.0123456 | \x419d6f34540ca453 | t
+ \x41678c29dcd6e9dc | 12345678.90123456 | 12345678.90123456 | \x41678c29dcd6e9dc | t
+ \x4132d687e3df217d | 1234567.890123456 | 1234567.890123456 | \x4132d687e3df217d | t
+ \x40fe240c9fcb68c8 | 123456.7890123456 | 123456.7890123456 | \x40fe240c9fcb68c8 | t
+ \x40c81cd6e63c53d3 | 12345.67890123456 | 12345.67890123456 | \x40c81cd6e63c53d3 | t
+ \x40934a4584fd0fdc | 1234.567890123456 | 1234.567890123456 | \x40934a4584fd0fdc | t
+ \x405edd3c07fb4c93 | 123.4567890123456 | 123.4567890123456 | \x405edd3c07fb4c93 | t
+ \x4028b0fcd32f7076 | 12.34567890123456 | 12.34567890123456 | \x4028b0fcd32f7076 | t
+ \x3ff3c0ca428c59f8 | 1.234567890123456 | 1.234567890123456 | \x3ff3c0ca428c59f8 | t
+ \x3e60000000000000 | 2.9802322387695312e-08 | 2.9802322387695312e-08 | \x3e60000000000000 | t
+ \xc352bd2668e077c4 | -2.1098088986959632e+16 | -2.1098088986959632e+16 | \xc352bd2668e077c4 | t
+ \x434018601510c000 | 9.0608011534336e+15 | 9.0608011534336e+15 | \x434018601510c000 | t
+ \x43d055dc36f24000 | 4.708356024711512e+18 | 4.708356024711512e+18 | \x43d055dc36f24000 | t
+ \x43e052961c6f8000 | 9.409340012568248e+18 | 9.409340012568248e+18 | \x43e052961c6f8000 | t
+ \x3ff3c0ca2a5b1d5d | 1.2345678 | 1.2345678 | \x3ff3c0ca2a5b1d5d | t
+ \x4830f0cf064dd592 | 5.764607523034235e+39 | 5.764607523034235e+39 | \x4830f0cf064dd592 | t
+ \x4840f0cf064dd592 | 1.152921504606847e+40 | 1.152921504606847e+40 | \x4840f0cf064dd592 | t
+ \x4850f0cf064dd592 | 2.305843009213694e+40 | 2.305843009213694e+40 | \x4850f0cf064dd592 | t
+ \x3ff3333333333333 | 1.2 | 1.2 | \x3ff3333333333333 | t
+ \x3ff3ae147ae147ae | 1.23 | 1.23 | \x3ff3ae147ae147ae | t
+ \x3ff3be76c8b43958 | 1.234 | 1.234 | \x3ff3be76c8b43958 | t
+ \x3ff3c083126e978d | 1.2345 | 1.2345 | \x3ff3c083126e978d | t
+ \x3ff3c0c1fc8f3238 | 1.23456 | 1.23456 | \x3ff3c0c1fc8f3238 | t
+ \x3ff3c0c9539b8887 | 1.234567 | 1.234567 | \x3ff3c0c9539b8887 | t
+ \x3ff3c0ca2a5b1d5d | 1.2345678 | 1.2345678 | \x3ff3c0ca2a5b1d5d | t
+ \x3ff3c0ca4283de1b | 1.23456789 | 1.23456789 | \x3ff3c0ca4283de1b | t
+ \x3ff3c0ca43db770a | 1.234567895 | 1.234567895 | \x3ff3c0ca43db770a | t
+ \x3ff3c0ca428abd53 | 1.2345678901 | 1.2345678901 | \x3ff3c0ca428abd53 | t
+ \x3ff3c0ca428c1d2b | 1.23456789012 | 1.23456789012 | \x3ff3c0ca428c1d2b | t
+ \x3ff3c0ca428c51f2 | 1.234567890123 | 1.234567890123 | \x3ff3c0ca428c51f2 | t
+ \x3ff3c0ca428c58fc | 1.2345678901234 | 1.2345678901234 | \x3ff3c0ca428c58fc | t
+ \x3ff3c0ca428c59dd | 1.23456789012345 | 1.23456789012345 | \x3ff3c0ca428c59dd | t
+ \x3ff3c0ca428c59f8 | 1.234567890123456 | 1.234567890123456 | \x3ff3c0ca428c59f8 | t
+ \x3ff3c0ca428c59fb | 1.2345678901234567 | 1.2345678901234567 | \x3ff3c0ca428c59fb | t
+ \x40112e0be8047a7d | 4.294967294 | 4.294967294 | \x40112e0be8047a7d | t
+ \x40112e0be815a889 | 4.294967295 | 4.294967295 | \x40112e0be815a889 | t
+ \x40112e0be826d695 | 4.294967296 | 4.294967296 | \x40112e0be826d695 | t
+ \x40112e0be83804a1 | 4.294967297 | 4.294967297 | \x40112e0be83804a1 | t
+ \x40112e0be84932ad | 4.294967298 | 4.294967298 | \x40112e0be84932ad | t
+ \x0040000000000000 | 1.7800590868057611e-307 | 1.7800590868057611e-307 | \x0040000000000000 | t
+ \x007fffffffffffff | 2.8480945388892175e-306 | 2.8480945388892175e-306 | \x007fffffffffffff | t
+ \x0290000000000000 | 2.446494580089078e-296 | 2.446494580089078e-296 | \x0290000000000000 | t
+ \x029fffffffffffff | 4.8929891601781557e-296 | 4.8929891601781557e-296 | \x029fffffffffffff | t
+ \x4350000000000000 | 1.8014398509481984e+16 | 1.8014398509481984e+16 | \x4350000000000000 | t
+ \x435fffffffffffff | 3.6028797018963964e+16 | 3.6028797018963964e+16 | \x435fffffffffffff | t
+ \x1330000000000000 | 2.900835519859558e-216 | 2.900835519859558e-216 | \x1330000000000000 | t
+ \x133fffffffffffff | 5.801671039719115e-216 | 5.801671039719115e-216 | \x133fffffffffffff | t
+ \x3a6fa7161a4d6e0c | 3.196104012172126e-27 | 3.196104012172126e-27 | \x3a6fa7161a4d6e0c | t
+(209 rows)
+
+-- clean up, lest opr_sanity complain
+\set VERBOSITY terse
+drop type xfloat8 cascade;
+NOTICE: drop cascades to 6 other objects
+\set VERBOSITY default
+--
diff --git a/src/test/regress/expected/int8.out b/src/test/regress/expected/int8.out
index 35e3b3ff81..8447a28c3d 100644
--- a/src/test/regress/expected/int8.out
+++ b/src/test/regress/expected/int8.out
@@ -329,23 +329,23 @@ SELECT '' AS five, q1, q2, q1 / q2 AS divide, q1 % q2 AS mod FROM INT8_TBL;
(5 rows)
SELECT '' AS five, q1, float8(q1) FROM INT8_TBL;
- five | q1 | float8
-------+------------------+----------------------
- | 123 | 123
- | 123 | 123
- | 4567890123456789 | 4.56789012345679e+15
- | 4567890123456789 | 4.56789012345679e+15
- | 4567890123456789 | 4.56789012345679e+15
+ five | q1 | float8
+------+------------------+-----------------------
+ | 123 | 123
+ | 123 | 123
+ | 4567890123456789 | 4.567890123456789e+15
+ | 4567890123456789 | 4.567890123456789e+15
+ | 4567890123456789 | 4.567890123456789e+15
(5 rows)
SELECT '' AS five, q2, float8(q2) FROM INT8_TBL;
- five | q2 | float8
-------+-------------------+-----------------------
- | 456 | 456
- | 4567890123456789 | 4.56789012345679e+15
- | 123 | 123
- | 4567890123456789 | 4.56789012345679e+15
- | -4567890123456789 | -4.56789012345679e+15
+ five | q2 | float8
+------+-------------------+------------------------
+ | 456 | 456
+ | 4567890123456789 | 4.567890123456789e+15
+ | 123 | 123
+ | 4567890123456789 | 4.567890123456789e+15
+ | -4567890123456789 | -4.567890123456789e+15
(5 rows)
SELECT 37 + q1 AS plus4 FROM INT8_TBL;
@@ -726,13 +726,13 @@ SELECT CAST('42'::int2 AS int8), CAST('-37'::int2 AS int8);
(1 row)
SELECT CAST(q1 AS float4), CAST(q2 AS float8) FROM INT8_TBL;
- q1 | q2
--------------+-----------------------
- 123 | 456
- 123 | 4.56789012345679e+15
- 4.56789e+15 | 123
- 4.56789e+15 | 4.56789012345679e+15
- 4.56789e+15 | -4.56789012345679e+15
+ q1 | q2
+-------------+------------------------
+ 123 | 456
+ 123 | 4.567890123456789e+15
+ 4.56789e+15 | 123
+ 4.56789e+15 | 4.567890123456789e+15
+ 4.56789e+15 | -4.567890123456789e+15
(5 rows)
SELECT CAST('36854775807.0'::float4 AS int8);
diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out
index 0ac47fcaee..8dcdaf5602 100644
--- a/src/test/regress/expected/jsonb.out
+++ b/src/test/regress/expected/jsonb.out
@@ -4376,9 +4376,9 @@ select '12345.05'::jsonb::numeric;
(1 row)
select '12345.05'::jsonb::float4;
- float4
---------
- 12345
+ float4
+----------
+ 12345.05
(1 row)
select '12345.05'::jsonb::float8;
diff --git a/src/test/regress/expected/line.out b/src/test/regress/expected/line.out
index bf780daa2c..fe106589c6 100644
--- a/src/test/regress/expected/line.out
+++ b/src/test/regress/expected/line.out
@@ -64,14 +64,14 @@ LINE 1: INSERT INTO LINE_TBL VALUES ('[(1,2),(1,2)]');
INSERT INTO LINE_TBL VALUES (line(point '(1,0)', point '(1,0)'));
ERROR: invalid line specification: must be two distinct points
select * from LINE_TBL;
- s
----------------------------------------------
+ s
+------------------------------------------------
{0,-1,5}
{1,0,5}
{0,3,0}
{1,-1,0}
{-0.4,-1,-6}
- {-0.000184615384615385,-1,15.3846153846154}
+ {-0.0001846153846153846,-1,15.384615384615387}
{3,NaN,5}
{NaN,NaN,NaN}
{0,-1,3}
diff --git a/src/test/regress/expected/point.out b/src/test/regress/expected/point.out
index c18e865370..15e3b83b37 100644
--- a/src/test/regress/expected/point.out
+++ b/src/test/regress/expected/point.out
@@ -1,6 +1,8 @@
--
-- POINT
--
+-- avoid bit-exact output here because operations may not be bit-exact.
+SET extra_float_digits = 0;
CREATE TABLE POINT_TBL(f1 point);
INSERT INTO POINT_TBL(f1) VALUES ('(0.0,0.0)');
INSERT INTO POINT_TBL(f1) VALUES ('(-10.0,0.0)');
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 2c8e21baa7..b31594a7b5 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -910,24 +910,24 @@ insert into rtest_comp values ('p4', 'cm', 15.0);
insert into rtest_comp values ('p5', 'inch', 7.0);
insert into rtest_comp values ('p6', 'inch', 4.4);
select * from rtest_vcomp order by part;
- part | size_in_cm
-------+------------
- p1 | 500
- p2 | 300
- p3 | 5
- p4 | 15
- p5 | 17.78
- p6 | 11.176
+ part | size_in_cm
+------+--------------------
+ p1 | 500
+ p2 | 300
+ p3 | 5
+ p4 | 15
+ p5 | 17.78
+ p6 | 11.176000000000002
(6 rows)
select * from rtest_vcomp where size_in_cm > 10.0 order by size_in_cm using >;
- part | size_in_cm
-------+------------
- p1 | 500
- p2 | 300
- p5 | 17.78
- p4 | 15
- p6 | 11.176
+ part | size_in_cm
+------+--------------------
+ p1 | 500
+ p2 | 300
+ p5 | 17.78
+ p4 | 15
+ p6 | 11.176000000000002
(5 rows)
--
diff --git a/src/test/regress/expected/tsearch.out b/src/test/regress/expected/tsearch.out
index b088ff0d4f..6f61acc1ed 100644
--- a/src/test/regress/expected/tsearch.out
+++ b/src/test/regress/expected/tsearch.out
@@ -970,9 +970,9 @@ Water, water, every where,
Nor any drop to drink.
S. T. Coleridge (1772-1834)
'), to_tsquery('english', 'breath&motion&water'));
- ts_rank_cd
-------------
- 0.00833333
+ ts_rank_cd
+-------------
+ 0.008333334
(1 row)
SELECT ts_rank_cd(to_tsvector('english', '
diff --git a/src/test/regress/expected/tstypes.out b/src/test/regress/expected/tstypes.out
index 6272e70e09..87a36ca329 100644
--- a/src/test/regress/expected/tstypes.out
+++ b/src/test/regress/expected/tstypes.out
@@ -787,57 +787,57 @@ select to_tsvector('simple', '') @@ '!foo' AS "true";
--ranking
SELECT ts_rank(' a:1 s:2C d g'::tsvector, 'a | s');
- ts_rank
------------
- 0.0911891
+ ts_rank
+-------------
+ 0.091189064
(1 row)
SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | s');
- ts_rank
------------
- 0.0303964
+ ts_rank
+-------------
+ 0.030396355
(1 row)
SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | s:*');
- ts_rank
------------
- 0.0911891
+ ts_rank
+-------------
+ 0.091189064
(1 row)
SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | sa:*');
- ts_rank
------------
- 0.0911891
+ ts_rank
+-------------
+ 0.091189064
(1 row)
SELECT ts_rank(' a:1 s:2B d g'::tsvector, 'a | s');
- ts_rank
-----------
- 0.151982
+ ts_rank
+------------
+ 0.15198177
(1 row)
SELECT ts_rank(' a:1 s:2 d g'::tsvector, 'a | s');
- ts_rank
------------
- 0.0607927
+ ts_rank
+------------
+ 0.06079271
(1 row)
SELECT ts_rank(' a:1 s:2C d g'::tsvector, 'a & s');
- ts_rank
-----------
- 0.140153
+ ts_rank
+------------
+ 0.14015312
(1 row)
SELECT ts_rank(' a:1 s:2B d g'::tsvector, 'a & s');
- ts_rank
-----------
- 0.198206
+ ts_rank
+------------
+ 0.19820644
(1 row)
SELECT ts_rank(' a:1 s:2 d g'::tsvector, 'a & s');
- ts_rank
------------
- 0.0991032
+ ts_rank
+------------
+ 0.09910322
(1 row)
SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a | s');
@@ -885,7 +885,7 @@ SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a | s');
SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a & s');
ts_rank_cd
------------
- 0.133333
+ 0.13333334
(1 row)
SELECT ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a & s');
@@ -903,13 +903,13 @@ SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a & s');
SELECT ts_rank_cd(' a:1 s:2A d g'::tsvector, 'a <-> s');
ts_rank_cd
------------
- 0.181818
+ 0.18181819
(1 row)
SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a <-> s');
ts_rank_cd
------------
- 0.133333
+ 0.13333334
(1 row)
SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a <-> s');
@@ -927,13 +927,13 @@ SELECT ts_rank_cd(' a:1 s:2 d:2A g'::tsvector, 'a <-> s');
SELECT ts_rank_cd(' a:1 s:2,3A d:2A g'::tsvector, 'a <2> s:A');
ts_rank_cd
------------
- 0.0909091
+ 0.09090909
(1 row)
SELECT ts_rank_cd(' a:1 b:2 s:3A d:2A g'::tsvector, 'a <2> s:A');
ts_rank_cd
------------
- 0.0909091
+ 0.09090909
(1 row)
SELECT ts_rank_cd(' a:1 sa:2D sb:2A g'::tsvector, 'a <-> s:*');
diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out
index 420c5a54f2..8b13ef3a09 100644
--- a/src/test/regress/expected/updatable_views.out
+++ b/src/test/regress/expected/updatable_views.out
@@ -1,6 +1,8 @@
--
-- UPDATABLE VIEWS
--
+-- avoid bit-exact output here because operations may not be bit-exact.
+SET extra_float_digits = 0;
-- check that non-updatable views and columns are rejected with useful error
-- messages
CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified');
diff --git a/src/test/regress/expected/window.out b/src/test/regress/expected/window.out
index 662d348653..edc93d5729 100644
--- a/src/test/regress/expected/window.out
+++ b/src/test/regress/expected/window.out
@@ -204,33 +204,33 @@ SELECT dense_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1
(10 rows)
SELECT percent_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
- percent_rank | ten | four
--------------------+-----+------
- 0 | 0 | 0
- 0 | 0 | 0
- 1 | 4 | 0
- 0 | 1 | 1
- 0 | 1 | 1
- 0.666666666666667 | 7 | 1
- 1 | 9 | 1
- 0 | 0 | 2
- 0 | 1 | 3
- 1 | 3 | 3
+ percent_rank | ten | four
+--------------------+-----+------
+ 0 | 0 | 0
+ 0 | 0 | 0
+ 1 | 4 | 0
+ 0 | 1 | 1
+ 0 | 1 | 1
+ 0.6666666666666666 | 7 | 1
+ 1 | 9 | 1
+ 0 | 0 | 2
+ 0 | 1 | 3
+ 1 | 3 | 3
(10 rows)
SELECT cume_dist() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
- cume_dist | ten | four
--------------------+-----+------
- 0.666666666666667 | 0 | 0
- 0.666666666666667 | 0 | 0
- 1 | 4 | 0
- 0.5 | 1 | 1
- 0.5 | 1 | 1
- 0.75 | 7 | 1
- 1 | 9 | 1
- 1 | 0 | 2
- 0.5 | 1 | 3
- 1 | 3 | 3
+ cume_dist | ten | four
+--------------------+-----+------
+ 0.6666666666666666 | 0 | 0
+ 0.6666666666666666 | 0 | 0
+ 1 | 4 | 0
+ 0.5 | 1 | 1
+ 0.5 | 1 | 1
+ 0.75 | 7 | 1
+ 1 | 9 | 1
+ 1 | 0 | 2
+ 0.5 | 1 | 3
+ 1 | 3 | 3
(10 rows)
SELECT ntile(3) OVER (ORDER BY ten, four), ten, four FROM tenk1 WHERE unique2 < 10;
diff --git a/src/test/regress/sql/aggregates.sql b/src/test/regress/sql/aggregates.sql
index a09fa47ae4..d4fd657188 100644
--- a/src/test/regress/sql/aggregates.sql
+++ b/src/test/regress/sql/aggregates.sql
@@ -2,6 +2,9 @@
-- AGGREGATES
--
+-- avoid bit-exact output here because operations may not be bit-exact.
+SET extra_float_digits = 0;
+
SELECT avg(four) AS avg_1 FROM onek;
SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100;
diff --git a/src/test/regress/sql/circle.sql b/src/test/regress/sql/circle.sql
index 46c96e1400..10e51d780e 100644
--- a/src/test/regress/sql/circle.sql
+++ b/src/test/regress/sql/circle.sql
@@ -2,6 +2,9 @@
-- CIRCLE
--
+-- avoid bit-exact output here because operations may not be bit-exact.
+SET extra_float_digits = 0;
+
CREATE TABLE CIRCLE_TBL (f1 circle);
INSERT INTO CIRCLE_TBL VALUES ('<(5,1),3>');
diff --git a/src/test/regress/sql/float4.sql b/src/test/regress/sql/float4.sql
index 1fc482e146..d606e7787b 100644
--- a/src/test/regress/sql/float4.sql
+++ b/src/test/regress/sql/float4.sql
@@ -132,3 +132,222 @@ SELECT float4send('750486563e-38'::float4);
SELECT float4send('1.17549435e-38'::float4);
SELECT float4send('1.1754944e-38'::float4);
+
+-- test output (and round-trip safety) of various values.
+-- To ensure we're testing what we think we're testing, start with
+-- float values specified by bit patterns (as a useful side effect,
+-- this means we'll fail on non-IEEE platforms).
+
+create type xfloat4;
+create function xfloat4in(cstring) returns xfloat4 immutable strict
+ language internal as 'int4in';
+create function xfloat4out(xfloat4) returns cstring immutable strict
+ language internal as 'int4out';
+create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4);
+create cast (xfloat4 as float4) without function;
+create cast (float4 as xfloat4) without function;
+create cast (xfloat4 as integer) without function;
+create cast (integer as xfloat4) without function;
+
+-- float4: seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
+
+-- we don't care to assume the platform's strtod() handles subnormals
+-- correctly; those are "use at your own risk". However we do test
+-- subnormal outputs, since those are under our control.
+
+with testdata(bits) as (values
+ -- small subnormals
+ (x'00000001'),
+ (x'00000002'), (x'00000003'),
+ (x'00000010'), (x'00000011'), (x'00000100'), (x'00000101'),
+ (x'00004000'), (x'00004001'), (x'00080000'), (x'00080001'),
+ -- stress values
+ (x'0053c4f4'), -- 7693e-42
+ (x'006c85c4'), -- 996622e-44
+ (x'0041ca76'), -- 60419369e-46
+ (x'004b7678'), -- 6930161142e-48
+ -- taken from upstream testsuite
+ (x'00000007'),
+ (x'00424fe2'),
+ -- borderline between subnormal and normal
+ (x'007ffff0'), (x'007ffff1'), (x'007ffffe'), (x'007fffff'))
+select float4send(flt) as ibits,
+ flt
+ from (select bits::integer::xfloat4::float4 as flt
+ from testdata
+ offset 0) s;
+
+with testdata(bits) as (values
+ (x'00000000'),
+ -- smallest normal values
+ (x'00800000'), (x'00800001'), (x'00800004'), (x'00800005'),
+ (x'00800006'),
+ -- small normal values chosen for short vs. long output
+ (x'008002f1'), (x'008002f2'), (x'008002f3'),
+ (x'00800e17'), (x'00800e18'), (x'00800e19'),
+ -- assorted values (random mantissae)
+ (x'01000001'), (x'01102843'), (x'01a52c98'),
+ (x'0219c229'), (x'02e4464d'), (x'037343c1'), (x'03a91b36'),
+ (x'047ada65'), (x'0496fe87'), (x'0550844f'), (x'05999da3'),
+ (x'060ea5e2'), (x'06e63c45'), (x'07f1e548'), (x'0fc5282b'),
+ (x'1f850283'), (x'2874a9d6'),
+ -- values around 5e-08
+ (x'3356bf94'), (x'3356bf95'), (x'3356bf96'),
+ -- around 1e-07
+ (x'33d6bf94'), (x'33d6bf95'), (x'33d6bf96'),
+ -- around 3e-07 .. 1e-04
+ (x'34a10faf'), (x'34a10fb0'), (x'34a10fb1'),
+ (x'350637bc'), (x'350637bd'), (x'350637be'),
+ (x'35719786'), (x'35719787'), (x'35719788'),
+ (x'358637bc'), (x'358637bd'), (x'358637be'),
+ (x'36a7c5ab'), (x'36a7c5ac'), (x'36a7c5ad'),
+ (x'3727c5ab'), (x'3727c5ac'), (x'3727c5ad'),
+ -- format crossover at 1e-04
+ (x'38d1b714'), (x'38d1b715'), (x'38d1b716'),
+ (x'38d1b717'), (x'38d1b718'), (x'38d1b719'),
+ (x'38d1b71a'), (x'38d1b71b'), (x'38d1b71c'),
+ (x'38d1b71d'),
+ --
+ (x'38dffffe'), (x'38dfffff'), (x'38e00000'),
+ (x'38efffff'), (x'38f00000'), (x'38f00001'),
+ (x'3a83126e'), (x'3a83126f'), (x'3a831270'),
+ (x'3c23d709'), (x'3c23d70a'), (x'3c23d70b'),
+ (x'3dcccccc'), (x'3dcccccd'), (x'3dccccce'),
+ -- chosen to need 9 digits for 3dcccd70
+ (x'3dcccd6f'), (x'3dcccd70'), (x'3dcccd71'),
+ --
+ (x'3effffff'), (x'3f000000'), (x'3f000001'),
+ (x'3f333332'), (x'3f333333'), (x'3f333334'),
+ -- approach 1.0 with increasing numbers of 9s
+ (x'3f666665'), (x'3f666666'), (x'3f666667'),
+ (x'3f7d70a3'), (x'3f7d70a4'), (x'3f7d70a5'),
+ (x'3f7fbe76'), (x'3f7fbe77'), (x'3f7fbe78'),
+ (x'3f7ff971'), (x'3f7ff972'), (x'3f7ff973'),
+ (x'3f7fff57'), (x'3f7fff58'), (x'3f7fff59'),
+ (x'3f7fffee'), (x'3f7fffef'),
+ -- values very close to 1
+ (x'3f7ffff0'), (x'3f7ffff1'), (x'3f7ffff2'),
+ (x'3f7ffff3'), (x'3f7ffff4'), (x'3f7ffff5'),
+ (x'3f7ffff6'), (x'3f7ffff7'), (x'3f7ffff8'),
+ (x'3f7ffff9'), (x'3f7ffffa'), (x'3f7ffffb'),
+ (x'3f7ffffc'), (x'3f7ffffd'), (x'3f7ffffe'),
+ (x'3f7fffff'),
+ (x'3f800000'),
+ (x'3f800001'), (x'3f800002'), (x'3f800003'),
+ (x'3f800004'), (x'3f800005'), (x'3f800006'),
+ (x'3f800007'), (x'3f800008'), (x'3f800009'),
+ -- values 1 to 1.1
+ (x'3f80000f'), (x'3f800010'), (x'3f800011'),
+ (x'3f800012'), (x'3f800013'), (x'3f800014'),
+ (x'3f800017'), (x'3f800018'), (x'3f800019'),
+ (x'3f80001a'), (x'3f80001b'), (x'3f80001c'),
+ (x'3f800029'), (x'3f80002a'), (x'3f80002b'),
+ (x'3f800053'), (x'3f800054'), (x'3f800055'),
+ (x'3f800346'), (x'3f800347'), (x'3f800348'),
+ (x'3f8020c4'), (x'3f8020c5'), (x'3f8020c6'),
+ (x'3f8147ad'), (x'3f8147ae'), (x'3f8147af'),
+ (x'3f8ccccc'), (x'3f8ccccd'), (x'3f8cccce'),
+ --
+ (x'3fc90fdb'), -- pi/2
+ (x'402df854'), -- e
+ (x'40490fdb'), -- pi
+ --
+ (x'409fffff'), (x'40a00000'), (x'40a00001'),
+ (x'40afffff'), (x'40b00000'), (x'40b00001'),
+ (x'411fffff'), (x'41200000'), (x'41200001'),
+ (x'42c7ffff'), (x'42c80000'), (x'42c80001'),
+ (x'4479ffff'), (x'447a0000'), (x'447a0001'),
+ (x'461c3fff'), (x'461c4000'), (x'461c4001'),
+ (x'47c34fff'), (x'47c35000'), (x'47c35001'),
+ (x'497423ff'), (x'49742400'), (x'49742401'),
+ (x'4b18967f'), (x'4b189680'), (x'4b189681'),
+ (x'4cbebc1f'), (x'4cbebc20'), (x'4cbebc21'),
+ (x'4e6e6b27'), (x'4e6e6b28'), (x'4e6e6b29'),
+ (x'501502f8'), (x'501502f9'), (x'501502fa'),
+ (x'51ba43b6'), (x'51ba43b7'), (x'51ba43b8'),
+ -- stress values
+ (x'1f6c1e4a'), -- 5e-20
+ (x'59be6cea'), -- 67e14
+ (x'5d5ab6c4'), -- 985e15
+ (x'2cc4a9bd'), -- 55895e-16
+ (x'15ae43fd'), -- 7038531e-32
+ (x'2cf757ca'), -- 702990899e-20
+ (x'665ba998'), -- 25933168707e13
+ (x'743c3324'), -- 596428896559e20
+ -- exercise fixed-point memmoves
+ (x'47f1205a'),
+ (x'4640e6ae'),
+ (x'449a5225'),
+ (x'42f6e9d5'),
+ (x'414587dd'),
+ (x'3f9e064b'),
+ -- these cases come from the upstream's testsuite
+ -- BoundaryRoundEven
+ (x'4c000004'),
+ (x'50061c46'),
+ (x'510006a8'),
+ -- ExactValueRoundEven
+ (x'48951f84'),
+ (x'45fd1840'),
+ -- LotsOfTrailingZeros
+ (x'39800000'),
+ (x'3b200000'),
+ (x'3b900000'),
+ (x'3bd00000'),
+ -- Regression
+ (x'63800000'),
+ (x'4b000000'),
+ (x'4b800000'),
+ (x'4c000001'),
+ (x'4c800b0d'),
+ (x'00d24584'),
+ (x'800000b0'),
+ (x'00d90b88'),
+ (x'45803f34'),
+ (x'4f9f24f7'),
+ (x'3a8722c3'),
+ (x'5c800041'),
+ (x'15ae43fd'),
+ (x'5d4cccfb'),
+ (x'4c800001'),
+ (x'57800ed8'),
+ (x'5f000000'),
+ (x'700000f0'),
+ (x'5f23e9ac'),
+ (x'5e9502f9'),
+ (x'5e8012b1'),
+ (x'3c000028'),
+ (x'60cde861'),
+ (x'03aa2a50'),
+ (x'43480000'),
+ (x'4c000000'),
+ -- LooksLikePow5
+ (x'5D1502F9'),
+ (x'5D9502F9'),
+ (x'5E1502F9'),
+ -- OutputLength
+ (x'3f99999a'),
+ (x'3f9d70a4'),
+ (x'3f9df3b6'),
+ (x'3f9e0419'),
+ (x'3f9e0610'),
+ (x'3f9e064b'),
+ (x'3f9e0651'),
+ (x'03d20cfe')
+)
+select float4send(flt) as ibits,
+ flt,
+ flt::text::float4 as r_flt,
+ float4send(flt::text::float4) as obits,
+ float4send(flt::text::float4) = float4send(flt) as correct
+ from (select bits::integer::xfloat4::float4 as flt
+ from testdata
+ offset 0) s;
+
+-- clean up, lest opr_sanity complain
+
+\set VERBOSITY terse
+drop type xfloat4 cascade;
+\set VERBOSITY default
+
+--
diff --git a/src/test/regress/sql/float8.sql b/src/test/regress/sql/float8.sql
index 6595fd2b95..a33321811d 100644
--- a/src/test/regress/sql/float8.sql
+++ b/src/test/regress/sql/float8.sql
@@ -16,6 +16,9 @@ SELECT '-10e400'::float8;
SELECT '10e-400'::float8;
SELECT '-10e-400'::float8;
+-- test smallest normalized input
+SELECT float8send('2.2250738585072014E-308'::float8);
+
-- bad input
INSERT INTO FLOAT8_TBL(f1) VALUES ('');
INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
@@ -97,6 +100,9 @@ select floor(f1) as floor_f1 from float8_tbl f;
-- sign
select sign(f1) as sign_f1 from float8_tbl f;
+-- avoid bit-exact output here because operations may not be bit-exact.
+SET extra_float_digits = 0;
+
-- square root
SELECT sqrt(float8 '64') AS eight;
@@ -148,6 +154,8 @@ SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
SELECT '' AS five, * FROM FLOAT8_TBL;
+RESET extra_float_digits;
+
-- test for over- and underflow
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
@@ -189,7 +197,6 @@ SELECT '-9223372036854775808.5'::float8::int8;
SELECT '-9223372036854780000'::float8::int8;
-- test exact cases for trigonometric functions in degrees
-SET extra_float_digits = 3;
SELECT x,
sind(x),
@@ -232,4 +239,203 @@ SELECT x, y,
FROM (SELECT 10*cosd(a), 10*sind(a)
FROM generate_series(0, 360, 90) AS t(a)) AS t(x,y);
-RESET extra_float_digits;
+--
+-- test output (and round-trip safety) of various values.
+-- To ensure we're testing what we think we're testing, start with
+-- float values specified by bit patterns (as a useful side effect,
+-- this means we'll fail on non-IEEE platforms).
+
+create type xfloat8;
+create function xfloat8in(cstring) returns xfloat8 immutable strict
+ language internal as 'int8in';
+create function xfloat8out(xfloat8) returns cstring immutable strict
+ language internal as 'int8out';
+create type xfloat8 (input = xfloat8in, output = xfloat8out, like = float8);
+create cast (xfloat8 as float8) without function;
+create cast (float8 as xfloat8) without function;
+create cast (xfloat8 as bigint) without function;
+create cast (bigint as xfloat8) without function;
+
+-- float8: seeeeeee eeeeeeee eeeeeeee mmmmmmmm mmmmmmmm(x4)
+
+-- we don't care to assume the platform's strtod() handles subnormals
+-- correctly; those are "use at your own risk". However we do test
+-- subnormal outputs, since those are under our control.
+
+with testdata(bits) as (values
+ -- small subnormals
+ (x'0000000000000001'),
+ (x'0000000000000002'), (x'0000000000000003'),
+ (x'0000000000001000'), (x'0000000100000000'),
+ (x'0000010000000000'), (x'0000010100000000'),
+ (x'0000400000000000'), (x'0000400100000000'),
+ (x'0000800000000000'), (x'0000800000000001'),
+ -- these values taken from upstream testsuite
+ (x'00000000000f4240'),
+ (x'00000000016e3600'),
+ (x'0000008cdcdea440'),
+ -- borderline between subnormal and normal
+ (x'000ffffffffffff0'), (x'000ffffffffffff1'),
+ (x'000ffffffffffffe'), (x'000fffffffffffff'))
+select float8send(flt) as ibits,
+ flt
+ from (select bits::bigint::xfloat8::float8 as flt
+ from testdata
+ offset 0) s;
+
+-- round-trip tests
+
+with testdata(bits) as (values
+ (x'0000000000000000'),
+ -- smallest normal values
+ (x'0010000000000000'), (x'0010000000000001'),
+ (x'0010000000000002'), (x'0018000000000000'),
+ --
+ (x'3ddb7cdfd9d7bdba'), (x'3ddb7cdfd9d7bdbb'), (x'3ddb7cdfd9d7bdbc'),
+ (x'3e112e0be826d694'), (x'3e112e0be826d695'), (x'3e112e0be826d696'),
+ (x'3e45798ee2308c39'), (x'3e45798ee2308c3a'), (x'3e45798ee2308c3b'),
+ (x'3e7ad7f29abcaf47'), (x'3e7ad7f29abcaf48'), (x'3e7ad7f29abcaf49'),
+ (x'3eb0c6f7a0b5ed8c'), (x'3eb0c6f7a0b5ed8d'), (x'3eb0c6f7a0b5ed8e'),
+ (x'3ee4f8b588e368ef'), (x'3ee4f8b588e368f0'), (x'3ee4f8b588e368f1'),
+ (x'3f1a36e2eb1c432c'), (x'3f1a36e2eb1c432d'), (x'3f1a36e2eb1c432e'),
+ (x'3f50624dd2f1a9fb'), (x'3f50624dd2f1a9fc'), (x'3f50624dd2f1a9fd'),
+ (x'3f847ae147ae147a'), (x'3f847ae147ae147b'), (x'3f847ae147ae147c'),
+ (x'3fb9999999999999'), (x'3fb999999999999a'), (x'3fb999999999999b'),
+ -- values very close to 1
+ (x'3feffffffffffff0'), (x'3feffffffffffff1'), (x'3feffffffffffff2'),
+ (x'3feffffffffffff3'), (x'3feffffffffffff4'), (x'3feffffffffffff5'),
+ (x'3feffffffffffff6'), (x'3feffffffffffff7'), (x'3feffffffffffff8'),
+ (x'3feffffffffffff9'), (x'3feffffffffffffa'), (x'3feffffffffffffb'),
+ (x'3feffffffffffffc'), (x'3feffffffffffffd'), (x'3feffffffffffffe'),
+ (x'3fefffffffffffff'),
+ (x'3ff0000000000000'),
+ (x'3ff0000000000001'), (x'3ff0000000000002'), (x'3ff0000000000003'),
+ (x'3ff0000000000004'), (x'3ff0000000000005'), (x'3ff0000000000006'),
+ (x'3ff0000000000007'), (x'3ff0000000000008'), (x'3ff0000000000009'),
+ --
+ (x'3ff921fb54442d18'),
+ (x'4005bf0a8b14576a'),
+ (x'400921fb54442d18'),
+ --
+ (x'4023ffffffffffff'), (x'4024000000000000'), (x'4024000000000001'),
+ (x'4058ffffffffffff'), (x'4059000000000000'), (x'4059000000000001'),
+ (x'408f3fffffffffff'), (x'408f400000000000'), (x'408f400000000001'),
+ (x'40c387ffffffffff'), (x'40c3880000000000'), (x'40c3880000000001'),
+ (x'40f869ffffffffff'), (x'40f86a0000000000'), (x'40f86a0000000001'),
+ (x'412e847fffffffff'), (x'412e848000000000'), (x'412e848000000001'),
+ (x'416312cfffffffff'), (x'416312d000000000'), (x'416312d000000001'),
+ (x'4197d783ffffffff'), (x'4197d78400000000'), (x'4197d78400000001'),
+ (x'41cdcd64ffffffff'), (x'41cdcd6500000000'), (x'41cdcd6500000001'),
+ (x'4202a05f1fffffff'), (x'4202a05f20000000'), (x'4202a05f20000001'),
+ (x'42374876e7ffffff'), (x'42374876e8000000'), (x'42374876e8000001'),
+ (x'426d1a94a1ffffff'), (x'426d1a94a2000000'), (x'426d1a94a2000001'),
+ (x'42a2309ce53fffff'), (x'42a2309ce5400000'), (x'42a2309ce5400001'),
+ (x'42d6bcc41e8fffff'), (x'42d6bcc41e900000'), (x'42d6bcc41e900001'),
+ (x'430c6bf52633ffff'), (x'430c6bf526340000'), (x'430c6bf526340001'),
+ (x'4341c37937e07fff'), (x'4341c37937e08000'), (x'4341c37937e08001'),
+ (x'4376345785d89fff'), (x'4376345785d8a000'), (x'4376345785d8a001'),
+ (x'43abc16d674ec7ff'), (x'43abc16d674ec800'), (x'43abc16d674ec801'),
+ (x'43e158e460913cff'), (x'43e158e460913d00'), (x'43e158e460913d01'),
+ (x'4415af1d78b58c3f'), (x'4415af1d78b58c40'), (x'4415af1d78b58c41'),
+ (x'444b1ae4d6e2ef4f'), (x'444b1ae4d6e2ef50'), (x'444b1ae4d6e2ef51'),
+ (x'4480f0cf064dd591'), (x'4480f0cf064dd592'), (x'4480f0cf064dd593'),
+ (x'44b52d02c7e14af5'), (x'44b52d02c7e14af6'), (x'44b52d02c7e14af7'),
+ (x'44ea784379d99db3'), (x'44ea784379d99db4'), (x'44ea784379d99db5'),
+ (x'45208b2a2c280290'), (x'45208b2a2c280291'), (x'45208b2a2c280292'),
+ --
+ (x'7feffffffffffffe'), (x'7fefffffffffffff'),
+ -- round to even tests (+ve)
+ (x'4350000000000002'),
+ (x'4350000000002e06'),
+ (x'4352000000000003'),
+ (x'4352000000000004'),
+ (x'4358000000000003'),
+ (x'4358000000000004'),
+ (x'435f000000000020'),
+ -- round to even tests (-ve)
+ (x'c350000000000002'),
+ (x'c350000000002e06'),
+ (x'c352000000000003'),
+ (x'c352000000000004'),
+ (x'c358000000000003'),
+ (x'c358000000000004'),
+ (x'c35f000000000020'),
+ -- exercise fixed-point memmoves
+ (x'42dc12218377de66'),
+ (x'42a674e79c5fe51f'),
+ (x'4271f71fb04cb74c'),
+ (x'423cbe991a145879'),
+ (x'4206fee0e1a9e061'),
+ (x'41d26580b487e6b4'),
+ (x'419d6f34540ca453'),
+ (x'41678c29dcd6e9dc'),
+ (x'4132d687e3df217d'),
+ (x'40fe240c9fcb68c8'),
+ (x'40c81cd6e63c53d3'),
+ (x'40934a4584fd0fdc'),
+ (x'405edd3c07fb4c93'),
+ (x'4028b0fcd32f7076'),
+ (x'3ff3c0ca428c59f8'),
+ -- these cases come from the upstream's testsuite
+ -- LotsOfTrailingZeros)
+ (x'3e60000000000000'),
+ -- Regression
+ (x'c352bd2668e077c4'),
+ (x'434018601510c000'),
+ (x'43d055dc36f24000'),
+ (x'43e052961c6f8000'),
+ (x'3ff3c0ca2a5b1d5d'),
+ -- LooksLikePow5
+ (x'4830f0cf064dd592'),
+ (x'4840f0cf064dd592'),
+ (x'4850f0cf064dd592'),
+ -- OutputLength
+ (x'3ff3333333333333'),
+ (x'3ff3ae147ae147ae'),
+ (x'3ff3be76c8b43958'),
+ (x'3ff3c083126e978d'),
+ (x'3ff3c0c1fc8f3238'),
+ (x'3ff3c0c9539b8887'),
+ (x'3ff3c0ca2a5b1d5d'),
+ (x'3ff3c0ca4283de1b'),
+ (x'3ff3c0ca43db770a'),
+ (x'3ff3c0ca428abd53'),
+ (x'3ff3c0ca428c1d2b'),
+ (x'3ff3c0ca428c51f2'),
+ (x'3ff3c0ca428c58fc'),
+ (x'3ff3c0ca428c59dd'),
+ (x'3ff3c0ca428c59f8'),
+ (x'3ff3c0ca428c59fb'),
+ -- 32-bit chunking
+ (x'40112e0be8047a7d'),
+ (x'40112e0be815a889'),
+ (x'40112e0be826d695'),
+ (x'40112e0be83804a1'),
+ (x'40112e0be84932ad'),
+ -- MinMaxShift
+ (x'0040000000000000'),
+ (x'007fffffffffffff'),
+ (x'0290000000000000'),
+ (x'029fffffffffffff'),
+ (x'4350000000000000'),
+ (x'435fffffffffffff'),
+ (x'1330000000000000'),
+ (x'133fffffffffffff'),
+ (x'3a6fa7161a4d6e0c')
+)
+select float8send(flt) as ibits,
+ flt,
+ flt::text::float8 as r_flt,
+ float8send(flt::text::float8) as obits,
+ float8send(flt::text::float8) = float8send(flt) as correct
+ from (select bits::bigint::xfloat8::float8 as flt
+ from testdata
+ offset 0) s;
+
+-- clean up, lest opr_sanity complain
+
+\set VERBOSITY terse
+drop type xfloat8 cascade;
+\set VERBOSITY default
+
+--
diff --git a/src/test/regress/sql/point.sql b/src/test/regress/sql/point.sql
index a209f3bfeb..7f8504dbd1 100644
--- a/src/test/regress/sql/point.sql
+++ b/src/test/regress/sql/point.sql
@@ -2,6 +2,9 @@
-- POINT
--
+-- avoid bit-exact output here because operations may not be bit-exact.
+SET extra_float_digits = 0;
+
CREATE TABLE POINT_TBL(f1 point);
INSERT INTO POINT_TBL(f1) VALUES ('(0.0,0.0)');
diff --git a/src/test/regress/sql/updatable_views.sql b/src/test/regress/sql/updatable_views.sql
index dc6d5cbe35..2ecc386238 100644
--- a/src/test/regress/sql/updatable_views.sql
+++ b/src/test/regress/sql/updatable_views.sql
@@ -2,6 +2,9 @@
-- UPDATABLE VIEWS
--
+-- avoid bit-exact output here because operations may not be bit-exact.
+SET extra_float_digits = 0;
+
-- check that non-updatable views and columns are rejected with useful error
-- messages
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index c930eafe89..5251a21d34 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -119,7 +119,7 @@ sub mkvcbuild
}
our @pgcommonallfiles = qw(
- base64.c config_info.c controldata_utils.c exec.c file_perm.c ip.c
+ base64.c config_info.c controldata_utils.c d2s.c exec.c f2s.c file_perm.c ip.c
keywords.c kwlookup.c link-canary.c md5.c
pg_lzcompress.c pgfnames.c psprintf.c relpath.c rmtree.c
saslprep.c scram-common.c string.c unicode_norm.c username.c