2000-01-04 17:21:02 +01:00
|
|
|
--
|
|
|
|
-- FLOAT8
|
|
|
|
--
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2022-02-08 21:30:38 +01:00
|
|
|
--
|
|
|
|
-- Build a table for testing
|
|
|
|
-- (This temporarily hides the table created in test_setup.sql)
|
|
|
|
--
|
|
|
|
|
|
|
|
CREATE TEMP TABLE FLOAT8_TBL(f1 float8);
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2004-03-11 03:11:14 +01:00
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES (' 0.0 ');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30 ');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES (' -34.84');
|
1997-04-05 13:26:55 +02:00
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e+200');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e-200');
|
|
|
|
|
2004-03-24 03:02:27 +01:00
|
|
|
-- test for underflow and overflow handling
|
|
|
|
SELECT '10e400'::float8;
|
|
|
|
SELECT '-10e400'::float8;
|
|
|
|
SELECT '10e-400'::float8;
|
|
|
|
SELECT '-10e-400'::float8;
|
2004-03-11 03:11:14 +01:00
|
|
|
|
Change floating-point output format for improved performance.
Previously, floating-point output was done by rounding to a specific
decimal precision; by default, to 6 or 15 decimal digits (losing
information) or as requested using extra_float_digits. Drivers that
wanted exact float values, and applications like pg_dump that must
preserve values exactly, set extra_float_digits=3 (or sometimes 2 for
historical reasons, though this isn't enough for float4).
Unfortunately, decimal rounded output is slow enough to become a
noticable bottleneck when dealing with large result sets or COPY of
large tables when many floating-point values are involved.
Floating-point output can be done much faster when the output is not
rounded to a specific decimal length, but rather is chosen as the
shortest decimal representation that is closer to the original float
value than to any other value representable in the same precision. The
recently published Ryu algorithm by Ulf Adams is both relatively
simple and remarkably fast.
Accordingly, change float4out/float8out to output shortest decimal
representations if extra_float_digits is greater than 0, and make that
the new default. Applications that need rounded output can set
extra_float_digits back to 0 or below, and take the resulting
performance hit.
We make one concession to portability for systems with buggy
floating-point input: we do not output decimal values that fall
exactly halfway between adjacent representable binary values (which
would rely on the reader doing round-to-nearest-even correctly). This
is known to be a problem at least for VS2013 on Windows.
Our version of the Ryu code originates from
https://github.com/ulfjack/ryu/ at commit c9c3fb1979, but with the
following (significant) modifications:
- Output format is changed to use fixed-point notation for small
exponents, as printf would, and also to use lowercase 'e', a
minimum of 2 exponent digits, and a mandatory sign on the exponent,
to keep the formatting as close as possible to previous output.
- The output of exact midpoint values is disabled as noted above.
- The integer fast-path code is changed somewhat (since we have
fixed-point output and the upstream did not).
- Our project style has been largely applied to the code with the
exception of C99 declaration-after-statement, which has been
retained as an exception to our present policy.
- Most of upstream's debugging and conditionals are removed, and we
use our own configure tests to determine things like uint128
availability.
Changing the float output format obviously affects a number of
regression tests. This patch uses an explicit setting of
extra_float_digits=0 for test output that is not expected to be
exactly reproducible (e.g. due to numerical instability or differing
algorithms for transcendental functions).
Conversions from floats to numeric are unchanged by this patch. These
may appear in index expressions and it is not yet clear whether any
change should be made, so that can be left for another day.
This patch assumes that the only supported floating point format is
now IEEE format, and the documentation is updated to reflect that.
Code by me, adapting the work of Ulf Adams and other contributors.
References:
https://dl.acm.org/citation.cfm?id=3192369
Reviewed-by: Tom Lane, Andres Freund, Donald Dong
Discussion: https://postgr.es/m/87r2el1bx6.fsf@news-spur.riddles.org.uk
2019-02-13 16:20:33 +01:00
|
|
|
-- test smallest normalized input
|
|
|
|
SELECT float8send('2.2250738585072014E-308'::float8);
|
|
|
|
|
2004-03-11 03:11:14 +01:00
|
|
|
-- bad input
|
2005-02-11 05:09:05 +01:00
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('');
|
2004-03-11 03:11:14 +01:00
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5');
|
|
|
|
|
Convert a few datatype input functions to use "soft" error reporting.
This patch converts the input functions for bool, int2, int4, int8,
float4, float8, numeric, and contrib/cube to the new soft-error style.
array_in and record_in are also converted. There's lots more to do,
but this is enough to provide proof-of-concept that the soft-error
API is usable, as well as reference examples for how to convert
input functions.
This patch is mostly by me, but it owes very substantial debt to
earlier work by Nikita Glukhov, Andrew Dunstan, and Amul Sul.
Thanks to Andres Freund for review.
Discussion: https://postgr.es/m/3bbbb0df-7382-bf87-9737-340ba096e034@postgrespro.ru
2022-12-09 16:14:53 +01:00
|
|
|
-- Also try it with non-error-throwing API
|
|
|
|
SELECT pg_input_is_valid('34.5', 'float8');
|
|
|
|
SELECT pg_input_is_valid('xyz', 'float8');
|
|
|
|
SELECT pg_input_is_valid('1e4000', 'float8');
|
2023-02-28 00:04:13 +01:00
|
|
|
SELECT * FROM pg_input_error_info('1e4000', 'float8');
|
Convert a few datatype input functions to use "soft" error reporting.
This patch converts the input functions for bool, int2, int4, int8,
float4, float8, numeric, and contrib/cube to the new soft-error style.
array_in and record_in are also converted. There's lots more to do,
but this is enough to provide proof-of-concept that the soft-error
API is usable, as well as reference examples for how to convert
input functions.
This patch is mostly by me, but it owes very substantial debt to
earlier work by Nikita Glukhov, Andrew Dunstan, and Amul Sul.
Thanks to Andres Freund for review.
Discussion: https://postgr.es/m/3bbbb0df-7382-bf87-9737-340ba096e034@postgrespro.ru
2022-12-09 16:14:53 +01:00
|
|
|
|
2004-03-11 03:11:14 +01:00
|
|
|
-- special inputs
|
|
|
|
SELECT 'NaN'::float8;
|
|
|
|
SELECT 'nan'::float8;
|
|
|
|
SELECT ' NAN '::float8;
|
2004-03-12 01:25:43 +01:00
|
|
|
SELECT 'infinity'::float8;
|
|
|
|
SELECT ' -INFINiTY '::float8;
|
2004-03-11 03:11:14 +01:00
|
|
|
-- bad special inputs
|
|
|
|
SELECT 'N A N'::float8;
|
2004-03-12 01:25:43 +01:00
|
|
|
SELECT 'NaN x'::float8;
|
|
|
|
SELECT ' INFINITY x'::float8;
|
|
|
|
|
|
|
|
SELECT 'Infinity'::float8 + 100.0;
|
|
|
|
SELECT 'Infinity'::float8 / 'Infinity'::float8;
|
2020-11-05 00:11:15 +01:00
|
|
|
SELECT '42'::float8 / 'Infinity'::float8;
|
2004-03-12 01:25:43 +01:00
|
|
|
SELECT 'nan'::float8 / 'nan'::float8;
|
2020-07-21 01:44:41 +02:00
|
|
|
SELECT 'nan'::float8 / '0'::float8;
|
2010-02-27 22:53:21 +01:00
|
|
|
SELECT 'nan'::numeric::float8;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT * FROM FLOAT8_TBL;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 <> '1004.3';
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 = '1004.3';
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.* FROM FLOAT8_TBL f WHERE '1004.3' > f.f1;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 < '1004.3';
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.* FROM FLOAT8_TBL f WHERE '1004.3' >= f.f1;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 <= '1004.3';
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1, f.f1 * '-10' AS x
|
1997-04-05 13:26:55 +02:00
|
|
|
FROM FLOAT8_TBL f
|
|
|
|
WHERE f.f1 > '0.0';
|
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1, f.f1 + '-10' AS x
|
1997-04-05 13:26:55 +02:00
|
|
|
FROM FLOAT8_TBL f
|
|
|
|
WHERE f.f1 > '0.0';
|
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1, f.f1 / '-10' AS x
|
1997-04-05 13:26:55 +02:00
|
|
|
FROM FLOAT8_TBL f
|
|
|
|
WHERE f.f1 > '0.0';
|
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1, f.f1 - '-10' AS x
|
1997-04-05 13:26:55 +02:00
|
|
|
FROM FLOAT8_TBL f
|
|
|
|
WHERE f.f1 > '0.0';
|
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1 ^ '2.0' AS square_f1
|
1997-04-05 13:26:55 +02:00
|
|
|
FROM FLOAT8_TBL f where f.f1 = '1004.3';
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- absolute value
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1, @f.f1 AS abs_f1
|
1997-04-05 13:26:55 +02:00
|
|
|
FROM FLOAT8_TBL f;
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- truncate
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1, trunc(f.f1) AS trunc_f1
|
1997-04-05 13:26:55 +02:00
|
|
|
FROM FLOAT8_TBL f;
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- round
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1, round(f.f1) AS round_f1
|
1997-04-05 13:26:55 +02:00
|
|
|
FROM FLOAT8_TBL f;
|
|
|
|
|
2004-04-23 22:32:20 +02:00
|
|
|
-- ceil / ceiling
|
2002-10-19 04:08:19 +02:00
|
|
|
select ceil(f1) as ceil_f1 from float8_tbl f;
|
2004-04-23 22:32:20 +02:00
|
|
|
select ceiling(f1) as ceiling_f1 from float8_tbl f;
|
2002-10-19 04:08:19 +02:00
|
|
|
|
|
|
|
-- floor
|
|
|
|
select floor(f1) as floor_f1 from float8_tbl f;
|
|
|
|
|
|
|
|
-- sign
|
|
|
|
select sign(f1) as sign_f1 from float8_tbl f;
|
2000-03-15 00:06:59 +01:00
|
|
|
|
Change floating-point output format for improved performance.
Previously, floating-point output was done by rounding to a specific
decimal precision; by default, to 6 or 15 decimal digits (losing
information) or as requested using extra_float_digits. Drivers that
wanted exact float values, and applications like pg_dump that must
preserve values exactly, set extra_float_digits=3 (or sometimes 2 for
historical reasons, though this isn't enough for float4).
Unfortunately, decimal rounded output is slow enough to become a
noticable bottleneck when dealing with large result sets or COPY of
large tables when many floating-point values are involved.
Floating-point output can be done much faster when the output is not
rounded to a specific decimal length, but rather is chosen as the
shortest decimal representation that is closer to the original float
value than to any other value representable in the same precision. The
recently published Ryu algorithm by Ulf Adams is both relatively
simple and remarkably fast.
Accordingly, change float4out/float8out to output shortest decimal
representations if extra_float_digits is greater than 0, and make that
the new default. Applications that need rounded output can set
extra_float_digits back to 0 or below, and take the resulting
performance hit.
We make one concession to portability for systems with buggy
floating-point input: we do not output decimal values that fall
exactly halfway between adjacent representable binary values (which
would rely on the reader doing round-to-nearest-even correctly). This
is known to be a problem at least for VS2013 on Windows.
Our version of the Ryu code originates from
https://github.com/ulfjack/ryu/ at commit c9c3fb1979, but with the
following (significant) modifications:
- Output format is changed to use fixed-point notation for small
exponents, as printf would, and also to use lowercase 'e', a
minimum of 2 exponent digits, and a mandatory sign on the exponent,
to keep the formatting as close as possible to previous output.
- The output of exact midpoint values is disabled as noted above.
- The integer fast-path code is changed somewhat (since we have
fixed-point output and the upstream did not).
- Our project style has been largely applied to the code with the
exception of C99 declaration-after-statement, which has been
retained as an exception to our present policy.
- Most of upstream's debugging and conditionals are removed, and we
use our own configure tests to determine things like uint128
availability.
Changing the float output format obviously affects a number of
regression tests. This patch uses an explicit setting of
extra_float_digits=0 for test output that is not expected to be
exactly reproducible (e.g. due to numerical instability or differing
algorithms for transcendental functions).
Conversions from floats to numeric are unchanged by this patch. These
may appear in index expressions and it is not yet clear whether any
change should be made, so that can be left for another day.
This patch assumes that the only supported floating point format is
now IEEE format, and the documentation is updated to reflect that.
Code by me, adapting the work of Ulf Adams and other contributors.
References:
https://dl.acm.org/citation.cfm?id=3192369
Reviewed-by: Tom Lane, Andres Freund, Donald Dong
Discussion: https://postgr.es/m/87r2el1bx6.fsf@news-spur.riddles.org.uk
2019-02-13 16:20:33 +01:00
|
|
|
-- avoid bit-exact output here because operations may not be bit-exact.
|
|
|
|
SET extra_float_digits = 0;
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- square root
|
2002-10-19 04:08:19 +02:00
|
|
|
SELECT sqrt(float8 '64') AS eight;
|
|
|
|
|
2000-03-15 00:06:59 +01:00
|
|
|
SELECT |/ float8 '64' AS eight;
|
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1, |/f.f1 AS sqrt_f1
|
1997-04-05 13:26:55 +02:00
|
|
|
FROM FLOAT8_TBL f
|
|
|
|
WHERE f.f1 > '0.0';
|
|
|
|
|
2004-04-23 22:32:20 +02:00
|
|
|
-- power
|
|
|
|
SELECT power(float8 '144', float8 '0.5');
|
2018-04-29 21:21:44 +02:00
|
|
|
SELECT power(float8 'NaN', float8 '0.5');
|
|
|
|
SELECT power(float8 '144', float8 'NaN');
|
|
|
|
SELECT power(float8 'NaN', float8 'NaN');
|
2018-04-30 00:15:16 +02:00
|
|
|
SELECT power(float8 '-1', float8 'NaN');
|
2018-04-29 21:21:44 +02:00
|
|
|
SELECT power(float8 '1', float8 'NaN');
|
|
|
|
SELECT power(float8 'NaN', float8 '0');
|
2020-06-14 17:00:07 +02:00
|
|
|
SELECT power(float8 'inf', float8 '0');
|
|
|
|
SELECT power(float8 '-inf', float8 '0');
|
|
|
|
SELECT power(float8 '0', float8 'inf');
|
|
|
|
SELECT power(float8 '0', float8 '-inf');
|
|
|
|
SELECT power(float8 '1', float8 'inf');
|
|
|
|
SELECT power(float8 '1', float8 '-inf');
|
|
|
|
SELECT power(float8 '-1', float8 'inf');
|
|
|
|
SELECT power(float8 '-1', float8 '-inf');
|
|
|
|
SELECT power(float8 '0.1', float8 'inf');
|
|
|
|
SELECT power(float8 '-0.1', float8 'inf');
|
|
|
|
SELECT power(float8 '1.1', float8 'inf');
|
|
|
|
SELECT power(float8 '-1.1', float8 'inf');
|
|
|
|
SELECT power(float8 '0.1', float8 '-inf');
|
|
|
|
SELECT power(float8 '-0.1', float8 '-inf');
|
|
|
|
SELECT power(float8 '1.1', float8 '-inf');
|
|
|
|
SELECT power(float8 '-1.1', float8 '-inf');
|
|
|
|
SELECT power(float8 'inf', float8 '-2');
|
|
|
|
SELECT power(float8 'inf', float8 '2');
|
|
|
|
SELECT power(float8 'inf', float8 'inf');
|
|
|
|
SELECT power(float8 'inf', float8 '-inf');
|
2020-06-16 21:28:37 +02:00
|
|
|
-- Intel's icc misoptimizes the code that controls the sign of this result,
|
|
|
|
-- even with -mp1. Pending a fix for that, only test for "is it zero".
|
|
|
|
SELECT power(float8 '-inf', float8 '-2') = '0';
|
2020-06-14 17:00:07 +02:00
|
|
|
SELECT power(float8 '-inf', float8 '-3');
|
|
|
|
SELECT power(float8 '-inf', float8 '2');
|
|
|
|
SELECT power(float8 '-inf', float8 '3');
|
2020-06-15 18:15:56 +02:00
|
|
|
SELECT power(float8 '-inf', float8 '3.5');
|
2020-06-14 17:00:07 +02:00
|
|
|
SELECT power(float8 '-inf', float8 'inf');
|
|
|
|
SELECT power(float8 '-inf', float8 '-inf');
|
2004-04-23 22:32:20 +02:00
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- take exp of ln(f.f1)
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1, exp(ln(f.f1)) AS exp_ln_f1
|
1997-04-05 13:26:55 +02:00
|
|
|
FROM FLOAT8_TBL f
|
|
|
|
WHERE f.f1 > '0.0';
|
|
|
|
|
2020-06-14 17:00:07 +02:00
|
|
|
-- check edge cases for exp
|
|
|
|
SELECT exp('inf'::float8), exp('-inf'::float8), exp('nan'::float8);
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- cube root
|
2000-03-15 00:06:59 +01:00
|
|
|
SELECT ||/ float8 '27' AS three;
|
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1, ||/f.f1 AS cbrt_f1 FROM FLOAT8_TBL f;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT * FROM FLOAT8_TBL;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
|
|
|
UPDATE FLOAT8_TBL
|
|
|
|
SET f1 = FLOAT8_TBL.f1 * '-1'
|
|
|
|
WHERE FLOAT8_TBL.f1 > '0.0';
|
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1 * '1e200' from FLOAT8_TBL f;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1 ^ '1e200' from FLOAT8_TBL f;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2008-05-09 00:17:54 +02:00
|
|
|
SELECT 0 ^ 0 + 0 ^ 1 + 0 ^ 0.0 + 0 ^ 0.5;
|
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT exp(f.f1) from FLOAT8_TBL f;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT f.f1 / '0.0' from FLOAT8_TBL f;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT * FROM FLOAT8_TBL;
|
1997-04-05 13:26:55 +02:00
|
|
|
|
Rethink how to test the hyperbolic functions.
The initial commit tried to test them on trivial cases such as 0,
reasoning that we shouldn't hit any portability issues that way.
The buildfarm immediately proved that hope ill-founded, and anyway
it's not a great testing scheme because it doesn't prove that we're
even calling the right library function for each SQL function.
Instead, let's test them at inputs such as 1 (or something within
the valid range, as needed), so that each function should produce
a different output.
As committed, this is just about certain to show portability
failures, because it's very unlikely that every platform computes
these functions the same as mine down to the last bit. However,
I want to put it through a buildfarm cycle this way, so that
we can see how big the variations are. The plan is to add
"set extra_float_digits = -1", or whatever we need in order to
hide the variations; but first we need data.
Discussion: https://postgr.es/m/E1h3nUY-0000sM-Vf@gemulon.postgresql.org
2019-03-13 23:13:38 +01:00
|
|
|
-- hyperbolic functions
|
2019-03-14 02:05:33 +01:00
|
|
|
-- we run these with extra_float_digits = 0 too, since different platforms
|
|
|
|
-- tend to produce results that vary in the last place.
|
Rethink how to test the hyperbolic functions.
The initial commit tried to test them on trivial cases such as 0,
reasoning that we shouldn't hit any portability issues that way.
The buildfarm immediately proved that hope ill-founded, and anyway
it's not a great testing scheme because it doesn't prove that we're
even calling the right library function for each SQL function.
Instead, let's test them at inputs such as 1 (or something within
the valid range, as needed), so that each function should produce
a different output.
As committed, this is just about certain to show portability
failures, because it's very unlikely that every platform computes
these functions the same as mine down to the last bit. However,
I want to put it through a buildfarm cycle this way, so that
we can see how big the variations are. The plan is to add
"set extra_float_digits = -1", or whatever we need in order to
hide the variations; but first we need data.
Discussion: https://postgr.es/m/E1h3nUY-0000sM-Vf@gemulon.postgresql.org
2019-03-13 23:13:38 +01:00
|
|
|
SELECT sinh(float8 '1');
|
|
|
|
SELECT cosh(float8 '1');
|
|
|
|
SELECT tanh(float8 '1');
|
|
|
|
SELECT asinh(float8 '1');
|
|
|
|
SELECT acosh(float8 '2');
|
|
|
|
SELECT atanh(float8 '0.5');
|
2019-03-14 02:05:33 +01:00
|
|
|
-- test Inf/NaN cases for hyperbolic functions
|
|
|
|
SELECT sinh(float8 'infinity');
|
|
|
|
SELECT sinh(float8 '-infinity');
|
|
|
|
SELECT sinh(float8 'nan');
|
|
|
|
SELECT cosh(float8 'infinity');
|
|
|
|
SELECT cosh(float8 '-infinity');
|
|
|
|
SELECT cosh(float8 'nan');
|
|
|
|
SELECT tanh(float8 'infinity');
|
|
|
|
SELECT tanh(float8 '-infinity');
|
|
|
|
SELECT tanh(float8 'nan');
|
|
|
|
SELECT asinh(float8 'infinity');
|
|
|
|
SELECT asinh(float8 '-infinity');
|
|
|
|
SELECT asinh(float8 'nan');
|
2019-03-16 20:50:13 +01:00
|
|
|
-- acosh(Inf) should be Inf, but some mingw versions produce NaN, so skip test
|
|
|
|
-- SELECT acosh(float8 'infinity');
|
2019-03-14 02:05:33 +01:00
|
|
|
SELECT acosh(float8 '-infinity');
|
|
|
|
SELECT acosh(float8 'nan');
|
|
|
|
SELECT atanh(float8 'infinity');
|
|
|
|
SELECT atanh(float8 '-infinity');
|
|
|
|
SELECT atanh(float8 'nan');
|
|
|
|
|
2023-03-14 10:17:36 +01:00
|
|
|
-- error functions
|
|
|
|
-- we run these with extra_float_digits = -1, to get consistently rounded
|
|
|
|
-- results on all platforms.
|
|
|
|
SET extra_float_digits = -1;
|
|
|
|
SELECT x,
|
|
|
|
erf(x),
|
|
|
|
erfc(x)
|
|
|
|
FROM (VALUES (float8 '-infinity'),
|
|
|
|
(-28), (-6), (-3.4), (-2.1), (-1.1), (-0.45),
|
|
|
|
(-1.2e-9), (-2.3e-13), (-1.2e-17), (0),
|
|
|
|
(1.2e-17), (2.3e-13), (1.2e-9),
|
|
|
|
(0.45), (1.1), (2.1), (3.4), (6), (28),
|
|
|
|
(float8 'infinity'), (float8 'nan')) AS t(x);
|
|
|
|
|
2019-03-14 02:05:33 +01:00
|
|
|
RESET extra_float_digits;
|
Rethink how to test the hyperbolic functions.
The initial commit tried to test them on trivial cases such as 0,
reasoning that we shouldn't hit any portability issues that way.
The buildfarm immediately proved that hope ill-founded, and anyway
it's not a great testing scheme because it doesn't prove that we're
even calling the right library function for each SQL function.
Instead, let's test them at inputs such as 1 (or something within
the valid range, as needed), so that each function should produce
a different output.
As committed, this is just about certain to show portability
failures, because it's very unlikely that every platform computes
these functions the same as mine down to the last bit. However,
I want to put it through a buildfarm cycle this way, so that
we can see how big the variations are. The plan is to add
"set extra_float_digits = -1", or whatever we need in order to
hide the variations; but first we need data.
Discussion: https://postgr.es/m/E1h3nUY-0000sM-Vf@gemulon.postgresql.org
2019-03-13 23:13:38 +01:00
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- test for over- and underflow
|
1998-09-22 18:52:59 +02:00
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
|
|
|
|
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
|
|
|
|
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400');
|
|
|
|
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400');
|
|
|
|
|
2022-02-08 21:30:38 +01:00
|
|
|
DROP TABLE FLOAT8_TBL;
|
1998-09-22 18:52:59 +02:00
|
|
|
|
2022-02-08 21:30:38 +01:00
|
|
|
-- Check the float8 values exported for use by other tests
|
1998-09-22 18:52:59 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT * FROM FLOAT8_TBL;
|
2016-01-22 21:46:22 +01:00
|
|
|
|
2018-11-24 02:57:11 +01:00
|
|
|
-- test edge-case coercions to integer
|
|
|
|
SELECT '32767.4'::float8::int2;
|
|
|
|
SELECT '32767.6'::float8::int2;
|
|
|
|
SELECT '-32768.4'::float8::int2;
|
|
|
|
SELECT '-32768.6'::float8::int2;
|
|
|
|
SELECT '2147483647.4'::float8::int4;
|
|
|
|
SELECT '2147483647.6'::float8::int4;
|
|
|
|
SELECT '-2147483648.4'::float8::int4;
|
|
|
|
SELECT '-2147483648.6'::float8::int4;
|
2018-11-24 05:49:25 +01:00
|
|
|
SELECT '9223372036854773760'::float8::int8;
|
2018-11-24 02:57:11 +01:00
|
|
|
SELECT '9223372036854775807'::float8::int8;
|
|
|
|
SELECT '-9223372036854775808.5'::float8::int8;
|
|
|
|
SELECT '-9223372036854780000'::float8::int8;
|
|
|
|
|
2016-01-22 21:46:22 +01:00
|
|
|
-- test exact cases for trigonometric functions in degrees
|
2016-04-19 22:47:21 +02:00
|
|
|
|
|
|
|
SELECT x,
|
|
|
|
sind(x),
|
|
|
|
sind(x) IN (-1,-0.5,0,0.5,1) AS sind_exact
|
|
|
|
FROM (VALUES (0), (30), (90), (150), (180),
|
|
|
|
(210), (270), (330), (360)) AS t(x);
|
|
|
|
|
2016-01-22 21:46:22 +01:00
|
|
|
SELECT x,
|
2016-04-19 22:47:21 +02:00
|
|
|
cosd(x),
|
|
|
|
cosd(x) IN (-1,-0.5,0,0.5,1) AS cosd_exact
|
|
|
|
FROM (VALUES (0), (60), (90), (120), (180),
|
|
|
|
(240), (270), (300), (360)) AS t(x);
|
2016-01-22 21:46:22 +01:00
|
|
|
|
|
|
|
SELECT x,
|
2016-04-19 22:47:21 +02:00
|
|
|
tand(x),
|
|
|
|
tand(x) IN ('-Infinity'::float8,-1,0,
|
|
|
|
1,'Infinity'::float8) AS tand_exact,
|
|
|
|
cotd(x),
|
|
|
|
cotd(x) IN ('-Infinity'::float8,-1,0,
|
|
|
|
1,'Infinity'::float8) AS cotd_exact
|
|
|
|
FROM (VALUES (0), (45), (90), (135), (180),
|
|
|
|
(225), (270), (315), (360)) AS t(x);
|
|
|
|
|
|
|
|
SELECT x,
|
|
|
|
asind(x),
|
|
|
|
asind(x) IN (-90,-30,0,30,90) AS asind_exact,
|
|
|
|
acosd(x),
|
|
|
|
acosd(x) IN (0,60,90,120,180) AS acosd_exact
|
2016-01-22 21:46:22 +01:00
|
|
|
FROM (VALUES (-1), (-0.5), (0), (0.5), (1)) AS t(x);
|
|
|
|
|
2016-04-19 22:47:21 +02:00
|
|
|
SELECT x,
|
|
|
|
atand(x),
|
|
|
|
atand(x) IN (-90,-45,0,45,90) AS atand_exact
|
|
|
|
FROM (VALUES ('-Infinity'::float8), (-1), (0), (1),
|
|
|
|
('Infinity'::float8)) AS t(x);
|
2016-01-22 21:46:22 +01:00
|
|
|
|
|
|
|
SELECT x, y,
|
2016-04-19 22:47:21 +02:00
|
|
|
atan2d(y, x),
|
|
|
|
atan2d(y, x) IN (-90,0,90,180) AS atan2d_exact
|
2016-01-22 21:46:22 +01:00
|
|
|
FROM (SELECT 10*cosd(a), 10*sind(a)
|
|
|
|
FROM generate_series(0, 360, 90) AS t(a)) AS t(x,y);
|
2016-04-19 22:47:21 +02:00
|
|
|
|
Change floating-point output format for improved performance.
Previously, floating-point output was done by rounding to a specific
decimal precision; by default, to 6 or 15 decimal digits (losing
information) or as requested using extra_float_digits. Drivers that
wanted exact float values, and applications like pg_dump that must
preserve values exactly, set extra_float_digits=3 (or sometimes 2 for
historical reasons, though this isn't enough for float4).
Unfortunately, decimal rounded output is slow enough to become a
noticable bottleneck when dealing with large result sets or COPY of
large tables when many floating-point values are involved.
Floating-point output can be done much faster when the output is not
rounded to a specific decimal length, but rather is chosen as the
shortest decimal representation that is closer to the original float
value than to any other value representable in the same precision. The
recently published Ryu algorithm by Ulf Adams is both relatively
simple and remarkably fast.
Accordingly, change float4out/float8out to output shortest decimal
representations if extra_float_digits is greater than 0, and make that
the new default. Applications that need rounded output can set
extra_float_digits back to 0 or below, and take the resulting
performance hit.
We make one concession to portability for systems with buggy
floating-point input: we do not output decimal values that fall
exactly halfway between adjacent representable binary values (which
would rely on the reader doing round-to-nearest-even correctly). This
is known to be a problem at least for VS2013 on Windows.
Our version of the Ryu code originates from
https://github.com/ulfjack/ryu/ at commit c9c3fb1979, but with the
following (significant) modifications:
- Output format is changed to use fixed-point notation for small
exponents, as printf would, and also to use lowercase 'e', a
minimum of 2 exponent digits, and a mandatory sign on the exponent,
to keep the formatting as close as possible to previous output.
- The output of exact midpoint values is disabled as noted above.
- The integer fast-path code is changed somewhat (since we have
fixed-point output and the upstream did not).
- Our project style has been largely applied to the code with the
exception of C99 declaration-after-statement, which has been
retained as an exception to our present policy.
- Most of upstream's debugging and conditionals are removed, and we
use our own configure tests to determine things like uint128
availability.
Changing the float output format obviously affects a number of
regression tests. This patch uses an explicit setting of
extra_float_digits=0 for test output that is not expected to be
exactly reproducible (e.g. due to numerical instability or differing
algorithms for transcendental functions).
Conversions from floats to numeric are unchanged by this patch. These
may appear in index expressions and it is not yet clear whether any
change should be made, so that can be left for another day.
This patch assumes that the only supported floating point format is
now IEEE format, and the documentation is updated to reflect that.
Code by me, adapting the work of Ulf Adams and other contributors.
References:
https://dl.acm.org/citation.cfm?id=3192369
Reviewed-by: Tom Lane, Andres Freund, Donald Dong
Discussion: https://postgr.es/m/87r2el1bx6.fsf@news-spur.riddles.org.uk
2019-02-13 16:20:33 +01:00
|
|
|
--
|
|
|
|
-- 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
|
|
|
|
drop type xfloat8 cascade;
|