helpers.odin 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. /*
  2. Copyright 2021 Jeroen van Rijn <[email protected]>.
  3. Made available under Odin's BSD-3 license.
  4. */
  5. package math_big
  6. import "base:intrinsics"
  7. import rnd "core:math/rand"
  8. /*
  9. TODO: Int.flags and Constants like ONE, NAN, etc, are not yet properly handled everywhere.
  10. */
  11. /*
  12. Deallocates the backing memory of one or more `Int`s.
  13. */
  14. int_destroy :: proc(integers: ..^Int) {
  15. integers := integers
  16. for a in integers {
  17. assert_if_nil(a)
  18. }
  19. #force_inline internal_int_destroy(..integers)
  20. }
  21. /*
  22. Helpers to set an `Int` to a specific value.
  23. */
  24. int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, allocator := context.allocator) -> (err: Error)
  25. where intrinsics.type_is_integer(T) {
  26. context.allocator = allocator
  27. src := src
  28. /*
  29. Check that `src` is usable and `dest` isn't immutable.
  30. */
  31. assert_if_nil(dest)
  32. #force_inline internal_error_if_immutable(dest) or_return
  33. return #force_inline internal_int_set_from_integer(dest, src, minimize)
  34. }
  35. set :: proc {
  36. int_set_from_integer,
  37. int_copy,
  38. int_atoi,
  39. rat_set_f64,
  40. rat_set_f32,
  41. rat_set_f16,
  42. rat_set_u64,
  43. rat_set_i64,
  44. rat_set_int,
  45. rat_set_digit,
  46. rat_set_rat,
  47. }
  48. /*
  49. Copy one `Int` to another.
  50. */
  51. int_copy :: proc(dest, src: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
  52. /*
  53. If dest == src, do nothing
  54. */
  55. if (dest == src) { return nil }
  56. /*
  57. Check that `src` is usable and `dest` isn't immutable.
  58. */
  59. assert_if_nil(dest, src)
  60. context.allocator = allocator
  61. #force_inline internal_clear_if_uninitialized(src) or_return
  62. #force_inline internal_error_if_immutable(dest) or_return
  63. return #force_inline internal_int_copy(dest, src, minimize)
  64. }
  65. copy :: proc {
  66. int_copy,
  67. rat_copy,
  68. }
  69. /*
  70. In normal code, you can also write `a, b = b, a`.
  71. However, that only swaps within the current scope.
  72. This helper swaps completely.
  73. */
  74. int_swap :: proc(a, b: ^Int) {
  75. assert_if_nil(a, b)
  76. #force_inline internal_swap(a, b)
  77. }
  78. swap :: proc { int_swap, rat_swap }
  79. /*
  80. Set `dest` to |`src`|.
  81. */
  82. int_abs :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
  83. /*
  84. Check that `src` is usable and `dest` isn't immutable.
  85. */
  86. assert_if_nil(dest, src)
  87. context.allocator = allocator
  88. #force_inline internal_clear_if_uninitialized(src) or_return
  89. #force_inline internal_error_if_immutable(dest) or_return
  90. return #force_inline internal_int_abs(dest, src)
  91. }
  92. platform_abs :: proc(n: $T) -> T where intrinsics.type_is_integer(T) {
  93. return n if n >= 0 else -n
  94. }
  95. abs :: proc{ int_abs, platform_abs, rat_abs }
  96. /*
  97. Set `dest` to `-src`.
  98. */
  99. int_neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
  100. /*
  101. Check that `src` is usable and `dest` isn't immutable.
  102. */
  103. assert_if_nil(dest, src)
  104. context.allocator = allocator
  105. #force_inline internal_clear_if_uninitialized(src) or_return
  106. #force_inline internal_error_if_immutable(dest) or_return
  107. return #force_inline internal_int_neg(dest, src)
  108. }
  109. neg :: proc { int_neg, rat_neg }
  110. /*
  111. Helpers to extract values from the `Int`.
  112. */
  113. int_bitfield_extract_single :: proc(a: ^Int, offset: int, allocator := context.allocator) -> (bit: _WORD, err: Error) {
  114. return #force_inline int_bitfield_extract(a, offset, 1, allocator)
  115. }
  116. int_bitfield_extract :: proc(a: ^Int, offset, count: int, allocator := context.allocator) -> (res: _WORD, err: Error) {
  117. /*
  118. Check that `a` is usable.
  119. */
  120. assert_if_nil(a)
  121. context.allocator = allocator
  122. #force_inline internal_clear_if_uninitialized(a) or_return
  123. return #force_inline internal_int_bitfield_extract(a, offset, count)
  124. }
  125. /*
  126. Resize backing store.
  127. */
  128. shrink :: proc(a: ^Int, allocator := context.allocator) -> (err: Error) {
  129. /*
  130. Check that `a` is usable.
  131. */
  132. assert_if_nil(a)
  133. context.allocator = allocator
  134. #force_inline internal_clear_if_uninitialized(a) or_return
  135. return #force_inline internal_shrink(a)
  136. }
  137. int_grow :: proc(a: ^Int, digits: int, allow_shrink := false, allocator := context.allocator) -> (err: Error) {
  138. /*
  139. Check that `a` is usable.
  140. */
  141. assert_if_nil(a)
  142. return #force_inline internal_int_grow(a, digits, allow_shrink, allocator)
  143. }
  144. grow :: proc { int_grow, }
  145. /*
  146. Clear `Int` and resize it to the default size.
  147. */
  148. int_clear :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
  149. /*
  150. Check that `a` is usable.
  151. */
  152. assert_if_nil(a)
  153. return #force_inline internal_int_clear(a, minimize, allocator)
  154. }
  155. clear :: proc { int_clear, }
  156. zero :: clear
  157. /*
  158. Set the `Int` to 1 and optionally shrink it to the minimum backing size.
  159. */
  160. int_one :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
  161. /*
  162. Check that `a` is usable.
  163. */
  164. assert_if_nil(a)
  165. return #force_inline internal_one(a, minimize, allocator)
  166. }
  167. one :: proc { int_one, }
  168. /*
  169. Set the `Int` to -1 and optionally shrink it to the minimum backing size.
  170. */
  171. int_minus_one :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
  172. /*
  173. Check that `a` is usable.
  174. */
  175. assert_if_nil(a)
  176. return #force_inline internal_minus_one(a, minimize, allocator)
  177. }
  178. minus_one :: proc { int_minus_one, }
  179. /*
  180. Set the `Int` to Inf and optionally shrink it to the minimum backing size.
  181. */
  182. int_inf :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
  183. /*
  184. Check that `a` is usable.
  185. */
  186. assert_if_nil(a)
  187. return #force_inline internal_inf(a, minimize, allocator)
  188. }
  189. inf :: proc { int_inf, }
  190. /*
  191. Set the `Int` to -Inf and optionally shrink it to the minimum backing size.
  192. */
  193. int_minus_inf :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
  194. /*
  195. Check that `a` is usable.
  196. */
  197. assert_if_nil(a)
  198. return #force_inline internal_minus_inf(a, minimize, allocator)
  199. }
  200. minus_inf :: proc { int_inf, }
  201. /*
  202. Set the `Int` to NaN and optionally shrink it to the minimum backing size.
  203. */
  204. int_nan :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
  205. /*
  206. Check that `a` is usable.
  207. */
  208. assert_if_nil(a)
  209. return #force_inline internal_nan(a, minimize, allocator)
  210. }
  211. nan :: proc { int_nan, }
  212. power_of_two :: proc(a: ^Int, power: int, allocator := context.allocator) -> (err: Error) {
  213. /*
  214. Check that `a` is usable.
  215. */
  216. assert_if_nil(a)
  217. return #force_inline internal_int_power_of_two(a, power, allocator)
  218. }
  219. int_get_u128 :: proc(a: ^Int, allocator := context.allocator) -> (res: u128, err: Error) {
  220. /*
  221. Check that `a` is usable.
  222. */
  223. assert_if_nil(a)
  224. return int_get(a, u128, allocator)
  225. }
  226. get_u128 :: proc { int_get_u128, }
  227. int_get_i128 :: proc(a: ^Int, allocator := context.allocator) -> (res: i128, err: Error) {
  228. /*
  229. Check that `a` is usable.
  230. */
  231. assert_if_nil(a)
  232. return int_get(a, i128, allocator)
  233. }
  234. get_i128 :: proc { int_get_i128, }
  235. int_get_u64 :: proc(a: ^Int, allocator := context.allocator) -> (res: u64, err: Error) {
  236. /*
  237. Check that `a` is usable.
  238. */
  239. assert_if_nil(a)
  240. return int_get(a, u64, allocator)
  241. }
  242. get_u64 :: proc { int_get_u64, }
  243. int_get_i64 :: proc(a: ^Int, allocator := context.allocator) -> (res: i64, err: Error) {
  244. /*
  245. Check that `a` is usable.
  246. */
  247. assert_if_nil(a)
  248. return int_get(a, i64, allocator)
  249. }
  250. get_i64 :: proc { int_get_i64, }
  251. int_get_u32 :: proc(a: ^Int, allocator := context.allocator) -> (res: u32, err: Error) {
  252. /*
  253. Check that `a` is usable.
  254. */
  255. assert_if_nil(a)
  256. return int_get(a, u32, allocator)
  257. }
  258. get_u32 :: proc { int_get_u32, }
  259. int_get_i32 :: proc(a: ^Int, allocator := context.allocator) -> (res: i32, err: Error) {
  260. /*
  261. Check that `a` is usable.
  262. */
  263. assert_if_nil(a)
  264. return int_get(a, i32, allocator)
  265. }
  266. get_i32 :: proc { int_get_i32, }
  267. /*
  268. TODO: Think about using `count_bits` to check if the value could be returned completely,
  269. and maybe return max(T), .Integer_Overflow if not?
  270. */
  271. int_get :: proc(a: ^Int, $T: typeid, allocator := context.allocator) -> (res: T, err: Error) where intrinsics.type_is_integer(T) {
  272. /*
  273. Check that `a` is usable.
  274. */
  275. assert_if_nil(a)
  276. #force_inline internal_clear_if_uninitialized(a, allocator) or_return
  277. return #force_inline internal_int_get(a, T)
  278. }
  279. get :: proc { int_get, }
  280. int_get_float :: proc(a: ^Int, allocator := context.allocator) -> (res: f64, err: Error) {
  281. /*
  282. Check that `a` is usable.
  283. */
  284. assert_if_nil(a)
  285. #force_inline internal_clear_if_uninitialized(a, allocator) or_return
  286. return #force_inline internal_int_get_float(a)
  287. }
  288. /*
  289. Count bits in an `Int`.
  290. */
  291. count_bits :: proc(a: ^Int, allocator := context.allocator) -> (count: int, err: Error) {
  292. /*
  293. Check that `a` is usable.
  294. */
  295. assert_if_nil(a)
  296. #force_inline internal_clear_if_uninitialized(a, allocator) or_return
  297. return #force_inline internal_count_bits(a), nil
  298. }
  299. /*
  300. Returns the number of trailing zeroes before the first one.
  301. Differs from regular `ctz` in that 0 returns 0.
  302. */
  303. int_count_lsb :: proc(a: ^Int, allocator := context.allocator) -> (count: int, err: Error) {
  304. /*
  305. Check that `a` is usable.
  306. */
  307. assert_if_nil(a)
  308. #force_inline internal_clear_if_uninitialized(a, allocator) or_return
  309. return #force_inline internal_int_count_lsb(a)
  310. }
  311. platform_count_lsb :: #force_inline proc(a: $T) -> (count: int)
  312. where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T) {
  313. return int(intrinsics.count_trailing_zeros(a)) if a > 0 else 0
  314. }
  315. count_lsb :: proc { int_count_lsb, platform_count_lsb, }
  316. int_random_digit :: proc() -> (res: DIGIT) {
  317. when _DIGIT_BITS == 60 { // DIGIT = u64
  318. return DIGIT(rnd.uint64()) & _MASK
  319. } else when _DIGIT_BITS == 28 { // DIGIT = u32
  320. return DIGIT(rnd.uint32()) & _MASK
  321. } else {
  322. panic("Unsupported DIGIT size.")
  323. }
  324. return 0 // We shouldn't get here.
  325. }
  326. int_random :: proc(dest: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {
  327. /*
  328. Check that `a` is usable.
  329. */
  330. assert_if_nil(dest)
  331. return #force_inline internal_int_random(dest, bits, allocator)
  332. }
  333. random :: proc { int_random, }
  334. /*
  335. Internal helpers.
  336. */
  337. assert_initialized :: proc(a: ^Int, loc := #caller_location) {
  338. assert_if_nil(a)
  339. assert(is_initialized(a), "`Int` was not properly initialized.", loc)
  340. }
  341. zero_unused :: proc(dest: ^Int, old_used := -1) {
  342. assert_if_nil(dest)
  343. if ! #force_inline is_initialized(dest) { return }
  344. #force_inline internal_zero_unused(dest, old_used)
  345. }
  346. clear_if_uninitialized_single :: proc(arg: ^Int, allocator := context.allocator) -> (err: Error) {
  347. assert_if_nil(arg)
  348. return #force_inline internal_clear_if_uninitialized_single(arg, allocator)
  349. }
  350. clear_if_uninitialized_multi :: proc(args: ..^Int, allocator := context.allocator) -> (err: Error) {
  351. args := args
  352. assert_if_nil(..args)
  353. for i in args {
  354. #force_inline internal_clear_if_uninitialized_single(i, allocator) or_return
  355. }
  356. return err
  357. }
  358. clear_if_uninitialized :: proc {clear_if_uninitialized_single, clear_if_uninitialized_multi, }
  359. error_if_immutable_single :: proc(arg: ^Int) -> (err: Error) {
  360. if arg != nil && .Immutable in arg.flags { return .Assignment_To_Immutable }
  361. return nil
  362. }
  363. error_if_immutable_multi :: proc(args: ..^Int) -> (err: Error) {
  364. for i in args {
  365. if i != nil && .Immutable in i.flags { return .Assignment_To_Immutable }
  366. }
  367. return nil
  368. }
  369. error_if_immutable :: proc {error_if_immutable_single, error_if_immutable_multi, }
  370. /*
  371. Allocates several `Int`s at once.
  372. */
  373. int_init_multi :: proc(integers: ..^Int, allocator := context.allocator) -> (err: Error) {
  374. assert_if_nil(..integers)
  375. integers := integers
  376. for a in integers {
  377. #force_inline internal_clear(a, true, allocator) or_return
  378. }
  379. return nil
  380. }
  381. init_multi :: proc { int_init_multi, }
  382. copy_digits :: proc(dest, src: ^Int, digits: int, offset := int(0), allocator := context.allocator) -> (err: Error) {
  383. context.allocator = allocator
  384. /*
  385. Check that `src` is usable and `dest` isn't immutable.
  386. */
  387. assert_if_nil(dest, src)
  388. #force_inline internal_clear_if_uninitialized(src) or_return
  389. return #force_inline internal_copy_digits(dest, src, digits, offset)
  390. }
  391. /*
  392. Trim unused digits.
  393. This is used to ensure that leading zero digits are trimmed and the leading "used" digit will be non-zero.
  394. Typically very fast. Also fixes the sign if there are no more leading digits.
  395. */
  396. clamp :: proc(a: ^Int, allocator := context.allocator) -> (err: Error) {
  397. assert_if_nil(a)
  398. #force_inline internal_clear_if_uninitialized(a, allocator) or_return
  399. for a.used > 0 && a.digit[a.used - 1] == 0 {
  400. a.used -= 1
  401. }
  402. if z, _ := is_zero(a); z {
  403. a.sign = .Zero_or_Positive
  404. }
  405. return nil
  406. }
  407. /*
  408. Size binary representation
  409. */
  410. int_to_bytes_size :: proc(a: ^Int, signed := false, allocator := context.allocator) -> (size_in_bytes: int, err: Error) {
  411. assert_if_nil(a)
  412. #force_inline internal_clear_if_uninitialized(a, allocator) or_return
  413. size_in_bits := internal_count_bits(a)
  414. size_in_bytes = (size_in_bits / 8)
  415. size_in_bytes += 0 if size_in_bits % 8 == 0 else 1
  416. size_in_bytes += 1 if signed else 0
  417. return
  418. }
  419. /*
  420. Return Little Endian binary representation of `a`, either signed or unsigned.
  421. If `a` is negative and we ask for the default unsigned representation, we return abs(a).
  422. */
  423. int_to_bytes_little :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
  424. assert_if_nil(a)
  425. size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return
  426. l := len(buf)
  427. if size_in_bytes > l { return .Buffer_Overflow }
  428. size_in_bits := internal_count_bits(a)
  429. i := 0
  430. if signed {
  431. buf[l - 1] = 1 if a.sign == .Negative else 0
  432. }
  433. #no_bounds_check for offset := 0; offset < size_in_bits; offset += 8 {
  434. bits, _ := internal_int_bitfield_extract(a, offset, 8)
  435. buf[i] = u8(bits & 255); i += 1
  436. }
  437. return
  438. }
  439. /*
  440. Return Big Endian binary representation of `a`, either signed or unsigned.
  441. If `a` is negative and we ask for the default unsigned representation, we return abs(a).
  442. */
  443. int_to_bytes_big :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
  444. assert_if_nil(a)
  445. size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return
  446. l := len(buf)
  447. if size_in_bytes > l { return .Buffer_Overflow }
  448. size_in_bits := internal_count_bits(a)
  449. i := l - 1
  450. if signed {
  451. buf[0] = 1 if a.sign == .Negative else 0
  452. }
  453. #no_bounds_check for offset := 0; offset < size_in_bits; offset += 8 {
  454. bits, _ := internal_int_bitfield_extract(a, offset, 8)
  455. buf[i] = u8(bits & 255); i -= 1
  456. }
  457. return
  458. }
  459. /*
  460. Return Python 3.x compatible Little Endian binary representation of `a`, either signed or unsigned.
  461. If `a` is negative when asking for an unsigned number, we return an error like Python does.
  462. */
  463. int_to_bytes_little_python :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
  464. assert_if_nil(a)
  465. if !signed && a.sign == .Negative { return .Invalid_Argument }
  466. l := len(buf)
  467. size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return
  468. if size_in_bytes > l { return .Buffer_Overflow }
  469. if a.sign == .Negative {
  470. t := &Int{}
  471. defer destroy(t)
  472. internal_complement(t, a, allocator) or_return
  473. size_in_bits := internal_count_bits(t)
  474. i := 0
  475. #no_bounds_check for offset := 0; offset < size_in_bits; offset += 8 {
  476. bits, _ := internal_int_bitfield_extract(t, offset, 8)
  477. buf[i] = 255 - u8(bits & 255); i += 1
  478. }
  479. buf[l-1] = 255
  480. } else {
  481. size_in_bits := internal_count_bits(a)
  482. i := 0
  483. #no_bounds_check for offset := 0; offset < size_in_bits; offset += 8 {
  484. bits, _ := internal_int_bitfield_extract(a, offset, 8)
  485. buf[i] = u8(bits & 255); i += 1
  486. }
  487. }
  488. return
  489. }
  490. /*
  491. Return Python 3.x compatible Big Endian binary representation of `a`, either signed or unsigned.
  492. If `a` is negative when asking for an unsigned number, we return an error like Python does.
  493. */
  494. int_to_bytes_big_python :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
  495. assert_if_nil(a)
  496. if !signed && a.sign == .Negative { return .Invalid_Argument }
  497. if a.sign == .Zero_or_Positive { return int_to_bytes_big(a, buf, signed, allocator) }
  498. l := len(buf)
  499. size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return
  500. if size_in_bytes > l { return .Buffer_Overflow }
  501. t := &Int{}
  502. defer destroy(t)
  503. internal_complement(t, a, allocator) or_return
  504. size_in_bits := internal_count_bits(t)
  505. i := l - 1
  506. #no_bounds_check for offset := 0; offset < size_in_bits; offset += 8 {
  507. bits, _ := internal_int_bitfield_extract(t, offset, 8)
  508. buf[i] = 255 - u8(bits & 255); i -= 1
  509. }
  510. buf[0] = 255
  511. return
  512. }
  513. /*
  514. Read `Int` from a Big Endian binary representation.
  515. Sign is detected from the first byte if `signed` is true.
  516. */
  517. int_from_bytes_big :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
  518. assert_if_nil(a)
  519. buf := buf
  520. l := len(buf)
  521. if l == 0 { return .Invalid_Argument }
  522. sign: Sign
  523. size_in_bits := l * 8
  524. if signed {
  525. /*
  526. First byte denotes the sign.
  527. */
  528. size_in_bits -= 8
  529. }
  530. size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS
  531. size_in_digits += 0 if size_in_bits % 8 == 0 else 1
  532. internal_zero(a, false, allocator) or_return
  533. internal_grow(a, size_in_digits, false, allocator) or_return
  534. if signed {
  535. sign = .Zero_or_Positive if buf[0] == 0 else .Negative
  536. buf = buf[1:]
  537. }
  538. #no_bounds_check for v in buf {
  539. internal_shl(a, a, 8) or_return
  540. a.digit[0] |= DIGIT(v)
  541. }
  542. a.sign = sign
  543. a.used = size_in_digits
  544. return internal_clamp(a)
  545. }
  546. /*
  547. Read `Int` from a Big Endian Python binary representation.
  548. Sign is detected from the first byte if `signed` is true.
  549. */
  550. int_from_bytes_big_python :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
  551. assert_if_nil(a)
  552. buf := buf
  553. l := len(buf)
  554. if l == 0 { return .Invalid_Argument }
  555. sign: Sign
  556. size_in_bits := l * 8
  557. if signed {
  558. /*
  559. First byte denotes the sign.
  560. */
  561. size_in_bits -= 8
  562. }
  563. size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS
  564. size_in_digits += 0 if size_in_bits % 8 == 0 else 1
  565. internal_zero(a, false, allocator) or_return
  566. internal_grow(a, size_in_digits, false, allocator) or_return
  567. if signed {
  568. sign = .Zero_or_Positive if buf[0] == 0 else .Negative
  569. buf = buf[1:]
  570. }
  571. #no_bounds_check for v in buf {
  572. internal_shl(a, a, 8) or_return
  573. if signed && sign == .Negative {
  574. a.digit[0] |= DIGIT(255 - v)
  575. } else {
  576. a.digit[0] |= DIGIT(v)
  577. }
  578. }
  579. a.sign = sign
  580. a.used = size_in_digits
  581. internal_clamp(a) or_return
  582. if signed && sign == .Negative {
  583. return internal_sub(a, a, 1)
  584. }
  585. return nil
  586. }
  587. /*
  588. Read `Int` from a Little Endian binary representation.
  589. Sign is detected from the last byte if `signed` is true.
  590. */
  591. int_from_bytes_little :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
  592. assert_if_nil(a)
  593. buf := buf
  594. l := len(buf)
  595. if l == 0 { return .Invalid_Argument }
  596. sign: Sign
  597. size_in_bits := l * 8
  598. if signed {
  599. /*
  600. First byte denotes the sign.
  601. */
  602. size_in_bits -= 8
  603. }
  604. size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS
  605. size_in_digits += 0 if size_in_bits % 8 == 0 else 1
  606. internal_zero(a, false, allocator) or_return
  607. internal_grow(a, size_in_digits, false, allocator) or_return
  608. if signed {
  609. sign = .Zero_or_Positive if buf[l-1] == 0 else .Negative
  610. buf = buf[:l-1]
  611. l -= 1
  612. }
  613. for _, i in buf {
  614. internal_shl(a, a, 8) or_return
  615. a.digit[0] |= DIGIT(buf[l-i-1])
  616. }
  617. a.sign = sign
  618. a.used = size_in_digits
  619. return internal_clamp(a)
  620. }
  621. /*
  622. Read `Int` from a Little Endian Python binary representation.
  623. Sign is detected from the first byte if `signed` is true.
  624. */
  625. int_from_bytes_little_python :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
  626. assert_if_nil(a)
  627. buf := buf
  628. l := len(buf)
  629. if l == 0 { return .Invalid_Argument }
  630. sign: Sign
  631. size_in_bits := l * 8
  632. if signed {
  633. /*
  634. First byte denotes the sign.
  635. */
  636. size_in_bits -= 8
  637. }
  638. size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS
  639. size_in_digits += 0 if size_in_bits % 8 == 0 else 1
  640. internal_zero(a, false, allocator) or_return
  641. internal_grow(a, size_in_digits, false, allocator) or_return
  642. if signed {
  643. sign = .Zero_or_Positive if buf[l-1] == 0 else .Negative
  644. buf = buf[:l-1]
  645. l -= 1
  646. }
  647. for _, i in buf {
  648. internal_shl(a, a, 8) or_return
  649. if signed && sign == .Negative {
  650. a.digit[0] |= DIGIT(255 - buf[l-i-1])
  651. } else {
  652. a.digit[0] |= DIGIT(buf[l-i-1])
  653. }
  654. }
  655. a.sign = sign
  656. a.used = size_in_digits
  657. internal_clamp(a) or_return
  658. if signed && sign == .Negative {
  659. return internal_sub(a, a, 1)
  660. }
  661. return nil
  662. }
  663. /*
  664. Initialize constants.
  665. */
  666. INT_ONE, INT_ZERO, INT_MINUS_ONE, INT_INF, INT_MINUS_INF, INT_NAN := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
  667. @(init, private)
  668. _init_constants :: proc() {
  669. initialize_constants()
  670. }
  671. initialize_constants :: proc() -> (res: int) {
  672. internal_set( INT_ZERO, 0); INT_ZERO.flags = {.Immutable}
  673. internal_set( INT_ONE, 1); INT_ONE.flags = {.Immutable}
  674. internal_set(INT_MINUS_ONE, -1); INT_MINUS_ONE.flags = {.Immutable}
  675. /*
  676. We set these special values to -1 or 1 so they don't get mistake for zero accidentally.
  677. This allows for shortcut tests of is_zero as .used == 0.
  678. */
  679. internal_set( INT_NAN, 1); INT_NAN.flags = {.Immutable, .NaN}
  680. internal_set( INT_INF, 1); INT_INF.flags = {.Immutable, .Inf}
  681. internal_set(INT_MINUS_INF, -1); INT_MINUS_INF.flags = {.Immutable, .Inf}
  682. return _DEFAULT_MUL_KARATSUBA_CUTOFF
  683. }
  684. /*
  685. Destroy constants.
  686. Optional for an EXE, as this would be called at the very end of a process.
  687. */
  688. destroy_constants :: proc() {
  689. internal_destroy(INT_ONE, INT_ZERO, INT_MINUS_ONE, INT_INF, INT_MINUS_INF, INT_NAN)
  690. }
  691. assert_if_nil :: proc{
  692. assert_if_nil_int,
  693. assert_if_nil_rat,
  694. }
  695. assert_if_nil_int :: #force_inline proc(integers: ..^Int, loc := #caller_location) {
  696. for i in integers {
  697. assert(i != nil, "(nil)", loc)
  698. }
  699. }
  700. assert_if_nil_rat :: #force_inline proc(rationals: ..^Rat, loc := #caller_location) {
  701. for r in rationals {
  702. assert(r != nil, "(nil)", loc)
  703. }
  704. }