mirror of
https://github.com/postgres/postgres.git
synced 2026-06-09 00:53:52 -04:00
452b637d4b
Early returns from the buildfarm say that most critters are good with
commit cbdb8b4c0, but gaur gives unexpected results with the test case
involving a float8 that's one-ULP-less-than-2^63. It appears that that
platform's version of rint() rounds that value up to 2^63 instead of
leaving it be. This is possibly a bug, and it's also possible that no
other platform anybody is using anywhere behaves likewise. Still, the
point of the test is not to insist that everybody's rint() behaves exactly
the same. Let's use two-ULPs-less-than-2^63 instead, which I've tested
to act the same on gaur as on more modern hardware.
(This is, more or less, exactly the portability issue I'd feared might
arise...)
Discussion: https://postgr.es/m/15519-4fc785b483201ff1@postgresql.org
236 lines
6.2 KiB
SQL
236 lines
6.2 KiB
SQL
--
|
|
-- FLOAT8
|
|
--
|
|
|
|
CREATE TABLE FLOAT8_TBL(f1 float8);
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES (' 0.0 ');
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30 ');
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES (' -34.84');
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e+200');
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e-200');
|
|
|
|
-- test for underflow and overflow handling
|
|
SELECT '10e400'::float8;
|
|
SELECT '-10e400'::float8;
|
|
SELECT '10e-400'::float8;
|
|
SELECT '-10e-400'::float8;
|
|
|
|
-- bad input
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('');
|
|
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');
|
|
|
|
-- special inputs
|
|
SELECT 'NaN'::float8;
|
|
SELECT 'nan'::float8;
|
|
SELECT ' NAN '::float8;
|
|
SELECT 'infinity'::float8;
|
|
SELECT ' -INFINiTY '::float8;
|
|
-- bad special inputs
|
|
SELECT 'N A N'::float8;
|
|
SELECT 'NaN x'::float8;
|
|
SELECT ' INFINITY x'::float8;
|
|
|
|
SELECT 'Infinity'::float8 + 100.0;
|
|
SELECT 'Infinity'::float8 / 'Infinity'::float8;
|
|
SELECT 'nan'::float8 / 'nan'::float8;
|
|
SELECT 'nan'::numeric::float8;
|
|
|
|
SELECT '' AS five, * FROM FLOAT8_TBL;
|
|
|
|
SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE f.f1 <> '1004.3';
|
|
|
|
SELECT '' AS one, f.* FROM FLOAT8_TBL f WHERE f.f1 = '1004.3';
|
|
|
|
SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE '1004.3' > f.f1;
|
|
|
|
SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE f.f1 < '1004.3';
|
|
|
|
SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE '1004.3' >= f.f1;
|
|
|
|
SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE f.f1 <= '1004.3';
|
|
|
|
SELECT '' AS three, f.f1, f.f1 * '-10' AS x
|
|
FROM FLOAT8_TBL f
|
|
WHERE f.f1 > '0.0';
|
|
|
|
SELECT '' AS three, f.f1, f.f1 + '-10' AS x
|
|
FROM FLOAT8_TBL f
|
|
WHERE f.f1 > '0.0';
|
|
|
|
SELECT '' AS three, f.f1, f.f1 / '-10' AS x
|
|
FROM FLOAT8_TBL f
|
|
WHERE f.f1 > '0.0';
|
|
|
|
SELECT '' AS three, f.f1, f.f1 - '-10' AS x
|
|
FROM FLOAT8_TBL f
|
|
WHERE f.f1 > '0.0';
|
|
|
|
SELECT '' AS one, f.f1 ^ '2.0' AS square_f1
|
|
FROM FLOAT8_TBL f where f.f1 = '1004.3';
|
|
|
|
-- absolute value
|
|
SELECT '' AS five, f.f1, @f.f1 AS abs_f1
|
|
FROM FLOAT8_TBL f;
|
|
|
|
-- truncate
|
|
SELECT '' AS five, f.f1, trunc(f.f1) AS trunc_f1
|
|
FROM FLOAT8_TBL f;
|
|
|
|
-- round
|
|
SELECT '' AS five, f.f1, round(f.f1) AS round_f1
|
|
FROM FLOAT8_TBL f;
|
|
|
|
-- ceil / ceiling
|
|
select ceil(f1) as ceil_f1 from float8_tbl f;
|
|
select ceiling(f1) as ceiling_f1 from float8_tbl f;
|
|
|
|
-- floor
|
|
select floor(f1) as floor_f1 from float8_tbl f;
|
|
|
|
-- sign
|
|
select sign(f1) as sign_f1 from float8_tbl f;
|
|
|
|
-- square root
|
|
SELECT sqrt(float8 '64') AS eight;
|
|
|
|
SELECT |/ float8 '64' AS eight;
|
|
|
|
SELECT '' AS three, f.f1, |/f.f1 AS sqrt_f1
|
|
FROM FLOAT8_TBL f
|
|
WHERE f.f1 > '0.0';
|
|
|
|
-- power
|
|
SELECT power(float8 '144', float8 '0.5');
|
|
SELECT power(float8 'NaN', float8 '0.5');
|
|
SELECT power(float8 '144', float8 'NaN');
|
|
SELECT power(float8 'NaN', float8 'NaN');
|
|
SELECT power(float8 '-1', float8 'NaN');
|
|
SELECT power(float8 '1', float8 'NaN');
|
|
SELECT power(float8 'NaN', float8 '0');
|
|
|
|
-- take exp of ln(f.f1)
|
|
SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1
|
|
FROM FLOAT8_TBL f
|
|
WHERE f.f1 > '0.0';
|
|
|
|
-- cube root
|
|
SELECT ||/ float8 '27' AS three;
|
|
|
|
SELECT '' AS five, f.f1, ||/f.f1 AS cbrt_f1 FROM FLOAT8_TBL f;
|
|
|
|
|
|
SELECT '' AS five, * FROM FLOAT8_TBL;
|
|
|
|
UPDATE FLOAT8_TBL
|
|
SET f1 = FLOAT8_TBL.f1 * '-1'
|
|
WHERE FLOAT8_TBL.f1 > '0.0';
|
|
|
|
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
|
|
|
|
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
|
|
|
|
SELECT 0 ^ 0 + 0 ^ 1 + 0 ^ 0.0 + 0 ^ 0.5;
|
|
|
|
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
|
|
|
|
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
|
|
|
|
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
|
|
|
|
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
|
|
|
|
SELECT '' AS five, * FROM FLOAT8_TBL;
|
|
|
|
-- test for over- and underflow
|
|
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');
|
|
|
|
-- maintain external table consistency across platforms
|
|
-- delete all values and reinsert well-behaved ones
|
|
|
|
DELETE FROM FLOAT8_TBL;
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('0.0');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('-34.84');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('-1004.30');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('-1.2345678901234e+200');
|
|
|
|
INSERT INTO FLOAT8_TBL(f1) VALUES ('-1.2345678901234e-200');
|
|
|
|
SELECT '' AS five, * FROM FLOAT8_TBL;
|
|
|
|
-- 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;
|
|
SELECT '9223372036854773760'::float8::int8;
|
|
SELECT '9223372036854775807'::float8::int8;
|
|
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),
|
|
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);
|
|
|
|
SELECT x,
|
|
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);
|
|
|
|
SELECT x,
|
|
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
|
|
FROM (VALUES (-1), (-0.5), (0), (0.5), (1)) AS t(x);
|
|
|
|
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);
|
|
|
|
SELECT x, y,
|
|
atan2d(y, x),
|
|
atan2d(y, x) IN (-90,0,90,180) AS atan2d_exact
|
|
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;
|