Skip to content

Instantly share code, notes, and snippets.

@youz
Created May 29, 2022 04:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save youz/a80eb35f72fdfa466d29807deb2ecae0 to your computer and use it in GitHub Desktop.
Save youz/a80eb35f72fdfa466d29807deb2ecae0 to your computer and use it in GitHub Desktop.
Computing the digits of π in SQLite3
-- ref. https://xn--w6q13e505b.jp/program/spigot.html
create table consts as
select 1000 ndigits;
.timer on
with a(i) as (
select ndigits/4*14 from consts
union all select i-1 from a where i>0
),
loop(step, n, i, p, carry, digit, denom, nume, out) as (
select 0
, (select ndigits/4*14 from consts) -- n
, (select ndigits/4*14-1 from consts) -- i
, 0, 0, 0, 0 -- p, carry, digit, denom
, (select json_group_array(2000) from a) -- nume
, '_' -- out
union all select
step + 1
, case when i > 0 then n else n-14 end -- n
, case when i > 0 then i-p else n-15 end -- i
, case when i > 0 then 1-p else 0 end -- p
/* carry */
, case when i > 0 then
case when p = 0 then (carry * i + 10000 * json_extract(nume, '$['||i||']')) else carry / denom end
else carry % 10000
end
/* digit */
, case when i > 0 then digit else carry % 10000 end
/* denom */
, case when i > 0 and p = 0 then 2*i-1 else denom end
/* nume */
, case when i > 0 then
case when p = 1 then json_set(nume, '$['||i||']', carry % denom) else nume end
else nume
end
/* out */
, case when i > 0 then null else printf('%04d', digit + carry / 10000) end
from loop
where n > 0
)
select
replace(group_concat(out, ''), '_3', '3.') pi
from loop
where out is not null;
@youz
Copy link
Author

youz commented May 29, 2022

benchmarks

shell time(sec)
v3.31.1 on WSL 44.328
WASM shell v3.39.0 on Chrome v102 116.029
WASM shell v3.39.0 on Firefox v100 127.253

wasm shell: https://www.sqlite.org/fiddle/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment