Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2017 Andrew Kelley
3 : : *
4 : : * This file is part of zig, which is MIT licensed.
5 : : * See http://opensource.org/licenses/MIT
6 : : */
7 : :
8 : : #ifndef ZIG_BIGINT_HPP
9 : : #define ZIG_BIGINT_HPP
10 : :
11 : : #include <stdint.h>
12 : : #include <stddef.h>
13 : :
14 : : struct BigInt {
15 : : size_t digit_count;
16 : : union {
17 : : uint64_t digit;
18 : : uint64_t *digits; // Least significant digit first
19 : : } data;
20 : : bool is_negative;
21 : : };
22 : :
23 : : struct Buf;
24 : : struct BigFloat;
25 : :
26 : : enum Cmp {
27 : : CmpLT,
28 : : CmpGT,
29 : : CmpEQ,
30 : : };
31 : :
32 : : void bigint_init_unsigned(BigInt *dest, uint64_t x);
33 : : void bigint_init_signed(BigInt *dest, int64_t x);
34 : : void bigint_init_bigint(BigInt *dest, const BigInt *src);
35 : : void bigint_init_bigfloat(BigInt *dest, const BigFloat *op);
36 : : void bigint_init_data(BigInt *dest, const uint64_t *digits, size_t digit_count, bool is_negative);
37 : :
38 : : // panics if number won't fit
39 : : uint64_t bigint_as_u64(const BigInt *bigint);
40 : : uint32_t bigint_as_u32(const BigInt *bigint);
41 : : size_t bigint_as_usize(const BigInt *bigint);
42 : :
43 : : int64_t bigint_as_signed(const BigInt *bigint);
44 : :
45 : 24108633 : static inline const uint64_t *bigint_ptr(const BigInt *bigint) {
46 [ + + ]: 24108633 : if (bigint->digit_count == 1) {
47 : 23851452 : return &bigint->data.digit;
48 : : } else {
49 : 257181 : return bigint->data.digits;
50 : : }
51 : : }
52 : :
53 : : bool bigint_fits_in_bits(const BigInt *bn, size_t bit_count, bool is_signed);
54 : : void bigint_write_twos_complement(const BigInt *big_int, uint8_t *buf, size_t bit_count, bool is_big_endian);
55 : : void bigint_read_twos_complement(BigInt *dest, const uint8_t *buf, size_t bit_count, bool is_big_endian,
56 : : bool is_signed);
57 : : void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2);
58 : : void bigint_add_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed);
59 : : void bigint_sub(BigInt *dest, const BigInt *op1, const BigInt *op2);
60 : : void bigint_sub_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed);
61 : : void bigint_mul(BigInt *dest, const BigInt *op1, const BigInt *op2);
62 : : void bigint_mul_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed);
63 : : void bigint_div_trunc(BigInt *dest, const BigInt *op1, const BigInt *op2);
64 : : void bigint_div_floor(BigInt *dest, const BigInt *op1, const BigInt *op2);
65 : : void bigint_rem(BigInt *dest, const BigInt *op1, const BigInt *op2);
66 : : void bigint_mod(BigInt *dest, const BigInt *op1, const BigInt *op2);
67 : :
68 : : void bigint_or(BigInt *dest, const BigInt *op1, const BigInt *op2);
69 : : void bigint_and(BigInt *dest, const BigInt *op1, const BigInt *op2);
70 : : void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2);
71 : :
72 : : void bigint_shl(BigInt *dest, const BigInt *op1, const BigInt *op2);
73 : : void bigint_shl_trunc(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed);
74 : : void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2);
75 : :
76 : : void bigint_negate(BigInt *dest, const BigInt *op);
77 : : void bigint_negate_wrap(BigInt *dest, const BigInt *op, size_t bit_count);
78 : : void bigint_not(BigInt *dest, const BigInt *op, size_t bit_count, bool is_signed);
79 : : void bigint_truncate(BigInt *dest, const BigInt *op, size_t bit_count, bool is_signed);
80 : :
81 : : Cmp bigint_cmp(const BigInt *op1, const BigInt *op2);
82 : :
83 : : void bigint_append_buf(Buf *buf, const BigInt *op, uint64_t base);
84 : :
85 : : size_t bigint_ctz(const BigInt *bi, size_t bit_count);
86 : : size_t bigint_clz(const BigInt *bi, size_t bit_count);
87 : : size_t bigint_popcount_signed(const BigInt *bi, size_t bit_count);
88 : : size_t bigint_popcount_unsigned(const BigInt *bi);
89 : :
90 : : size_t bigint_bits_needed(const BigInt *op);
91 : :
92 : :
93 : : // convenience functions
94 : : Cmp bigint_cmp_zero(const BigInt *op);
95 : :
96 : : void bigint_incr(BigInt *value);
97 : :
98 : : bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result);
99 : :
100 : : uint32_t bigint_hash(BigInt x);
101 : : bool bigint_eql(BigInt a, BigInt b);
102 : :
103 : : #endif
|