basic.odin 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. package big
  2. /*
  3. Copyright 2021 Jeroen van Rijn <[email protected]>.
  4. Made available under Odin's BSD-2 license.
  5. An arbitrary precision mathematics implementation in Odin.
  6. For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3.
  7. The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks.
  8. This file contains basic arithmetic operations like `add`, `sub`, `mul`, `div`, ...
  9. */
  10. import "core:mem"
  11. /*
  12. ===========================
  13. User-level routines
  14. ===========================
  15. */
  16. /*
  17. High-level addition. Handles sign.
  18. */
  19. int_add :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
  20. if dest == nil || a == nil || b == nil { return .Invalid_Pointer; }
  21. if err = clear_if_uninitialized(dest, a, b); err != nil { return err; }
  22. /*
  23. All parameters have been initialized.
  24. */
  25. return #force_inline internal_int_add_signed(dest, a, b, allocator);
  26. }
  27. /*
  28. Adds the unsigned `DIGIT` immediate to an `Int`,
  29. such that the `DIGIT` doesn't have to be turned into an `Int` first.
  30. dest = a + digit;
  31. */
  32. int_add_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context.allocator) -> (err: Error) {
  33. if dest == nil || a == nil { return .Invalid_Pointer; }
  34. if err = clear_if_uninitialized(a); err != nil { return err; }
  35. /*
  36. Grow destination as required.
  37. */
  38. if err = grow(dest, a.used + 1, false, allocator); err != nil { return err; }
  39. /*
  40. All parameters have been initialized.
  41. */
  42. return #force_inline internal_int_add_digit(dest, a, digit);
  43. }
  44. /*
  45. High-level subtraction, dest = number - decrease. Handles signs.
  46. */
  47. int_sub :: proc(dest, number, decrease: ^Int, allocator := context.allocator) -> (err: Error) {
  48. if dest == nil || number == nil || decrease == nil { return .Invalid_Pointer; }
  49. if err = clear_if_uninitialized(dest, number, decrease); err != nil { return err; }
  50. /*
  51. All parameters have been initialized.
  52. */
  53. return #force_inline internal_int_sub_signed(dest, number, decrease, allocator);
  54. }
  55. /*
  56. Adds the unsigned `DIGIT` immediate to an `Int`,
  57. such that the `DIGIT` doesn't have to be turned into an `Int` first.
  58. dest = a - digit;
  59. */
  60. int_sub_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context.allocator) -> (err: Error) {
  61. if dest == nil || a == nil { return .Invalid_Pointer; }
  62. if err = clear_if_uninitialized(a); err != nil { return err; }
  63. /*
  64. Grow destination as required.
  65. */
  66. if err = grow(dest, a.used + 1, false, allocator); err != nil { return err; }
  67. /*
  68. All parameters have been initialized.
  69. */
  70. return #force_inline internal_int_sub_digit(dest, a, digit);
  71. }
  72. /*
  73. dest = src / 2
  74. dest = src >> 1
  75. */
  76. int_halve :: proc(dest, src: ^Int) -> (err: Error) {
  77. if dest == nil || src == nil { return .Invalid_Pointer; }
  78. if err = clear_if_uninitialized(dest, src); err != nil { return err; }
  79. /*
  80. Grow destination as required.
  81. */
  82. if dest != src { if err = grow(dest, src.used + 1); err != nil { return err; } }
  83. return #force_inline internal_int_shr1(dest, src);
  84. }
  85. halve :: proc { int_halve, };
  86. shr1 :: halve;
  87. /*
  88. dest = src * 2
  89. dest = src << 1
  90. */
  91. int_double :: proc(dest, src: ^Int) -> (err: Error) {
  92. if dest == nil || src == nil { return .Invalid_Pointer; }
  93. if err = clear_if_uninitialized(dest, src); err != nil { return err; }
  94. /*
  95. Grow destination as required.
  96. */
  97. if dest != src { if err = grow(dest, src.used + 1); err != nil { return err; } }
  98. return #force_inline internal_int_shl1(dest, src);
  99. }
  100. double :: proc { int_double, };
  101. shl1 :: double;
  102. /*
  103. Multiply by a DIGIT.
  104. */
  105. int_mul_digit :: proc(dest, src: ^Int, multiplier: DIGIT, allocator := context.allocator) -> (err: Error) {
  106. if dest == nil || src == nil { return .Invalid_Pointer; }
  107. if err = clear_if_uninitialized(src, dest); err != nil { return err; }
  108. return #force_inline internal_int_mul_digit(dest, src, multiplier, allocator);
  109. }
  110. /*
  111. High level multiplication (handles sign).
  112. */
  113. int_mul :: proc(dest, src, multiplier: ^Int, allocator := context.allocator) -> (err: Error) {
  114. if dest == nil || src == nil || multiplier == nil { return .Invalid_Pointer; }
  115. if err = clear_if_uninitialized(dest, src, multiplier); err != nil { return err; }
  116. return #force_inline internal_int_mul(dest, src, multiplier, allocator);
  117. }
  118. mul :: proc { int_mul, int_mul_digit, };
  119. sqr :: proc(dest, src: ^Int) -> (err: Error) { return mul(dest, src, src); }
  120. /*
  121. divmod.
  122. Both the quotient and remainder are optional and may be passed a nil.
  123. */
  124. int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int) -> (err: Error) {
  125. /*
  126. Early out if neither of the results is wanted.
  127. */
  128. if quotient == nil && remainder == nil { return nil; }
  129. if err = clear_if_uninitialized(numerator, denominator); err != nil { return err; }
  130. return #force_inline internal_divmod(quotient, remainder, numerator, denominator);
  131. }
  132. int_divmod_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT) -> (remainder: DIGIT, err: Error) {
  133. if quotient == nil { return 0, .Invalid_Pointer; };
  134. if err = clear_if_uninitialized(numerator); err != nil { return 0, err; }
  135. return #force_inline internal_divmod(quotient, numerator, denominator);
  136. }
  137. divmod :: proc{ int_divmod, int_divmod_digit, };
  138. int_div :: proc(quotient, numerator, denominator: ^Int) -> (err: Error) {
  139. if quotient == nil { return .Invalid_Pointer; };
  140. if err = clear_if_uninitialized(numerator, denominator); err != nil { return err; }
  141. return #force_inline internal_divmod(quotient, nil, numerator, denominator);
  142. }
  143. int_div_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT) -> (err: Error) {
  144. if quotient == nil { return .Invalid_Pointer; };
  145. if err = clear_if_uninitialized(numerator); err != nil { return err; }
  146. remainder: DIGIT;
  147. remainder, err = #force_inline internal_divmod(quotient, numerator, denominator);
  148. return err;
  149. }
  150. div :: proc { int_div, int_div_digit, };
  151. /*
  152. remainder = numerator % denominator.
  153. 0 <= remainder < denominator if denominator > 0
  154. denominator < remainder <= 0 if denominator < 0
  155. */
  156. int_mod :: proc(remainder, numerator, denominator: ^Int) -> (err: Error) {
  157. if remainder == nil { return .Invalid_Pointer; };
  158. if err = clear_if_uninitialized(numerator, denominator); err != nil { return err; }
  159. return #force_inline internal_int_mod(remainder, numerator, denominator);
  160. }
  161. int_mod_digit :: proc(numerator: ^Int, denominator: DIGIT) -> (remainder: DIGIT, err: Error) {
  162. return #force_inline internal_divmod(nil, numerator, denominator);
  163. }
  164. mod :: proc { int_mod, int_mod_digit, };
  165. /*
  166. remainder = (number + addend) % modulus.
  167. */
  168. int_addmod :: proc(remainder, number, addend, modulus: ^Int) -> (err: Error) {
  169. if remainder == nil { return .Invalid_Pointer; };
  170. if err = clear_if_uninitialized(number, addend, modulus); err != nil { return err; }
  171. return #force_inline internal_addmod(remainder, number, addend, modulus);
  172. }
  173. addmod :: proc { int_addmod, };
  174. /*
  175. remainder = (number - decrease) % modulus.
  176. */
  177. int_submod :: proc(remainder, number, decrease, modulus: ^Int) -> (err: Error) {
  178. if remainder == nil { return .Invalid_Pointer; };
  179. if err = clear_if_uninitialized(number, decrease, modulus); err != nil { return err; }
  180. return #force_inline internal_submod(remainder, number, decrease, modulus);
  181. }
  182. submod :: proc { int_submod, };
  183. /*
  184. remainder = (number * multiplicand) % modulus.
  185. */
  186. int_mulmod :: proc(remainder, number, multiplicand, modulus: ^Int) -> (err: Error) {
  187. if remainder == nil { return .Invalid_Pointer; };
  188. if err = clear_if_uninitialized(number, multiplicand, modulus); err != nil { return err; }
  189. return #force_inline internal_mulmod(remainder, number, multiplicand, modulus);
  190. }
  191. mulmod :: proc { int_mulmod, };
  192. /*
  193. remainder = (number * number) % modulus.
  194. */
  195. int_sqrmod :: proc(remainder, number, modulus: ^Int) -> (err: Error) {
  196. if remainder == nil { return .Invalid_Pointer; };
  197. if err = clear_if_uninitialized(number, modulus); err != nil { return err; }
  198. return #force_inline internal_sqrmod(remainder, number, modulus);
  199. }
  200. sqrmod :: proc { int_sqrmod, };
  201. int_factorial :: proc(res: ^Int, n: int) -> (err: Error) {
  202. if n < 0 || n > _FACTORIAL_MAX_N { return .Invalid_Argument; }
  203. if res == nil { return .Invalid_Pointer; }
  204. return #force_inline internal_int_factorial(res, n);
  205. }
  206. factorial :: proc { int_factorial, };
  207. /*
  208. Number of ways to choose `k` items from `n` items.
  209. Also known as the binomial coefficient.
  210. TODO: Speed up.
  211. Could be done faster by reusing code from factorial and reusing the common "prefix" results for n!, k! and n-k!
  212. We know that n >= k, otherwise we early out with res = 0.
  213. So:
  214. n-k, keep result
  215. n, start from previous result
  216. k, start from previous result
  217. */
  218. int_choose_digit :: proc(res: ^Int, n, k: int) -> (err: Error) {
  219. if res == nil { return .Invalid_Pointer; }
  220. if n < 0 || n > _FACTORIAL_MAX_N { return .Invalid_Argument; }
  221. if k > n { return zero(res); }
  222. /*
  223. res = n! / (k! * (n - k)!)
  224. */
  225. n_fac, k_fac, n_minus_k_fac := &Int{}, &Int{}, &Int{};
  226. defer destroy(n_fac, k_fac, n_minus_k_fac);
  227. if err = #force_inline internal_int_factorial(n_minus_k_fac, n - k); err != nil { return err; }
  228. if err = #force_inline internal_int_factorial(k_fac, k); err != nil { return err; }
  229. if err = #force_inline internal_mul(k_fac, k_fac, n_minus_k_fac); err != nil { return err; }
  230. if err = #force_inline internal_int_factorial(n_fac, n); err != nil { return err; }
  231. if err = #force_inline internal_div(res, n_fac, k_fac); err != nil { return err; }
  232. return err;
  233. }
  234. choose :: proc { int_choose_digit, };
  235. /*
  236. Function computing both GCD and (if target isn't `nil`) also LCM.
  237. */
  238. int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int) -> (err: Error) {
  239. if res_gcd == nil && res_lcm == nil { return nil; }
  240. if err = clear_if_uninitialized(res_gcd, res_lcm, a, b); err != nil { return err; }
  241. az, _ := is_zero(a); bz, _ := is_zero(b);
  242. if az && bz {
  243. if res_gcd != nil {
  244. if err = zero(res_gcd); err != nil { return err; }
  245. }
  246. if res_lcm != nil {
  247. if err = zero(res_lcm); err != nil { return err; }
  248. }
  249. return nil;
  250. }
  251. else if az {
  252. if res_gcd != nil {
  253. if err = abs(res_gcd, b); err != nil { return err; }
  254. }
  255. if res_lcm != nil {
  256. if err = zero(res_lcm); err != nil { return err; }
  257. }
  258. return nil;
  259. }
  260. else if bz {
  261. if res_gcd != nil {
  262. if err = abs(res_gcd, a); err != nil { return err; }
  263. }
  264. if res_lcm != nil {
  265. if err = zero(res_lcm); err != nil { return err; }
  266. }
  267. return nil;
  268. }
  269. return #force_inline _int_gcd_lcm(res_gcd, res_lcm, a, b);
  270. }
  271. gcd_lcm :: proc { int_gcd_lcm, };
  272. /*
  273. Greatest Common Divisor.
  274. */
  275. int_gcd :: proc(res, a, b: ^Int) -> (err: Error) {
  276. return #force_inline int_gcd_lcm(res, nil, a, b);
  277. }
  278. gcd :: proc { int_gcd, };
  279. /*
  280. Least Common Multiple.
  281. */
  282. int_lcm :: proc(res, a, b: ^Int) -> (err: Error) {
  283. return #force_inline int_gcd_lcm(nil, res, a, b);
  284. }
  285. lcm :: proc { int_lcm, };
  286. /*
  287. Internal function computing both GCD using the binary method,
  288. and, if target isn't `nil`, also LCM.
  289. Expects the arguments to have been initialized.
  290. */
  291. _int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int) -> (err: Error) {
  292. /*
  293. If both `a` and `b` are zero, return zero.
  294. If either `a` or `b`, return the other one.
  295. The `gcd` and `lcm` wrappers have already done this test,
  296. but `gcd_lcm` wouldn't have, so we still need to perform it.
  297. If neither result is wanted, we have nothing to do.
  298. */
  299. if res_gcd == nil && res_lcm == nil { return nil; }
  300. /*
  301. We need a temporary because `res_gcd` is allowed to be `nil`.
  302. */
  303. az, _ := is_zero(a); bz, _ := is_zero(b);
  304. if az && bz {
  305. /*
  306. GCD(0, 0) and LCM(0, 0) are both 0.
  307. */
  308. if res_gcd != nil {
  309. if err = zero(res_gcd); err != nil { return err; }
  310. }
  311. if res_lcm != nil {
  312. if err = zero(res_lcm); err != nil { return err; }
  313. }
  314. return nil;
  315. } else if az {
  316. /*
  317. We can early out with GCD = B and LCM = 0
  318. */
  319. if res_gcd != nil {
  320. if err = abs(res_gcd, b); err != nil { return err; }
  321. }
  322. if res_lcm != nil {
  323. if err = zero(res_lcm); err != nil { return err; }
  324. }
  325. return nil;
  326. } else if bz {
  327. /*
  328. We can early out with GCD = A and LCM = 0
  329. */
  330. if res_gcd != nil {
  331. if err = abs(res_gcd, a); err != nil { return err; }
  332. }
  333. if res_lcm != nil {
  334. if err = zero(res_lcm); err != nil { return err; }
  335. }
  336. return nil;
  337. }
  338. temp_gcd_res := &Int{};
  339. defer destroy(temp_gcd_res);
  340. /*
  341. If neither `a` or `b` was zero, we need to compute `gcd`.
  342. Get copies of `a` and `b` we can modify.
  343. */
  344. u, v := &Int{}, &Int{};
  345. defer destroy(u, v);
  346. if err = copy(u, a); err != nil { return err; }
  347. if err = copy(v, b); err != nil { return err; }
  348. /*
  349. Must be positive for the remainder of the algorithm.
  350. */
  351. u.sign = .Zero_or_Positive; v.sign = .Zero_or_Positive;
  352. /*
  353. B1. Find the common power of two for `u` and `v`.
  354. */
  355. u_lsb, _ := count_lsb(u);
  356. v_lsb, _ := count_lsb(v);
  357. k := min(u_lsb, v_lsb);
  358. if k > 0 {
  359. /*
  360. Divide the power of two out.
  361. */
  362. if err = shr(u, u, k); err != nil { return err; }
  363. if err = shr(v, v, k); err != nil { return err; }
  364. }
  365. /*
  366. Divide any remaining factors of two out.
  367. */
  368. if u_lsb != k {
  369. if err = shr(u, u, u_lsb - k); err != nil { return err; }
  370. }
  371. if v_lsb != k {
  372. if err = shr(v, v, v_lsb - k); err != nil { return err; }
  373. }
  374. for v.used != 0 {
  375. /*
  376. Make sure `v` is the largest.
  377. */
  378. if c, _ := cmp_mag(u, v); c == 1 {
  379. /*
  380. Swap `u` and `v` to make sure `v` is >= `u`.
  381. */
  382. swap(u, v);
  383. }
  384. /*
  385. Subtract smallest from largest.
  386. */
  387. if err = sub(v, v, u); err != nil { return err; }
  388. /*
  389. Divide out all factors of two.
  390. */
  391. b, _ := count_lsb(v);
  392. if err = shr(v, v, b); err != nil { return err; }
  393. }
  394. /*
  395. Multiply by 2**k which we divided out at the beginning.
  396. */
  397. if err = shl(temp_gcd_res, u, k); err != nil { return err; }
  398. temp_gcd_res.sign = .Zero_or_Positive;
  399. /*
  400. We've computed `gcd`, either the long way, or because one of the inputs was zero.
  401. If we don't want `lcm`, we're done.
  402. */
  403. if res_lcm == nil {
  404. swap(temp_gcd_res, res_gcd);
  405. return nil;
  406. }
  407. /*
  408. Computes least common multiple as `|a*b|/gcd(a,b)`
  409. Divide the smallest by the GCD.
  410. */
  411. if c, _ := cmp_mag(a, b); c == -1 {
  412. /*
  413. Store quotient in `t2` such that `t2 * b` is the LCM.
  414. */
  415. if err = div(res_lcm, a, temp_gcd_res); err != nil { return err; }
  416. err = mul(res_lcm, res_lcm, b);
  417. } else {
  418. /*
  419. Store quotient in `t2` such that `t2 * a` is the LCM.
  420. */
  421. if err = div(res_lcm, a, temp_gcd_res); err != nil { return err; }
  422. err = mul(res_lcm, res_lcm, b);
  423. }
  424. if res_gcd != nil {
  425. swap(temp_gcd_res, res_gcd);
  426. }
  427. /*
  428. Fix the sign to positive and return.
  429. */
  430. res_lcm.sign = .Zero_or_Positive;
  431. return err;
  432. }
  433. /*
  434. remainder = numerator % (1 << bits)
  435. */
  436. int_mod_bits :: proc(remainder, numerator: ^Int, bits: int) -> (err: Error) {
  437. if err = clear_if_uninitialized(remainder); err != nil { return err; }
  438. if err = clear_if_uninitialized(numerator); err != nil { return err; }
  439. if bits < 0 { return .Invalid_Argument; }
  440. if bits == 0 { return zero(remainder); }
  441. /*
  442. If the modulus is larger than the value, return the value.
  443. */
  444. err = copy(remainder, numerator);
  445. if bits >= (numerator.used * _DIGIT_BITS) || err != nil {
  446. return;
  447. }
  448. /*
  449. Zero digits above the last digit of the modulus.
  450. */
  451. zero_count := (bits / _DIGIT_BITS);
  452. zero_count += 0 if (bits % _DIGIT_BITS == 0) else 1;
  453. /*
  454. Zero remainder. Special case, can't use `zero_unused`.
  455. */
  456. if zero_count > 0 {
  457. mem.zero_slice(remainder.digit[zero_count:]);
  458. }
  459. /*
  460. Clear the digit that is not completely outside/inside the modulus.
  461. */
  462. remainder.digit[bits / _DIGIT_BITS] &= DIGIT(1 << DIGIT(bits % _DIGIT_BITS)) - DIGIT(1);
  463. return clamp(remainder);
  464. }
  465. mod_bits :: proc { int_mod_bits, };