helpers.odin 22 KB

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