bigint.k 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. red:{f:0 127@x;,/|1(#/|f,x=64>*:)\(&\f=)_y}
  2. leb80:{`c$|+/1(128*&1,-1+#:)\x}
  3. / unsigned leb8
  4. leb8:{leb80[128\x]}
  5. unleb8:|+/1(128*0>)\0+
  6. / signed leb8
  7. leb8s:{s:x<0;leb80 red[s]((::;neg)s)[128\(1 -1s)*x]}
  8. / unsigned padding
  9. pad:{0^@\:/1(!|/#:')\|:'(!0),/:(x;y)}
  10. / signed padding
  11. pads:{(127 0@64>*p[~i])^(|'p)@\:!s@i:*>s:#'p:(!0),/:(x;y)}
  12. neg:{$[64>*x;add[1;127-x];127-add[-1;x]]}
  13. add0:{,/(::;|x\)@'{(r;c):y;(c;d):(0;x)\+/c,z;(r,d;c)}[x]/[(!0;0);+y]}
  14. / unsigned addition with given base
  15. addb:{(&\~:)_|add0[x]pad[y;z]}
  16. / unsigned addition
  17. /add:{(&\~:)_|add0[128]pad[x;y]}
  18. add:addb[128]
  19. / signed addition
  20. adds:{r:|add0[128]pads[x;y]
  21. $[=/s:~64>*'(x;y)
  22. (((*s)=64>*r)#(0 127@*s)),r:(*s)_r
  23. _/|1(0 0~@[;!2]@)\(64>*r)_r]}
  24. / unsigned multiplication
  25. mul:{{add/(x,0;y)}/@[&1+|/i;i:+/!#'x;add;,/*\:/x:(x;y)]}
  26. / unsigned subtraction using signed addition
  27. sub:{(x;y):,'/|1(#\:/|0,,~64>*:')\(x;y);(&\~:)_adds[x;neg y]}
  28. dm0:{2#(#*|:){(i;p;d):y
  29. $[(~#p)&(~c:-/#'h)&j:*<h:(x[i];*d)
  30. (i;p;(*d;!0),'(0,1)_*|d)
  31. (0>c)|(~c)&~j
  32. (i+1;x[i];d)
  33. (i;(sub[*d;p]),*|d;())]}[y]/(0;!0;(0,#*y)_z)}
  34. divmod:{{$[*<+|1#:'\(*x;*|y);y;(*y;!0),'dm0[128;x;*|y]]}[x]/(!0;y)}
  35. // Faster, but does most math in host K and so has limits.
  36. \d fast
  37. pad:{0^x@\:!|/#:'x:|'(!0),/:(x;y)}
  38. str:,/|1(&~#:)\(&\~:)_
  39. car:{str{(x\z+*y),1_y}[0,x]/[,0;y]}
  40. add:car[128]@+/pad@
  41. mul0:{@[&1+m;(m:|/i)-i:+/!#'x;+;,/*\:/x:(x;y)]}
  42. mul:{car[128]mul0[x;y]}
  43. \d .