Skip to content

Commit 06fd3ae

Browse files
committed
Made specification of BitWidth and Signedness more verbose
1 parent 2a56cb3 commit 06fd3ae

File tree

8 files changed

+199
-190
lines changed

8 files changed

+199
-190
lines changed

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# bigint
2-
A header-only C++ library provides a fixed-width arbitrary-precision integer type called `bigint`. It supports both signed and unsigned numbers with a customizable bit-width. The class implements a wide range of arithmetic, bitwise, and comparison operators, making it suitable for tasks that require precise control over large integers.
2+
This header-only C++ library provides an arbitrary-fixed-width integer type called `bigint`. It supports both signed and unsigned numbers with a customizable bit-width. The class implements a wide range of arithmetic, bitwise, and comparison operators, making it suitable for tasks that require precise control over large integers.
33

44
## Features
55
- **Customizable Bit-Width:**
@@ -41,13 +41,13 @@ Construct a `bigint` from an integral type or a string:
4141

4242
```cpp
4343
// Create a 128-bit signed bigint from an integer:
44-
bigint::bigint<128, true> a(123456789);
44+
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> a(123456789);
4545

4646
// Create a 128-bit unsigned bigint from a decimal string:
47-
bigint::bigint<128, false> b("9876543210");
47+
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned> b("9876543210");
4848

4949
// Create a 128-bit signed bigint from a hexadecimal string:
50-
bigint::bigint<128, true> c("0x1A2B3C4D");
50+
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> c("0x1A2B3C4D");
5151
```
5252
5353
### Performing Arithmetic and Bitwise Operations
@@ -65,10 +65,10 @@ a -= 50;
6565
a *= -3;
6666
a /= 7;
6767
68-
bigint::bigint<128, true> d = ~a; // Bitwise NOT
69-
bigint::bigint<128, true> e = a & c; // Bitwise AND
70-
bigint::bigint<128, true> f = a | c; // Bitwise OR
71-
bigint::bigint<128, true> g = a ^ c; // Bitwise XOR
68+
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> d = ~a; // Bitwise NOT
69+
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> e = a & c; // Bitwise AND
70+
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> f = a | c; // Bitwise OR
71+
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> g = a ^ c; // Bitwise XOR
7272
7373
a <<= 4; // Left shift
7474
b >>= 8; // Right shift

include/bigint23/bigint.hpp

Lines changed: 106 additions & 97 deletions
Large diffs are not rendered by default.

