Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
test_big_int01.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2024 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24#include <cstring>
25#include <iostream>
26
28
29#include <jau/int_types.hpp>
30#include <jau/mp/big_int.hpp>
31
32using namespace jau;
33using namespace jau::mp;
34using namespace jau::int_literals;
35
36TEST_CASE( "MP Big Int Test 00", "[big_int_t][arithmetic][math]" ) {
37 std::cout << "big_int mp_word_bits " << std::to_string( mp_word_bits ) << std::endl;
38
39 {
40 BigInt a = 1_u64, b = 2_u64, c = 3_u64, d = 4_u64, e = 256_u64;
41 std::cout << "big_int 1:: " << a.to_dec_string(true) << std::endl;
42 std::cout << "big_int 1:: " << a.to_hex_string(true) << std::endl;
43 std::cout << "big_int 2:: " << b.to_dec_string(true) << std::endl;
44 std::cout << "big_int 3:: " << c.to_dec_string(true) << std::endl;
45 std::cout << "big_int 256:: " << e.to_dec_string(true) << std::endl;
46 std::cout << "big_int 256:: " << e.to_hex_string(true) << std::endl;
47 REQUIRE( 1 == a.bits() );
48 REQUIRE( 1 == a.bytes() );
49 REQUIRE( 1 == a.sign() );
50 {
51 BigInt r = a + b;
52 std::cout << "big_int 1+2:: " << r.to_dec_string(true) << std::endl;
53 REQUIRE( c == r );
54 }
55 {
56 BigInt r = b * b;
57 std::cout << "big_int 2*2:: " << r.to_dec_string(true) << std::endl;
58 REQUIRE( d == r );
59 }
60 {
61 BigInt r = b / b;
62 std::cout << "big_int 2/2:: " << r.to_dec_string(true) << std::endl;
63 REQUIRE( a == r );
64 }
65
66 REQUIRE( 2 == b.bits() );
67 REQUIRE( 1 == b.bytes() );
68 REQUIRE( 1 == b.sign() );
69
70 REQUIRE( 2 == c.bits() );
71 REQUIRE( 1 == c.bytes() );
72 REQUIRE( 1 == c.sign() );
73
74 REQUIRE( 9 == e.bits() );
75 REQUIRE( 2 == e.bytes() );
76 REQUIRE( 1 == e.sign() );
77 }
78 {
79 BigInt a = BigInt::from_s32(-1), b = BigInt::from_s32(-2), c = BigInt::from_s32(-3), d = BigInt::from_s32(-256);
80 std::cout << "big_int -1:: " << a.to_dec_string(true) << std::endl;
81 std::cout << "big_int -2:: " << b.to_dec_string(true) << std::endl;
82 std::cout << "big_int -3:: " << c.to_dec_string(true) << std::endl;
83 std::cout << "big_int -256:: " << d.to_dec_string(true) << std::endl;
84 REQUIRE( 1 == a.bits() );
85 REQUIRE( 1 == a.bytes() );
86 REQUIRE( BigInt::negative == a.sign() );
87
88 REQUIRE( 2 == b.bits() );
89 REQUIRE( 1 == b.bytes() );
90 REQUIRE(BigInt::negative == b.sign() );
91
92 REQUIRE( 2 == c.bits() );
93 REQUIRE( 1 == c.bytes() );
94 REQUIRE(BigInt::negative == c.sign() );
95
96 REQUIRE( 9 == d.bits() );
97 REQUIRE( 2 == d.bytes() );
98 REQUIRE(BigInt::negative == d.sign() );
99 }
100}
101TEST_CASE( "MP Big Int Test 01", "[big_int_t][arithmetic][math]" ) {
102 {
103 BigInt a = 0xffffffffffffffff_u64, b = 0x12000000ffffffff_u64;
104 std::cout << "big_int a:: " << a.to_dec_string(true) << std::endl;
105 std::cout << "big_int a:: " << a.to_hex_string(true) << std::endl;
106 std::cout << "big_int b:: " << b.to_dec_string(true) << std::endl;
107 std::cout << "big_int b:: " << b.to_hex_string(true) << std::endl;
108
109 BigInt ab = a*b;
110 std::cout << "big_int a*b:: " << ab.to_dec_string(true) << std::endl;
111 std::cout << "big_int a*b:: " << ab.to_hex_string(true) << std::endl;
112 }
113 {
114 BigInt zero, ten(10), thirty(30), forty(40);
115 REQUIRE( zero < ten );
116 REQUIRE( zero < thirty );
117 REQUIRE( ten < thirty );
118
119 REQUIRE( ten > zero );
120 REQUIRE( thirty > ten );
121 REQUIRE( thirty > zero );
122
123 REQUIRE( ten <= ten );
124 REQUIRE( ten <= thirty );
125
126 REQUIRE( thirty >= thirty );
127 REQUIRE( thirty >= ten );
128
129 REQUIRE( thirty == thirty );
130 REQUIRE( thirty != ten );
131
132 REQUIRE( zero == min(zero, ten) );
133 REQUIRE( ten == max(zero, ten) );
134 REQUIRE( ten == clamp(zero, ten, thirty) );
135 REQUIRE( thirty == clamp(forty, ten, thirty) );
136 }
137}
138TEST_CASE( "MP Big Int Test 02", "[big_int_t][arithmetic][math]" ) {
139 REQUIRE( BigInt(10) == BigInt( 5) + BigInt(5) );
140 REQUIRE( BigInt(10) == BigInt( 2) * BigInt(5) );
141 REQUIRE( BigInt( 5) == BigInt(10) / BigInt(2) );
142 REQUIRE( BigInt( 1) == BigInt(10) % BigInt(3) );
143
144 REQUIRE( BigInt( 1) == BigInt(10).pow( BigInt( 0) ) );
145 REQUIRE( BigInt( 10) == BigInt(10).pow( BigInt( 1) ) );
146 REQUIRE( BigInt( 100000000_u64 ) == BigInt(10).pow( BigInt( 8) ) );
147 REQUIRE( BigInt( 4294967296_u64 ) == BigInt( 2).pow( BigInt(32) ) );
148
149 REQUIRE( BigInt( 0) == BigInt(10).pow( BigInt::from_s32(-1) ) );
150}
151TEST_CASE( "MP Big Int Dec Test 10", "[big_int_t][inout][math]" ) {
152 {
153 uint8_t a_u8[] = { 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe,
154 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
155 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
156
157 };
158 BigInt a(a_u8, sizeof(a_u8), lb_endian_t::little);
159 std::cout << "big_int zero:: " << a.to_dec_string(true) << std::endl;
160 std::cout << "big_int zero:: " << a.to_hex_string(true) << std::endl;
161 REQUIRE( 23 == sizeof(a_u8) );
162 if ( false ) {
163 for(size_t i=0; i<sizeof(a_u8); ++i) {
164 std::string s1;
165 jau::byteHexString(s1, a.byte_at(i), true);
166 std::cout << "zero.buf[" << std::to_string(i) << "]: 0x" << s1 << std::endl;
167 }
168 }
169 REQUIRE( sizeof(a_u8)*8 == a.bits() );
170 REQUIRE( sizeof(a_u8) == a.bytes() );
171
172 uint8_t buf[sizeof(a_u8)];
173 {
174 for(size_t i=0; i<sizeof(a_u8); ++i) {
175 buf[i] = 0;
176 }
177 REQUIRE( sizeof(a_u8) == a.binary_encode(buf, sizeof(buf), jau::lb_endian_t::little) );
178 if ( false ) {
179 for(size_t i=0; i<sizeof(a_u8); ++i) {
180 std::string s1;
181 jau::byteHexString(s1, buf[i], true);
182 std::cout << "le.buf[" << std::to_string(i) << "]: 0x" << s1 << std::endl;
183 }
184 }
185 for(size_t i=0; i<sizeof(a_u8); ++i) {
186 REQUIRE( (uint32_t)a_u8[i] == (uint32_t)buf[i] );
187 }
188 BigInt b(buf, sizeof(buf), jau::lb_endian_t::little);
189 std::cout << "big_int le:: " << b.to_dec_string(true) << std::endl;
190 std::cout << "big_int le:: " << b.to_hex_string(true) << std::endl;
191 REQUIRE( a == b );
192 }
193 {
194 for(size_t i=0; i<sizeof(a_u8); ++i) {
195 buf[i] = 0;
196 }
197 REQUIRE( sizeof(a_u8) == a.binary_encode(buf, sizeof(buf), jau::lb_endian_t::big) );
198 if ( false ) {
199 for(size_t i=0; i<sizeof(a_u8); ++i) {
200 std::string s1;
201 jau::byteHexString(s1, buf[i], true);
202 std::cout << "be.buf[" << std::to_string(i) << "]: 0x" << s1 << std::endl;
203 }
204 }
205 for(size_t i=0; i<sizeof(a_u8); ++i) {
206 REQUIRE( (uint32_t)a_u8[sizeof(a_u8)-i-1] == (uint32_t)buf[i] );
207 }
208 BigInt b(buf, sizeof(buf), jau::lb_endian_t::big);
209 std::cout << "big_int be:: " << b.to_dec_string(true) << std::endl;
210 std::cout << "big_int be:: " << b.to_hex_string(true) << std::endl;
211 REQUIRE( a == b );
212 }
213 }
214}
215TEST_CASE( "MP Big Int Dec Test 11", "[big_int_t][inout][math]" ) {
216 {
217 uint8_t a_u8[] = { 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe,
218 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
219 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
220
221 };
222 BigInt a("0xffeeddccbbaa998877665544332211fedcba9876543210");
223 std::cout << "big_int zero:: " << a.to_dec_string(true) << std::endl;
224 std::cout << "big_int zero:: " << a.to_hex_string(true) << std::endl;
225 REQUIRE( 23 == sizeof(a_u8) );
226 REQUIRE( sizeof(a_u8)*8 == a.bits() );
227 REQUIRE( sizeof(a_u8) == a.bytes() );
228
229 uint8_t buf[sizeof(a_u8)];
230 {
231 for(size_t i=0; i<sizeof(a_u8); ++i) {
232 buf[i] = 0;
233 }
234 REQUIRE( sizeof(a_u8) == a.binary_encode(buf, sizeof(buf), jau::lb_endian_t::little) );
235 for(size_t i=0; i<sizeof(a_u8); ++i) {
236 REQUIRE( (uint32_t)a_u8[i] == (uint32_t)buf[i] );
237 }
238 BigInt b(buf, sizeof(buf), jau::lb_endian_t::little);
239 std::cout << "big_int le:: " << b.to_dec_string(true) << std::endl;
240 std::cout << "big_int le:: " << b.to_hex_string(true) << std::endl;
241 REQUIRE( a == b );
242 }
243 {
244 for(size_t i=0; i<sizeof(a_u8); ++i) {
245 buf[i] = 0;
246 }
247 REQUIRE( sizeof(a_u8) == a.binary_encode(buf, sizeof(buf), jau::lb_endian_t::big) );
248 for(size_t i=0; i<sizeof(a_u8); ++i) {
249 REQUIRE( (uint32_t)a_u8[sizeof(a_u8)-i-1] == (uint32_t)buf[i] );
250 }
251 BigInt b(buf, sizeof(buf), jau::lb_endian_t::big);
252 std::cout << "big_int be:: " << b.to_dec_string(true) << std::endl;
253 std::cout << "big_int be:: " << b.to_hex_string(true) << std::endl;
254 REQUIRE( a == b );
255 }
256 }
257}
258TEST_CASE( "MP Big Int Error Handling Test 88", "[big_int_t][error][arithmetic][math]" ) {
259 {
260 BigInt a = 1, b = 0, r;
261 REQUIRE_THROWS_MATCHES( r = a / b, jau::math::MathDivByZeroError, Catch::Matchers::ContainsSubstring("div_by_zero") );
262 REQUIRE_THROWS_MATCHES( r = a % b, jau::math::MathDivByZeroError, Catch::Matchers::ContainsSubstring("div_by_zero") );
263 }
264 {
265 BigInt a = BigInt::from_s32(-1), b = BigInt::from_s32(-1), r;
266 REQUIRE_THROWS_MATCHES( r = a % b, jau::math::MathDomainError, Catch::Matchers::ContainsSubstring("invalid") );
267 }
268}
math_error_t::div_by_zero, i.e.
Definition: math_error.hpp:78
math_error_t::invalid
Definition: math_error.hpp:72
Arbitrary precision integer type.
Definition: big_int.hpp:43
size_t bits() const noexcept
Returns bit length of this integer.
Definition: big_int.hpp:310
size_t bytes() const
Returns byte length of this integer.
Definition: big_int.hpp:307
std::string to_dec_string(bool add_details=false) const noexcept
Definition: big_int.hpp:681
std::string to_hex_string(bool add_details=false) const noexcept
Definition: big_int.hpp:754
sign_t sign() const noexcept
Return the sign of the integer.
Definition: big_int.hpp:258
size_t binary_encode(uint8_t output[], size_t byte_len, const lb_endian_t byte_order) const noexcept
Stores this number to the value in buf with given byte_len, considering the given byte_order.
Definition: big_int.hpp:1119
uint8_t byte_at(size_t n) const noexcept
Definition: big_int.hpp:222
@ little
Identifier for little endian, equivalent to endian::little.
@ big
Identifier for big endian, equivalent to endian::big.
std::string to_string(const alphabet &v) noexcept
Definition: base_codec.hpp:97
constexpr T clamp(const T x, const T min_val, const T max_val) noexcept
Returns constrained integral value to lie between given min- and maximum value (w/ branching) in O(1)...
Definition: base_math.hpp:208
constexpr T min(const T x, const T y) noexcept
Returns the minimum of two integrals (w/ branching) in O(1)
Definition: base_math.hpp:177
constexpr T max(const T x, const T y) noexcept
Returns the maximum of two integrals (w/ branching) in O(1)
Definition: base_math.hpp:191
mp::BigInt pow(mp::BigInt b, mp::BigInt e)
Definition: big_int.hpp:1560
std::string & byteHexString(std::string &dest, const uint8_t value, const bool lowerCase) noexcept
Produce a hexadecimal string representation of the given byte value.
constexpr const jau::fraction_i64 zero(0l, 1lu)
zero is 0/1
big_int_t (this file) (c) 2024 Gothel Software e.K.
Definition: big_int.hpp:26
constexpr const size_t mp_word_bits
Definition: big_int_ops.hpp:41
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
TEST_CASE("MP Big Int Test 00", "[big_int_t][arithmetic][math]")