helpers.odin 21 KB

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