tests/arithmetic_tests.cpp

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
namespace {
99
TEST(bigint23, addition_with_integral_test) {
10-
using i32 = bigint::bigint<32, true>;
11-
using u32 = bigint::bigint<32, false>;
10+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
11+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
1212
u32 const c = "0xffffffff";
1313
ASSERT_EQ(c + 1, 0);
1414
ASSERT_EQ(c + 2, 1);
@@ -18,8 +18,8 @@ namespace {
1818
}
1919

2020
TEST(bigint23, addition_with_bigint23_test) {
21-
using i32 = bigint::bigint<32, true>;
22-
using u32 = bigint::bigint<32, false>;
21+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
22+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
2323
u32 const c = "0xffffffff";
2424
u32 const d = "0x1";
2525
ASSERT_EQ(c + d, 0);
@@ -32,8 +32,8 @@ namespace {
3232
}
3333

3434
TEST(bigint23, multiplication_with_integral_test) {
35-
using i32 = bigint::bigint<32, true>;
36-
using u32 = bigint::bigint<32, false>;
35+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
36+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
3737
u32 const a = 42;
3838
ASSERT_EQ(a * 43, 1806);
3939
i32 const c = 2018238;
@@ -45,10 +45,10 @@ namespace {
4545
}
4646

4747
TEST(bigint23, multiplication_with_bigint23_test) {
48-
using i32 = bigint::bigint<32, true>;
49-
using u32 = bigint::bigint<32, false>;
50-
using i16 = bigint::bigint<16, true>;
51-
using u16 = bigint::bigint<16, false>;
48+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
49+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
50+
using i16 = bigint::bigint<bigint::BitWidth{16}, bigint::Signedness::Signed>;
51+
using u16 = bigint::bigint<bigint::BitWidth{16}, bigint::Signedness::Unsigned>;
5252
u32 const a = 42;
5353
u32 const b = 43;
5454
ASSERT_EQ(a * b, 1806);
@@ -65,8 +65,8 @@ namespace {
6565
}
6666

6767
TEST(bigint23, subtraction_with_integral_test) {
68-
using i32 = bigint::bigint<32, true>;
69-
using u32 = bigint::bigint<32, false>;
68+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
69+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
7070
u32 const a = 42;
7171
ASSERT_EQ(a - 1, 41);
7272
ASSERT_EQ(a - 2, 40);
@@ -78,8 +78,8 @@ namespace {
7878
}
7979

8080
TEST(bigint23, subtraction_with_bigint23_test) {
81-
using i32 = bigint::bigint<32, true>;
82-
using u32 = bigint::bigint<32, false>;
81+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
82+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
8383
u32 const a = 42;
8484
u32 const b = 1;
8585
ASSERT_EQ(a - b, 41);
@@ -94,8 +94,8 @@ namespace {
9494
}
9595

9696
TEST(bigint23, division_with_integral_test) {
97-
using i32 = bigint::bigint<32, true>;
98-
using u32 = bigint::bigint<32, false>;
97+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
98+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
9999
u32 const a = 15;
100100
ASSERT_EQ(a / 3, 5);
101101
ASSERT_EQ(a / 2, 7);
@@ -105,8 +105,8 @@ namespace {
105105
}
106106

107107
TEST(bigint23, division_with_bigint23_test) {
108-
using i32 = bigint::bigint<32, true>;
109-
using u32 = bigint::bigint<32, false>;
108+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
109+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
110110
u32 const a = 15;
111111
u32 const b = 3;
112112
ASSERT_EQ(a / b, 5);
@@ -120,8 +120,8 @@ namespace {
120120
}
121121

122122
TEST(bigint23, modulo_with_integral_test) {
123-
using i32 = bigint::bigint<32, true>;
124-
using u32 = bigint::bigint<32, false>;
123+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
124+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
125125
u32 const a = 15;
126126
ASSERT_EQ(a % 3, 0);
127127
ASSERT_EQ(a % 2, 1);
@@ -131,8 +131,8 @@ namespace {
131131
}
132132

133133
TEST(bigint23, modulo_with_bigint23_test) {
134-
using i32 = bigint::bigint<32, true>;
135-
using u32 = bigint::bigint<32, false>;
134+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
135+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
136136
u32 const a = 15;
137137
u32 const b = 3;
138138
ASSERT_EQ(a % b, 0);
@@ -146,8 +146,8 @@ namespace {
146146
}
147147

148148
TEST(bigint23, shift_test) {
149-
using i32 = bigint::bigint<32, true>;
150-
using u32 = bigint::bigint<32, false>;
149+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
150+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
151151
u32 const a = 42;
152152
ASSERT_EQ(a >> 2, 10);
153153
ASSERT_EQ(a << 2, 168);
@@ -166,24 +166,24 @@ namespace {
166166
}
167167

168168
TEST(bigint23, increment_test) {
169-
using i32 = bigint::bigint<32, true>;
169+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
170170
i32 a = 42;
171171
ASSERT_EQ(++a, 43);
172172
ASSERT_EQ(a++, 43);
173173
ASSERT_EQ(a, 44);
174174
}
175175

176176
TEST(bigint23, decrement_test) {
177-
using i32 = bigint::bigint<32, true>;
177+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
178178
i32 a = 42;
179179
ASSERT_EQ(--a, 41);
180180
ASSERT_EQ(a--, 41);
181181
ASSERT_EQ(a, 40);
182182
}
183183

184184
TEST(bigint23, unary_minus_test) {
185-
using i8 = bigint::bigint<8, true>;
186-
using u8 = bigint::bigint<8, false>;
185+
using i8 = bigint::bigint<bigint::BitWidth{8}, bigint::Signedness::Signed>;
186+
using u8 = bigint::bigint<bigint::BitWidth{8}, bigint::Signedness::Unsigned>;
187187
i8 const a = static_cast<int8_t>(0x80);
188188
ASSERT_THROW(auto test = -a, std::overflow_error);
189189
i8 const b = static_cast<int8_t>(-15);
@@ -196,7 +196,7 @@ namespace {
196196
}
197197

198198
TEST(bigint23, unary_plus_test) {
199-
using i8 = bigint::bigint<8, true>;
199+
using i8 = bigint::bigint<bigint::BitWidth{8}, bigint::Signedness::Signed>;
200200
constexpr i8 a = "42";
201201
ASSERT_EQ(+a, static_cast<int8_t>(42));
202202
}

tests/assign_and_equals_tests.cpp

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
namespace {
99
TEST(bigint23, assign_and_equals_8bit_test) {
10-
using uint128_t = bigint::bigint<128, false>;
11-
using int128_t = bigint::bigint<128, true>;
12-
using u8 = bigint::bigint<8, false>;
13-
using i8 = bigint::bigint<8, true>;
10+
using uint128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned>;
11+
using int128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed>;
12+
using u8 = bigint::bigint<bigint::BitWidth{8}, bigint::Signedness::Unsigned>;
13+
using i8 = bigint::bigint<bigint::BitWidth{8}, bigint::Signedness::Signed>;
1414

1515
uint128_t const a = static_cast<std::uint8_t>(42);
1616
ASSERT_EQ(static_cast<std::uint8_t>(42), a);
@@ -35,10 +35,10 @@ namespace {
3535
}
3636

3737
TEST(bigint23, assign_and_equals_16bit_test) {
38-
using uint128_t = bigint::bigint<128, false>;
39-
using int128_t = bigint::bigint<128, true>;
40-
using u16 = bigint::bigint<16, false>;
41-
using i16 = bigint::bigint<16, true>;
38+
using uint128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned>;
39+
using int128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed>;
40+
using u16 = bigint::bigint<bigint::BitWidth{16}, bigint::Signedness::Unsigned>;
41+
using i16 = bigint::bigint<bigint::BitWidth{16}, bigint::Signedness::Signed>;
4242

4343
uint128_t const a = static_cast<std::uint16_t>(42);
4444
ASSERT_EQ(static_cast<std::uint16_t>(42), a);
@@ -63,10 +63,10 @@ namespace {
6363
}
6464

6565
TEST(bigint23, assign_and_equals_32bit_test) {
66-
using uint128_t = bigint::bigint<128, false>;
67-
using int128_t = bigint::bigint<128, true>;
68-
using u32 = bigint::bigint<32, false>;
69-
using i32 = bigint::bigint<32, true>;
66+
using uint128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned>;
67+
using int128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed>;
68+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
69+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
7070

7171
uint128_t const a = static_cast<std::uint32_t>(42);
7272
ASSERT_EQ(static_cast<std::uint32_t>(42), a);
@@ -91,10 +91,10 @@ namespace {
9191
}
9292

9393
TEST(bigint23, assign_and_equals_64bit_test) {
94-
using uint128_t = bigint::bigint<128, false>;
95-
using int128_t = bigint::bigint<128, true>;
96-
using u64 = bigint::bigint<64, false>;
97-
using i64 = bigint::bigint<64, true>;
94+
using uint128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned>;
95+
using int128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed>;
96+
using u64 = bigint::bigint<bigint::BitWidth{64}, bigint::Signedness::Unsigned>;
97+
using i64 = bigint::bigint<bigint::BitWidth{64}, bigint::Signedness::Signed>;
9898

9999
uint128_t const a = static_cast<std::uint64_t>(42);
100100
ASSERT_EQ(static_cast<std::uint64_t>(42), a);
@@ -119,14 +119,14 @@ namespace {
119119
}
120120

121121
TEST(bigint23, assign_and_equals_large_test) {
122-
using uint128_t = bigint::bigint<128, false>;
123-
using int128_t = bigint::bigint<128, true>;
124-
using uint256_t = bigint::bigint<256, false>;
125-
using int256_t = bigint::bigint<256, true>;
126-
using u16 = bigint::bigint<16, false>;
127-
using u32 = bigint::bigint<32, false>;
128-
using i16 = bigint::bigint<16, true>;
129-
using i32 = bigint::bigint<32, true>;
122+
using uint128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned>;
123+
using int128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed>;
124+
using uint256_t = bigint::bigint<bigint::BitWidth{256}, bigint::Signedness::Unsigned>;
125+
using int256_t = bigint::bigint<bigint::BitWidth{256}, bigint::Signedness::Signed>;
126+
using u16 = bigint::bigint<bigint::BitWidth{16}, bigint::Signedness::Unsigned>;
127+
using u32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
128+
using i16 = bigint::bigint<bigint::BitWidth{16}, bigint::Signedness::Signed>;
129+
using i32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Signed>;
130130

131131
uint128_t const pos_uint = static_cast<std::uint64_t>(42);
132132
uint256_t const b = pos_uint;
@@ -190,4 +190,4 @@ namespace {
190190
ak = std::string("1234");
191191
ASSERT_EQ(ak, 1234);
192192
}
193-
}
193+
}

tests/binary_tests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,27 @@
77

88
namespace {
99
TEST(bigint23, binary_and_test) {
10-
using U32 = bigint::bigint<32, false>;
10+
using U32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
1111
U32 const a = "0x5a3b3216";
1212
ASSERT_EQ(a & 0x415185ab, 0x40110002);
1313
}
1414

1515
TEST(bigint23, binary_negation_test) {
16-
using U32 = bigint::bigint<32, false>;
16+
using U32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
1717
U32 const a = "0";
1818
ASSERT_EQ(~a, 0xFFFFFFFF);
1919
U32 const b = "0x41ED7899";
2020
ASSERT_EQ(~b, 0xBE128766);
2121
}
2222

2323
TEST(bigint23, binary_or_test) {
24-
using U32 = bigint::bigint<32, false>;
24+
using U32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
2525
U32 const a = "0x5a3b3216";
2626
ASSERT_EQ(a | 0x415185ab, 0x5B7BB7BF);
2727
}
2828

2929
TEST(bigint23, binary_xor_test) {
30-
using U32 = bigint::bigint<32, false>;
30+
using U32 = bigint::bigint<bigint::BitWidth{32}, bigint::Signedness::Unsigned>;
3131
U32 const a = "0x5a3b3216";
3232
ASSERT_EQ(a ^ 0x415185ab, 0x1B6AB7BD);
3333
}

tests/comparison_tests.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
namespace {
99
TEST(bigint23, compare_8bit_test) {
10-
using uint128_t = bigint::bigint<128, false>;
11-
using int128_t = bigint::bigint<128, true>;
10+
using uint128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned>;
11+
using int128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed>;
1212
uint128_t const a = static_cast<uint8_t>(0x42);
1313
ASSERT_GT(static_cast<uint8_t>(0x43), a);
1414
ASSERT_LT(static_cast<uint8_t>(0x41), a);
@@ -20,8 +20,8 @@ namespace {
2020
}
2121

2222
TEST(bigint23, compare_16bit_test) {
23-
using uint128_t = bigint::bigint<128, false>;
24-
using int128_t = bigint::bigint<128, true>;
23+
using uint128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned>;
24+
using int128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed>;
2525
uint128_t const a = static_cast<uint16_t>(0x42);
2626
ASSERT_GT(static_cast<uint16_t>(0x43), a);
2727
ASSERT_LT(static_cast<uint16_t>(0x41), a);
@@ -33,8 +33,8 @@ namespace {
3333
}
3434

3535
TEST(bigint23, compare_32bit_test) {
36-
using uint128_t = bigint::bigint<128, false>;
37-
using int128_t = bigint::bigint<128, true>;
36+
using uint128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned>;
37+
using int128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed>;
3838
uint128_t const a = static_cast<uint32_t>(0x42);
3939
ASSERT_GT(static_cast<uint32_t>(0x43), a);
4040
ASSERT_LT(static_cast<uint32_t>(0x41), a);
@@ -46,8 +46,8 @@ namespace {
4646
}
4747

4848
TEST(bigint23, complare_large_test) {
49-
using uint128_t = bigint::bigint<128, false>;
50-
using int128_t = bigint::bigint<128, true>;
49+
using uint128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned>;
50+
using int128_t = bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed>;
5151
uint128_t const a = static_cast<uint64_t>(0x42);
5252
uint128_t const b = static_cast<uint64_t>(0x43);
5353
ASSERT_LT(a, b);

tests/functions_tests.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
#include <gtest/gtest.h>
77

88
TEST(bigint23, byteswap_test) {
9-
bigint::bigint<128, false> expected;
9+
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned> expected;
1010
if constexpr (std::endian::native == std::endian::little) {
1111
expected = "0x78563412000000000000000000000000";
1212
} else {
1313
expected = "0x12345678";
1414
}
15-
bigint::bigint<128, false> const input = 0x12345678;
15+
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned> const input = 0x12345678;
1616
auto actual = byteswap(input);
1717
auto const actual_ptr = reinterpret_cast<char const *>(std::addressof(actual));
1818
auto const expected_ptr = reinterpret_cast<char const *>(std::addressof(expected));
@@ -22,10 +22,10 @@ TEST(bigint23, byteswap_test) {
2222
}
2323

2424
TEST(bigint23, abs_test) {
25-
bigint::bigint<128, false> const expected = 1234567890;
26-
bigint::bigint<128, true> const input = -1234567890;
25+
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned> const expected = 1234567890;
26+
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> const input = -1234567890;
2727
auto actual1 = abs(input);
2828
ASSERT_EQ(actual1, expected);
2929
auto actual2 = abs(expected);
3030
ASSERT_EQ(actual2, expected);
31-
}
31+
}

0 commit comments

Comments
 (0)