1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
--
\set VERBOSITY terse
-- test numerics
create function lua_numexec(code text, n1 numeric, n2 numeric)
returns text
language pllua
as $$
local f,e = load("return function(n1,n2) return "..code.." end", code, "t", self)
assert(f,e)
f = f()
assert(f)
return tostring(f(n1,n2))
end
do
num = require "pllua.numeric"
$$;
create function pg_numexec(code text, n1 numeric, n2 numeric)
returns text
language plpgsql
as $$
declare
r text;
begin
execute format('select (%s)::text',
regexp_replace(regexp_replace(code, '\mnum\.', '', 'g'),
'\mn([0-9])', '$\1', 'g'))
into r using n1,n2;
return r;
end;
$$;
with
t as (select code,
lua_numexec(code, 5439.123456, -1.9) as lua,
pg_numexec(code, 5439.123456, -1.9) as pg
from unnest(array[
$$ n1 + n2 $$, $$ n1 - n2 $$,
$$ n1 * n2 $$, $$ n1 / n2 $$,
$$ n1 % n2 $$, $$ n1 ^ n2 $$,
$$ (-n1) + n2 $$, $$ (-n1) - n2 $$,
$$ (-n1) * n2 $$, $$ (-n1) / n2 $$,
$$ (-n1) % n2 $$, $$ (-n1) ^ 3 $$,
$$ (-n1) + (-n2) $$, $$ (-n1) - (-n2) $$,
$$ (-n1) * (-n2) $$, $$ (-n1) / (-n2) $$,
$$ (-n1) % (-n2) $$, $$ (-n1) ^ (-3) $$,
$$ (n1) > (n2) $$, $$ (n1) < (n2) $$,
$$ (n1) >= (n2) $$, $$ (n1) <= (n2) $$,
$$ (n1) > (n2*10000) $$,
$$ (n1) < (n2*10000) $$,
$$ (n1) >= (n2 * -10000) $$,
$$ (n1) <= (n2 * -10000) $$,
$$ num.round(n1) $$, $$ num.round(n2) $$,
$$ num.round(n1,4) $$, $$ num.round(n1,-1) $$,
$$ num.trunc(n1) $$, $$ num.trunc(n2) $$,
$$ num.trunc(n1,4) $$, $$ num.trunc(n1,-1) $$,
$$ num.floor(n1) $$, $$ num.floor(n2) $$,
$$ num.ceil(n1) $$, $$ num.ceil(n2) $$,
$$ num.abs(n1) $$, $$ num.abs(n2) $$,
$$ num.sign(n1) $$, $$ num.sign(n2) $$,
$$ num.sqrt(n1) $$,
$$ num.exp(12.3) $$,
$$ num.exp(n2) $$
]) as u(code))
select (lua = pg) as ok, * from t;
-- calculate pi to 40 places
do language pllua $$
-- Chudnovsky formula; ~14 digits per round, we use 4 rounds
local num = require 'pllua.numeric'
local prec = 100 -- precision of intermediate values
local function fact(n)
local r = pgtype.numeric(1):round(prec)
for i = 2,n do r = r * i end
return r:round(prec)
end
local c640320 = pgtype.numeric(640320):round(prec)
local c13591409 = pgtype.numeric(13591409):round(prec)
local c545140134 = pgtype.numeric(545140134):round(prec)
local function chn(k)
return (fact(6*k) * (c13591409 + (c545140134 * k)))
/ (fact(3*k) * fact(k)^3 * (-c640320)^(3*k))
end
local function pi()
return (1 / ((chn(0) + chn(1) + chn(2) + chn(3))*12 / num.sqrt(c640320^3))):round(40)
end
print(pi())
$$;
-- check sanity of maxinteger/mininteger
do language pllua $$
local num = require 'pllua.numeric'
local maxi = num.maxinteger
local mini = num.mininteger
print(type(num.tointeger(maxi)), type(num.tointeger(maxi+1)))
print(type(num.tointeger(mini)), type(num.tointeger(mini-1)))
$$
--end
|