Guest User

pi calculator

a guest
Mar 15th, 2014
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.70 KB | None | 0 0
  1. --Made by TurtleHunter
  2.  
  3. --bigInt from https://bitbucket.org/tedu/bigintlua/src/56ec909773a11c9cc910882b56e3b1c66014b687/bigint.lua
  4.  
  5. --
  6. -- Copyright (c) 2010 Ted Unangst <[email protected]>
  7. --
  8. -- Permission to use, copy, modify, and distribute this software for any
  9. -- purpose with or without fee is hereby granted, provided that the above
  10. -- copyright notice and this permission notice appear in all copies.
  11. --
  12. -- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  13. -- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  14. -- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  15. -- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  16. -- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  17. -- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  18. -- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  19. --
  20.  
  21. --
  22. -- Lua version ported/copied from the C version, copyright as follows.
  23. --
  24. -- Copyright (c) 2000 by Jef Poskanzer <[email protected]>.
  25. -- All rights reserved.
  26. --
  27. -- Redistribution and use in source and binary forms, with or without
  28. -- modification, are permitted provided that the following conditions
  29. -- are met:
  30. -- 1. Redistributions of source code must retain the above copyright
  31. -- notice, this list of conditions and the following disclaimer.
  32. -- 2. Redistributions in binary form must reproduce the above copyright
  33. -- notice, this list of conditions and the following disclaimer in the
  34. -- documentation and/or other materials provided with the distribution.
  35. --
  36. -- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  37. -- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  38. -- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  39. -- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  40. -- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  41. -- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  42. -- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43. -- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  44. -- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  45. -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. -- SUCH DAMAGE.
  47. --
  48.  
  49. --
  50. -- Usage is pretty obvious. bigint(n) constructs a bigint. n can be
  51. -- a number or a string. The regular operators are all overridden via
  52. -- metatable, and also generally work with regular numbers too.
  53. -- Note that comparisons between bigints and numbers *don't* work.
  54. -- bigint() uses a small cache, so bigint(constant) should be fast.
  55. --
  56. -- Only the basic operations are here. No gcd, factorial, prime test, ...
  57. --
  58. -- Technical notes:
  59. -- Primary difference from the C version is the obvious 1 indexing, this
  60. -- shows up in a variety of ways and places, along with slightly different
  61. -- handling of pre-allocated comps arrays.
  62. -- I made a brief effort to sync some of the comments, but you're better
  63. -- off just reading the C code.
  64. -- C version homepage: http://www.acme.com/software/bigint/
  65. --
  66.  
  67. -- two functions to help make Lua act more like C
  68. local function fl(x)
  69. if x < 0 then
  70. return math.ceil(x) + 0 -- make -0 go away
  71. else
  72. return math.floor(x)
  73. end
  74. end
  75.  
  76. local function cmod(a, b)
  77. local x = a % b
  78. if a < 0 and x > 0 then
  79. x = x - b
  80. end
  81. return x
  82. end
  83.  
  84.  
  85. local radix = 2^24 -- maybe up to 2^26 is safe?
  86. local radix_sqrt = fl(math.sqrt(radix))
  87.  
  88. local bigintmt -- forward decl
  89.  
  90. local function normalize(bi, notrunc)
  91. local c = bi.comps
  92. local v
  93. -- borrow for negative components
  94. for i = 1, #c - 1 do
  95. v = c[i]
  96. if v < 0 then
  97. c[i+1] = c[i+1] + fl(v / radix) - 1
  98. v = cmod(v, radix)
  99. if v ~= 0 then
  100. c[i] = v + radix
  101. else
  102. c[i] = v
  103. c[i+1] = c[i+1] + 1
  104. end
  105. end
  106. end
  107. -- is top component negative?
  108. if c[#c] < 0 then
  109. -- switch the sign and fix components
  110. bi.sign = -bi.sign
  111. for i = 1, #c - 1 do
  112. v = c[i]
  113. c[i] = radix - v
  114. c[i+1] = c[i+1] + 1
  115. end
  116. c[#c] = -c[#c]
  117. end
  118. -- carry for components larger than radix
  119. for i, v in ipairs(c) do
  120. if v > radix then
  121. c[i+1] = (c[i+1] or 0) + fl(v / radix)
  122. c[i] = cmod(v, radix)
  123. end
  124. end
  125. -- trim off leading zeros
  126. if not notrunc then
  127. for i = #c, 2, -1 do
  128. if c[i] == 0 then
  129. c[i] = nil
  130. else
  131. break
  132. end
  133. end
  134. end
  135. -- check for -0
  136. if #c == 1 and c[1] == 0 and bi.sign == -1 then
  137. bi.sign = 1
  138. end
  139. end
  140.  
  141. local function alloc()
  142. local bi = {}
  143. setmetatable(bi, bigintmt)
  144. bi.comps = {}
  145. bi.sign = 1;
  146. return bi
  147. end
  148.  
  149. local function clone(a)
  150. local bi = alloc()
  151. bi.sign = a.sign
  152. local c = bi.comps
  153. for i,v in ipairs(a.comps) do
  154. c[i] = v
  155. end
  156. return bi
  157. end
  158.  
  159. local function negate(a)
  160. local bi = clone(a)
  161. bi.sign = -bi.sign
  162. return bi
  163. end
  164.  
  165. local function compare(a, b)
  166. local ac, bc = a.comps, b.comps
  167. local as, bs = a.sign, b.sign
  168. if ac == bc then
  169. return 0
  170. elseif as > bs then
  171. return 1
  172. elseif as < bs then
  173. return -1
  174. elseif #ac > #bc then
  175. return as
  176. elseif #ac < #bc then
  177. return -as
  178. end
  179. for i = #ac, 1, -1 do
  180. if ac[i] > bc[i] then
  181. return as
  182. elseif ac[i] < bc[i] then
  183. return -as
  184. end
  185. end
  186. return 0
  187. end
  188.  
  189. local function lt(a, b)
  190. return compare(a, b) < 0
  191. end
  192.  
  193. local function eq(a, b)
  194. return compare(a, b) == 0
  195. end
  196.  
  197. local function le(a, b)
  198. return compare(a, b) <= 0
  199. end
  200.  
  201. local function addint(a, n)
  202. local bi = clone(a)
  203. if bi.sign == 1 then
  204. bi.comps[1] = bi.comps[1] + n
  205. else
  206. bi.comps[1] = bi.comps[1] - n
  207. end
  208. normalize(bi)
  209. return bi
  210. end
  211.  
  212. local function add(a, b)
  213. if type(a) == "number" then
  214. return addint(b, a)
  215. elseif type(b) == "number" then
  216. return addint(a, b)
  217. end
  218. local bi = clone(a)
  219. local sign = bi.sign == b.sign
  220. local c = bi.comps
  221. for i = #c + 1, #b.comps do
  222. c[i] = 0
  223. end
  224. for i, v in ipairs(b.comps) do
  225. if sign then
  226. c[i] = c[i] + v
  227. else
  228. c[i] = c[i] - v
  229. end
  230. end
  231. normalize(bi)
  232. return bi
  233. end
  234.  
  235. local function sub(a, b)
  236. if type(b) == "number" then
  237. return addint(a, -b)
  238. elseif type(a) == "number" then
  239. a = bigint(a)
  240. end
  241. return add(a, negate(b))
  242. end
  243.  
  244. local function mulint(a, b)
  245. local bi = clone(a)
  246. if b < 0 then
  247. b = -b
  248. bi.sign = -bi.sign
  249. end
  250. for i,v in ipairs(bi.comps) do
  251. bi.comps[i] = v * b
  252. end
  253. normalize(bi)
  254. return bi
  255. end
  256.  
  257. local function multiply(a, b)
  258. local bi = alloc()
  259. local c = bi.comps
  260. local ac, bc = a.comps, b.comps
  261. for i = 1, #ac + #bc do
  262. c[i] = 0
  263. end
  264. for i = 1, #ac do
  265. for j = 1, #bc do
  266. c[i+j-1] = c[i+j-1] + ac[i] * bc[j]
  267. end
  268. -- keep the zeroes
  269. normalize(bi, true)
  270. end
  271. normalize(bi)
  272. if bi ~= bigint(0) then
  273. bi.sign = a.sign * b.sign
  274. end
  275. return bi
  276. end
  277.  
  278. local function kmul(a, b)
  279. local ac, bc = a.comps, b.comps
  280. local an, bn = #a.comps, #b.comps
  281. local bi, bj, bk, bl = alloc(), alloc(), alloc(), alloc()
  282. local ic, jc, kc, lc = bi.comps, bj.comps, bk.comps, bl.comps
  283.  
  284. local n = fl((math.max(an, bn) + 1) / 2)
  285. for i = 1, n do
  286. ic[i] = (i + n <= an) and ac[i+n] or 0
  287. jc[i] = (i <= an) and ac[i] or 0
  288. kc[i] = (i + n <= bn) and bc[i+n] or 0
  289. lc[i] = (i <= bn) and bc[i] or 0
  290. end
  291. normalize(bi)
  292. normalize(bj)
  293. normalize(bk)
  294. normalize(bl)
  295. local ik = bi * bk
  296. local jl = bj * bl
  297. local mid = (bi + bj) * (bk + bl) - ik - jl
  298. local mc = mid.comps
  299. local jlc = jl.comps
  300. for i = 1, #mc do
  301. jlc[i+n] = (jlc[i+n] or 0) + mc[i]
  302. end
  303. local ikc = ik.comps
  304. for i = 1, #ikc do
  305. jlc[i+n*2] = (jlc[i+n*2] or 0) + ikc[i]
  306. end
  307. jl.sign = a.sign * b.sign
  308. normalize(jl)
  309. return jl
  310. end
  311.  
  312. local kthresh = 12
  313.  
  314. local function mul(a, b)
  315. if type(a) == "number" then
  316. return mulint(b, a)
  317. elseif type(b) == "number" then
  318. return mulint(a, b)
  319. end
  320. if #a.comps < kthresh or #b.comps < kthresh then
  321. return multiply(a, b)
  322. end
  323. return kmul(a, b)
  324. end
  325.  
  326. local function divint(numer, denom)
  327. local bi = clone(numer)
  328. if denom < 0 then
  329. denom = -denom
  330. bi.sign = -bi.sign
  331. end
  332. local r = 0
  333. local c = bi.comps
  334. for i = #c, 1, -1 do
  335. r = r * radix + c[i]
  336. c[i] = fl(r / denom)
  337. r = cmod(r, denom)
  338. end
  339. normalize(bi)
  340. return bi
  341. end
  342.  
  343. local function multi_divide(numer, denom)
  344. local n = #denom.comps
  345. local approx = divint(numer, denom.comps[n])
  346. for i = n, #approx.comps do
  347. approx.comps[i - n + 1] = approx.comps[i]
  348. end
  349. for i = #approx.comps, #approx.comps - n + 2, -1 do
  350. approx.comps[i] = nil
  351. end
  352. local rem = approx * denom - numer
  353. if rem < denom then
  354. quotient = approx
  355. else
  356. quotient = approx - multi_divide(rem, denom)
  357. end
  358. return quotient
  359. end
  360.  
  361. local function multi_divide_wrap(numer, denom)
  362. -- we use a successive approximation method, but it doesn't work
  363. -- if the high order component is too small. adjust if needed.
  364. if denom.comps[#denom.comps] < radix_sqrt then
  365. numer = mulint(numer, radix_sqrt)
  366. denom = mulint(denom, radix_sqrt)
  367. end
  368. return multi_divide(numer, denom)
  369. end
  370.  
  371. local function div(numer, denom)
  372. if type(denom) == "number" then
  373. if denom == 0 then
  374. error("divide by 0", 2)
  375. end
  376. return divint(numer, denom)
  377. elseif type(numer) == "number" then
  378. numer = bigint(numer)
  379. end
  380. -- check signs and trivial cases
  381. local sign = 1
  382. local cmp = compare(denom, bigint(0))
  383. if cmp == 0 then
  384. error("divide by 0", 2)
  385. elseif cmp == -1 then
  386. sign = -sign
  387. denom = negate(denom)
  388. end
  389. cmp = compare(numer, bigint(0))
  390. if cmp == 0 then
  391. return bigint(0)
  392. elseif cmp == -1 then
  393. sign = -sign
  394. numer = negate(numer)
  395. end
  396. cmp = compare(numer, denom)
  397. if cmp == -1 then
  398. return bigint(0)
  399. elseif cmp == 0 then
  400. return bigint(sign)
  401. end
  402. local bi
  403. -- if small enough, do it the easy way
  404. if #denom.comps == 1 then
  405. bi = divint(numer, denom.comps[1])
  406. else
  407. bi = multi_divide_wrap(numer, denom)
  408. end
  409. if sign == -1 then
  410. bi = negate(bi)
  411. end
  412. return bi
  413. end
  414.  
  415. local function intrem(bi, m)
  416. if m < 0 then
  417. m = -m
  418. end
  419. local rad_r = 1
  420. local r = 0
  421. for i,v in ipairs(bi.comps) do
  422. r = cmod(r + v * rad_r, m)
  423. rad_r = cmod(rad_r * radix, m)
  424. end
  425. if bi.sign < 1 then
  426. r = -r
  427. end
  428. return r
  429. end
  430.  
  431. local function intmod(bi, m)
  432. local r = intrem(bi, m)
  433. if r < 0 then
  434. r = r + m
  435. end
  436. return r
  437. end
  438.  
  439. local function rem(bi, m)
  440. if type(m) == "number" then
  441. return bigint(intrem(bi, m))
  442. elseif type(bi) == "number" then
  443. bi = bigint(bi)
  444. end
  445. return bi - ((bi / m) * bi)
  446. end
  447.  
  448. local function mod(a, m)
  449. local bi = rem(a, m)
  450. if bi.sign == -1 then
  451. bi = bi + m
  452. end
  453. return bi
  454. end
  455.  
  456. local printscale = 10000000
  457. local printscalefmt = string.format("%%.%dd", math.log10(printscale))
  458. local function makestr(bi, s)
  459. if bi >= bigint(printscale) then
  460. makestr(divint(bi, printscale), s)
  461. end
  462. table.insert(s, string.format(printscalefmt, intmod(bi, printscale)))
  463. end
  464.  
  465. local function biginttostring(bi)
  466. local s = {}
  467. if bi < bigint(0) then
  468. bi = negate(bi)
  469. table.insert(s, "-")
  470. end
  471. makestr(bi, s)
  472. s = table.concat(s):gsub("^0*", "")
  473. if s == "" then s = "0" end
  474. return s
  475. end
  476.  
  477. bigintmt = {
  478. __add = add,
  479. __sub = sub,
  480. __mul = mul,
  481. __div = div,
  482. __mod = mod,
  483. __unm = negate,
  484. __eq = eq,
  485. __lt = lt,
  486. __le = le,
  487. __tostring = biginttostring
  488. }
  489.  
  490. local cache = {}
  491. local ncache = 0
  492.  
  493. function bigint(n)
  494. if cache[n] then
  495. return cache[n]
  496. end
  497. local bi
  498. if type(n) == "string" then
  499. local digits = { n:byte(1, -1) }
  500. for i,v in ipairs(digits) do
  501. digits[i] = string.char(v)
  502. end
  503. local start = 1
  504. local sign = 1
  505. if digits[i] == '-' then
  506. sign = -1
  507. start = 2
  508. end
  509. bi = bigint(0)
  510. for i = start, #digits do
  511. bi = addint(mulint(bi, 10), tonumber(digits[i]))
  512. end
  513. bi = mulint(bi, sign)
  514. else
  515. bi = alloc()
  516. bi.comps[1] = n
  517. normalize(bi)
  518. end
  519. if ncache > 100 then
  520. cache = {}
  521. ncache = 0
  522. end
  523. cache[n] = bi
  524. ncache = ncache + 1
  525. return bi
  526. end
  527.  
  528. local yieldTime
  529. local function yield() --http://www.computercraft.info/forums2/index.php?/topic/11245-avoiding-too-long-without-yielding-the-efficient-way modified to sleep(so you can see the result) instead of pulling a event
  530. if yieldTime then
  531. if os.clock() - yieldTime > 2 then
  532. print("Yielding...")
  533. sleep(2)
  534. yieldTime = nil
  535. end
  536. else
  537. yieldTime = os.clock() -- store the time
  538. end
  539. end
  540.  
  541. function pi(precision) --localized :P ported to cclua and bigInt from http://powdertoy.co.uk/Discussions/Thread/View.html?Thread=16546
  542. local pival = bigint(1)
  543. local isNegative = 1
  544. local k = 0
  545. local calc = bigint(3)
  546. while k < precision do
  547. pival = mul(sub(pival, div(bigint(1), calc)), bigint(isNegative))
  548. calc = add(calc, 2)
  549. isNegative = bigint(-isNegative)
  550. k = k+1
  551. if k==precision then
  552. term.clear()
  553. term.setCursorPos(1,1)
  554. print("Finished")
  555. print(biginttostring(mul(pival, bigint(4))))
  556. else
  557. term.clear()
  558. term.setCursorPos(1,1)
  559. print(biginttostring(mul(pival, bigint(4))))
  560. end
  561. yield()
  562. end
  563. end
  564.  
  565. print("Precision(How many times to run): ")
  566. local a = read()
  567. pi(tonumber(a))
Advertisement
Add Comment
Please, Sign In to add comment