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