-
Notifications
You must be signed in to change notification settings - Fork 4
/
bint.hpp
199 lines (151 loc) · 5.94 KB
/
bint.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#ifndef SIGNED_BIG_INTEGER_HPP
#define SIGNED_BIG_INTEGER_HPP
#include "integer.hpp"
/// Left Positive - Right Negative.
#define LPOS_RNEG(SIGN_A, SIGN_B) (SIGN_A < SIGN_B)
/// Left Negative - Right Positive.
#define LNEG_RPOS(SIGN_A, SIGN_B) (SIGN_A > SIGN_B)
/// true if sign is positive.
#define SIGN_POSITIVE(SIGN) (!SIGN)
/// true if sign is negative.
#define SIGN_NEGATIVE(SIGN) (SIGN)
/// bint::compare -> integer.compare result sign flip.
#define CMP_RES_FLIP(CMP_RESULT) (-CMP_RESULT)
namespace apa {
/// Positive Sign Value Indicator.
static const limb_t POSITIVE = 0;
/// Negative Sign Value Indicator.
static const limb_t NEGATIVE = 1;
class bint_error : public std::exception {
private:
unsigned int error_code;
std::string error_message;
public:
bint_error(unsigned int error_code);
unsigned int get_error_code() const;
const char *what() const throw();
};
class bint {
private:
integer number;
/// 1 if negative, 0 if positive.
limb_t sign;
/// @return returns; -1 : if less than, 0 : if equal, 1 : if greater than.
int compare(const bint &with) const;
static void bitwise_prepare(bint &left, bint &right);
static bint add_partial(
const limb_t *l, size_t l_len, size_t l_index, const limb_t *r, size_t r_len, size_t r_index
);
static void sub_partial(
limb_t *output, size_t out_len, size_t out_index, const limb_t *m, size_t m_len, size_t m_index
);
static void mul_karatsuba(
limb_t *output, size_t out_len, size_t out_index, const limb_t *l, size_t l_len, size_t l_index,
const limb_t *r, size_t r_len, size_t r_index
);
public:
// Constructors
bint();
// Literal Constructors
bint(char num);
bint(unsigned char num);
bint(short num);
bint(unsigned short num);
bint(int num);
bint(unsigned int num);
bint(long num);
bint(unsigned long num);
bint(long long num);
bint(unsigned long long num);
// String Literal Constructors
bint(const std::string &input);
bint(const char *input);
// Array Constructors
bint(std::initializer_list<limb_t> limbs, limb_t sign = 0);
bint(limb_t *arr, size_t capacity, size_t length, limb_t sign);
/// automatically sets the sign to `POSITIVE`.
bint(size_t capacity, size_t length, bool AllocateSpace = true);
// Special Constructors.
bint(const bint &src); // copy.
bint(bint &&src) noexcept; // move.
// Special Assignments.
bint &operator=(const bint &src); // copy.
bint &operator=(bint &&src) noexcept; // move.
// integer Constructors
bint(limb_t sign, const integer &number); // integer copy.
bint(limb_t sign, integer &&number) noexcept; // integer move.
~bint();
// Relational Operators
bool operator<(const bint &op) const;
bool operator>(const bint &op) const;
bool operator==(const bint &op) const;
bool operator!=(const bint &op) const;
bool operator<=(const bint &op) const;
bool operator>=(const bint &op) const;
// Bit-Wise Logical Operators
bint &operator&=(const bint &op);
bint &operator|=(const bint &op);
bint &operator^=(const bint &op);
bint operator&(const bint &op) const;
bint operator|(const bint &op) const;
bint operator^(const bint &op) const;
bint operator~() const;
// Logical Operators
explicit operator bool() const noexcept;
// Arithmetic Operators
bint &operator+=(const bint &op);
bint &operator-=(const bint &op);
bint &operator*=(const bint &op);
bint &operator/=(const bint &op);
bint &operator%=(const bint &op);
bint operator+(const bint &op) const;
bint operator-(const bint &op) const;
bint operator*(const bint &op) const;
bint operator/(const bint &op) const;
bint operator%(const bint &op) const;
bint operator-() const;
bint mul_naive(const bint &op) const;
// pre-fix increment/decrement
bint &operator++();
bint &operator--();
// post-fix increment/decrement
bint operator++(int);
bint operator--(int);
// Shift Operators
bint &operator<<=(size_t bits);
bint &operator>>=(size_t bits);
bint operator<<(size_t bits) const;
bint operator>>(size_t bits) const;
// for left shift (<<) with parameter bint type use the formula : x*2^k
// for right shift (>>) with parameter bint type use the formula : x/2^k
// Print Methods
void printHex() const;
void printHex_spaced_out() const;
void printStatus(std::string printIdentifier = "default") const;
/// @return returns a string that represent the value of a bint number in base
/// 10 form or decimal.
std::string to_base10_string() const;
/// @return returns a string that represent the value of a bint number in base
/// 16 form or hexadecimal.
std::string to_base16_string() const;
// Member Access Methods
size_t capacity_size() const;
size_t limb_size() const;
size_t byte_size() const;
size_t bit_size() const;
const limb_t *limb_view() const;
const limb_t *byte_view() const;
limb_t *detach();
};
// functions
void swap(bint &a, bint &b);
// IO Operators
std::ostream &operator<<(std::ostream &out, const bint &num);
std::istream &operator>>(std::istream &in, bint &num);
// bint constants
static const bint __BINT_ZERO = 0;
static const bint __BINT_ONE = 1;
static const bint __BINT_TWO = 2;
static const bint __BINT_TEN = 10;
} // namespace apa
#endif