/rust/registry/src/index.crates.io-1949cf8c6b5b557f/num-bigint-0.4.6/src/bigint.rs
Line | Count | Source |
1 | | // `Add`/`Sub` ops may flip from `BigInt` to its `BigUint` magnitude |
2 | | #![allow(clippy::suspicious_arithmetic_impl)] |
3 | | |
4 | | use alloc::string::String; |
5 | | use alloc::vec::Vec; |
6 | | use core::cmp::Ordering::{self, Equal}; |
7 | | use core::default::Default; |
8 | | use core::fmt; |
9 | | use core::hash; |
10 | | use core::ops::{Neg, Not}; |
11 | | use core::str; |
12 | | |
13 | | use num_integer::{Integer, Roots}; |
14 | | use num_traits::{ConstZero, Num, One, Pow, Signed, Zero}; |
15 | | |
16 | | use self::Sign::{Minus, NoSign, Plus}; |
17 | | |
18 | | use crate::big_digit::BigDigit; |
19 | | use crate::biguint::to_str_radix_reversed; |
20 | | use crate::biguint::{BigUint, IntDigits, U32Digits, U64Digits}; |
21 | | |
22 | | mod addition; |
23 | | mod division; |
24 | | mod multiplication; |
25 | | mod subtraction; |
26 | | |
27 | | mod arbitrary; |
28 | | mod bits; |
29 | | mod convert; |
30 | | mod power; |
31 | | mod serde; |
32 | | mod shift; |
33 | | |
34 | | /// A `Sign` is a [`BigInt`]'s composing element. |
35 | | #[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone, Debug, Hash)] |
36 | | pub enum Sign { |
37 | | Minus, |
38 | | NoSign, |
39 | | Plus, |
40 | | } |
41 | | |
42 | | impl Neg for Sign { |
43 | | type Output = Sign; |
44 | | |
45 | | /// Negate `Sign` value. |
46 | | #[inline] |
47 | 0 | fn neg(self) -> Sign { |
48 | 0 | match self { |
49 | 0 | Minus => Plus, |
50 | 0 | NoSign => NoSign, |
51 | 0 | Plus => Minus, |
52 | | } |
53 | 0 | } |
54 | | } |
55 | | |
56 | | /// A big signed integer type. |
57 | | pub struct BigInt { |
58 | | sign: Sign, |
59 | | data: BigUint, |
60 | | } |
61 | | |
62 | | // Note: derived `Clone` doesn't specialize `clone_from`, |
63 | | // but we want to keep the allocation in `data`. |
64 | | impl Clone for BigInt { |
65 | | #[inline] |
66 | 0 | fn clone(&self) -> Self { |
67 | 0 | BigInt { |
68 | 0 | sign: self.sign, |
69 | 0 | data: self.data.clone(), |
70 | 0 | } |
71 | 0 | } Unexecuted instantiation: <num_bigint::bigint::BigInt as core::clone::Clone>::clone Unexecuted instantiation: <num_bigint::bigint::BigInt as core::clone::Clone>::clone |
72 | | |
73 | | #[inline] |
74 | 0 | fn clone_from(&mut self, other: &Self) { |
75 | 0 | self.sign = other.sign; |
76 | 0 | self.data.clone_from(&other.data); |
77 | 0 | } |
78 | | } |
79 | | |
80 | | impl hash::Hash for BigInt { |
81 | | #[inline] |
82 | 0 | fn hash<H: hash::Hasher>(&self, state: &mut H) { |
83 | 0 | debug_assert!((self.sign != NoSign) ^ self.data.is_zero()); |
84 | 0 | self.sign.hash(state); |
85 | 0 | if self.sign != NoSign { |
86 | 0 | self.data.hash(state); |
87 | 0 | } |
88 | 0 | } |
89 | | } |
90 | | |
91 | | impl PartialEq for BigInt { |
92 | | #[inline] |
93 | 0 | fn eq(&self, other: &BigInt) -> bool { |
94 | 0 | debug_assert!((self.sign != NoSign) ^ self.data.is_zero()); |
95 | 0 | debug_assert!((other.sign != NoSign) ^ other.data.is_zero()); |
96 | 0 | self.sign == other.sign && (self.sign == NoSign || self.data == other.data) |
97 | 0 | } Unexecuted instantiation: <num_bigint::bigint::BigInt as core::cmp::PartialEq>::eq Unexecuted instantiation: <num_bigint::bigint::BigInt as core::cmp::PartialEq>::eq |
98 | | } |
99 | | |
100 | | impl Eq for BigInt {} |
101 | | |
102 | | impl PartialOrd for BigInt { |
103 | | #[inline] |
104 | 0 | fn partial_cmp(&self, other: &BigInt) -> Option<Ordering> { |
105 | 0 | Some(self.cmp(other)) |
106 | 0 | } |
107 | | } |
108 | | |
109 | | impl Ord for BigInt { |
110 | | #[inline] |
111 | 0 | fn cmp(&self, other: &BigInt) -> Ordering { |
112 | 0 | debug_assert!((self.sign != NoSign) ^ self.data.is_zero()); |
113 | 0 | debug_assert!((other.sign != NoSign) ^ other.data.is_zero()); |
114 | 0 | let scmp = self.sign.cmp(&other.sign); |
115 | 0 | if scmp != Equal { |
116 | 0 | return scmp; |
117 | 0 | } |
118 | | |
119 | 0 | match self.sign { |
120 | 0 | NoSign => Equal, |
121 | 0 | Plus => self.data.cmp(&other.data), |
122 | 0 | Minus => other.data.cmp(&self.data), |
123 | | } |
124 | 0 | } |
125 | | } |
126 | | |
127 | | impl Default for BigInt { |
128 | | #[inline] |
129 | 0 | fn default() -> BigInt { |
130 | 0 | Self::ZERO |
131 | 0 | } |
132 | | } |
133 | | |
134 | | impl fmt::Debug for BigInt { |
135 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
136 | 0 | fmt::Display::fmt(self, f) |
137 | 0 | } |
138 | | } |
139 | | |
140 | | impl fmt::Display for BigInt { |
141 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
142 | 0 | f.pad_integral(!self.is_negative(), "", &self.data.to_str_radix(10)) |
143 | 0 | } |
144 | | } |
145 | | |
146 | | impl fmt::Binary for BigInt { |
147 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
148 | 0 | f.pad_integral(!self.is_negative(), "0b", &self.data.to_str_radix(2)) |
149 | 0 | } |
150 | | } |
151 | | |
152 | | impl fmt::Octal for BigInt { |
153 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
154 | 0 | f.pad_integral(!self.is_negative(), "0o", &self.data.to_str_radix(8)) |
155 | 0 | } |
156 | | } |
157 | | |
158 | | impl fmt::LowerHex for BigInt { |
159 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
160 | 0 | f.pad_integral(!self.is_negative(), "0x", &self.data.to_str_radix(16)) |
161 | 0 | } |
162 | | } |
163 | | |
164 | | impl fmt::UpperHex for BigInt { |
165 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
166 | 0 | let mut s = self.data.to_str_radix(16); |
167 | 0 | s.make_ascii_uppercase(); |
168 | 0 | f.pad_integral(!self.is_negative(), "0x", &s) |
169 | 0 | } |
170 | | } |
171 | | |
172 | | // !-2 = !...f fe = ...0 01 = +1 |
173 | | // !-1 = !...f ff = ...0 00 = 0 |
174 | | // ! 0 = !...0 00 = ...f ff = -1 |
175 | | // !+1 = !...0 01 = ...f fe = -2 |
176 | | impl Not for BigInt { |
177 | | type Output = BigInt; |
178 | | |
179 | 0 | fn not(mut self) -> BigInt { |
180 | 0 | match self.sign { |
181 | 0 | NoSign | Plus => { |
182 | 0 | self.data += 1u32; |
183 | 0 | self.sign = Minus; |
184 | 0 | } |
185 | | Minus => { |
186 | 0 | self.data -= 1u32; |
187 | 0 | self.sign = if self.data.is_zero() { NoSign } else { Plus }; |
188 | | } |
189 | | } |
190 | 0 | self |
191 | 0 | } |
192 | | } |
193 | | |
194 | | impl Not for &BigInt { |
195 | | type Output = BigInt; |
196 | | |
197 | 0 | fn not(self) -> BigInt { |
198 | 0 | match self.sign { |
199 | 0 | NoSign => -BigInt::one(), |
200 | 0 | Plus => -BigInt::from(&self.data + 1u32), |
201 | 0 | Minus => BigInt::from(&self.data - 1u32), |
202 | | } |
203 | 0 | } |
204 | | } |
205 | | |
206 | | impl Zero for BigInt { |
207 | | #[inline] |
208 | 0 | fn zero() -> BigInt { |
209 | 0 | Self::ZERO |
210 | 0 | } |
211 | | |
212 | | #[inline] |
213 | 0 | fn set_zero(&mut self) { |
214 | 0 | self.data.set_zero(); |
215 | 0 | self.sign = NoSign; |
216 | 0 | } |
217 | | |
218 | | #[inline] |
219 | 0 | fn is_zero(&self) -> bool { |
220 | 0 | self.sign == NoSign |
221 | 0 | } |
222 | | } |
223 | | |
224 | | impl ConstZero for BigInt { |
225 | | // forward to the inherent const |
226 | | const ZERO: Self = Self::ZERO; |
227 | | } |
228 | | |
229 | | impl One for BigInt { |
230 | | #[inline] |
231 | 0 | fn one() -> BigInt { |
232 | 0 | BigInt { |
233 | 0 | sign: Plus, |
234 | 0 | data: BigUint::one(), |
235 | 0 | } |
236 | 0 | } |
237 | | |
238 | | #[inline] |
239 | 0 | fn set_one(&mut self) { |
240 | 0 | self.data.set_one(); |
241 | 0 | self.sign = Plus; |
242 | 0 | } |
243 | | |
244 | | #[inline] |
245 | 0 | fn is_one(&self) -> bool { |
246 | 0 | self.sign == Plus && self.data.is_one() |
247 | 0 | } |
248 | | } |
249 | | |
250 | | impl Signed for BigInt { |
251 | | #[inline] |
252 | 0 | fn abs(&self) -> BigInt { |
253 | 0 | match self.sign { |
254 | 0 | Plus | NoSign => self.clone(), |
255 | 0 | Minus => BigInt::from(self.data.clone()), |
256 | | } |
257 | 0 | } |
258 | | |
259 | | #[inline] |
260 | 0 | fn abs_sub(&self, other: &BigInt) -> BigInt { |
261 | 0 | if *self <= *other { |
262 | 0 | Self::ZERO |
263 | | } else { |
264 | 0 | self - other |
265 | | } |
266 | 0 | } |
267 | | |
268 | | #[inline] |
269 | 0 | fn signum(&self) -> BigInt { |
270 | 0 | match self.sign { |
271 | 0 | Plus => BigInt::one(), |
272 | 0 | Minus => -BigInt::one(), |
273 | 0 | NoSign => Self::ZERO, |
274 | | } |
275 | 0 | } |
276 | | |
277 | | #[inline] |
278 | 0 | fn is_positive(&self) -> bool { |
279 | 0 | self.sign == Plus |
280 | 0 | } |
281 | | |
282 | | #[inline] |
283 | 0 | fn is_negative(&self) -> bool { |
284 | 0 | self.sign == Minus |
285 | 0 | } |
286 | | } |
287 | | |
288 | | trait UnsignedAbs { |
289 | | type Unsigned; |
290 | | |
291 | | fn checked_uabs(self) -> CheckedUnsignedAbs<Self::Unsigned>; |
292 | | } |
293 | | |
294 | | enum CheckedUnsignedAbs<T> { |
295 | | Positive(T), |
296 | | Negative(T), |
297 | | } |
298 | | use self::CheckedUnsignedAbs::{Negative, Positive}; |
299 | | |
300 | | macro_rules! impl_unsigned_abs { |
301 | | ($Signed:ty, $Unsigned:ty) => { |
302 | | impl UnsignedAbs for $Signed { |
303 | | type Unsigned = $Unsigned; |
304 | | |
305 | | #[inline] |
306 | 0 | fn checked_uabs(self) -> CheckedUnsignedAbs<Self::Unsigned> { |
307 | 0 | if self >= 0 { |
308 | 0 | Positive(self as $Unsigned) |
309 | | } else { |
310 | 0 | Negative(self.wrapping_neg() as $Unsigned) |
311 | | } |
312 | 0 | } Unexecuted instantiation: <i32 as num_bigint::bigint::UnsignedAbs>::checked_uabs Unexecuted instantiation: <i16 as num_bigint::bigint::UnsignedAbs>::checked_uabs Unexecuted instantiation: <i64 as num_bigint::bigint::UnsignedAbs>::checked_uabs Unexecuted instantiation: <i128 as num_bigint::bigint::UnsignedAbs>::checked_uabs Unexecuted instantiation: <isize as num_bigint::bigint::UnsignedAbs>::checked_uabs Unexecuted instantiation: <i8 as num_bigint::bigint::UnsignedAbs>::checked_uabs |
313 | | } |
314 | | }; |
315 | | } |
316 | | impl_unsigned_abs!(i8, u8); |
317 | | impl_unsigned_abs!(i16, u16); |
318 | | impl_unsigned_abs!(i32, u32); |
319 | | impl_unsigned_abs!(i64, u64); |
320 | | impl_unsigned_abs!(i128, u128); |
321 | | impl_unsigned_abs!(isize, usize); |
322 | | |
323 | | impl Neg for BigInt { |
324 | | type Output = BigInt; |
325 | | |
326 | | #[inline] |
327 | 0 | fn neg(mut self) -> BigInt { |
328 | 0 | self.sign = -self.sign; |
329 | 0 | self |
330 | 0 | } |
331 | | } |
332 | | |
333 | | impl Neg for &BigInt { |
334 | | type Output = BigInt; |
335 | | |
336 | | #[inline] |
337 | 0 | fn neg(self) -> BigInt { |
338 | 0 | -self.clone() |
339 | 0 | } |
340 | | } |
341 | | |
342 | | impl Integer for BigInt { |
343 | | #[inline] |
344 | 0 | fn div_rem(&self, other: &BigInt) -> (BigInt, BigInt) { |
345 | | // r.sign == self.sign |
346 | 0 | let (d_ui, r_ui) = self.data.div_rem(&other.data); |
347 | 0 | let d = BigInt::from_biguint(self.sign, d_ui); |
348 | 0 | let r = BigInt::from_biguint(self.sign, r_ui); |
349 | 0 | if other.is_negative() { |
350 | 0 | (-d, r) |
351 | | } else { |
352 | 0 | (d, r) |
353 | | } |
354 | 0 | } |
355 | | |
356 | | #[inline] |
357 | 0 | fn div_floor(&self, other: &BigInt) -> BigInt { |
358 | 0 | let (d_ui, m) = self.data.div_mod_floor(&other.data); |
359 | 0 | let d = BigInt::from(d_ui); |
360 | 0 | match (self.sign, other.sign) { |
361 | 0 | (Plus, Plus) | (NoSign, Plus) | (Minus, Minus) => d, |
362 | | (Plus, Minus) | (NoSign, Minus) | (Minus, Plus) => { |
363 | 0 | if m.is_zero() { |
364 | 0 | -d |
365 | | } else { |
366 | 0 | -d - 1u32 |
367 | | } |
368 | | } |
369 | 0 | (_, NoSign) => unreachable!(), |
370 | | } |
371 | 0 | } |
372 | | |
373 | | #[inline] |
374 | 0 | fn mod_floor(&self, other: &BigInt) -> BigInt { |
375 | | // m.sign == other.sign |
376 | 0 | let m_ui = self.data.mod_floor(&other.data); |
377 | 0 | let m = BigInt::from_biguint(other.sign, m_ui); |
378 | 0 | match (self.sign, other.sign) { |
379 | 0 | (Plus, Plus) | (NoSign, Plus) | (Minus, Minus) => m, |
380 | | (Plus, Minus) | (NoSign, Minus) | (Minus, Plus) => { |
381 | 0 | if m.is_zero() { |
382 | 0 | m |
383 | | } else { |
384 | 0 | other - m |
385 | | } |
386 | | } |
387 | 0 | (_, NoSign) => unreachable!(), |
388 | | } |
389 | 0 | } |
390 | | |
391 | 0 | fn div_mod_floor(&self, other: &BigInt) -> (BigInt, BigInt) { |
392 | | // m.sign == other.sign |
393 | 0 | let (d_ui, m_ui) = self.data.div_mod_floor(&other.data); |
394 | 0 | let d = BigInt::from(d_ui); |
395 | 0 | let m = BigInt::from_biguint(other.sign, m_ui); |
396 | 0 | match (self.sign, other.sign) { |
397 | 0 | (Plus, Plus) | (NoSign, Plus) | (Minus, Minus) => (d, m), |
398 | | (Plus, Minus) | (NoSign, Minus) | (Minus, Plus) => { |
399 | 0 | if m.is_zero() { |
400 | 0 | (-d, m) |
401 | | } else { |
402 | 0 | (-d - 1u32, other - m) |
403 | | } |
404 | | } |
405 | 0 | (_, NoSign) => unreachable!(), |
406 | | } |
407 | 0 | } |
408 | | |
409 | | #[inline] |
410 | 0 | fn div_ceil(&self, other: &Self) -> Self { |
411 | 0 | let (d_ui, m) = self.data.div_mod_floor(&other.data); |
412 | 0 | let d = BigInt::from(d_ui); |
413 | 0 | match (self.sign, other.sign) { |
414 | 0 | (Plus, Minus) | (NoSign, Minus) | (Minus, Plus) => -d, |
415 | | (Plus, Plus) | (NoSign, Plus) | (Minus, Minus) => { |
416 | 0 | if m.is_zero() { |
417 | 0 | d |
418 | | } else { |
419 | 0 | d + 1u32 |
420 | | } |
421 | | } |
422 | 0 | (_, NoSign) => unreachable!(), |
423 | | } |
424 | 0 | } |
425 | | |
426 | | /// Calculates the Greatest Common Divisor (GCD) of the number and `other`. |
427 | | /// |
428 | | /// The result is always positive. |
429 | | #[inline] |
430 | 0 | fn gcd(&self, other: &BigInt) -> BigInt { |
431 | 0 | BigInt::from(self.data.gcd(&other.data)) |
432 | 0 | } |
433 | | |
434 | | /// Calculates the Lowest Common Multiple (LCM) of the number and `other`. |
435 | | #[inline] |
436 | 0 | fn lcm(&self, other: &BigInt) -> BigInt { |
437 | 0 | BigInt::from(self.data.lcm(&other.data)) |
438 | 0 | } |
439 | | |
440 | | /// Calculates the Greatest Common Divisor (GCD) and |
441 | | /// Lowest Common Multiple (LCM) together. |
442 | | #[inline] |
443 | 0 | fn gcd_lcm(&self, other: &BigInt) -> (BigInt, BigInt) { |
444 | 0 | let (gcd, lcm) = self.data.gcd_lcm(&other.data); |
445 | 0 | (BigInt::from(gcd), BigInt::from(lcm)) |
446 | 0 | } |
447 | | |
448 | | /// Greatest common divisor, least common multiple, and Bézout coefficients. |
449 | | #[inline] |
450 | 0 | fn extended_gcd_lcm(&self, other: &BigInt) -> (num_integer::ExtendedGcd<BigInt>, BigInt) { |
451 | 0 | let egcd = self.extended_gcd(other); |
452 | 0 | let lcm = if egcd.gcd.is_zero() { |
453 | 0 | Self::ZERO |
454 | | } else { |
455 | 0 | BigInt::from(&self.data / &egcd.gcd.data * &other.data) |
456 | | }; |
457 | 0 | (egcd, lcm) |
458 | 0 | } |
459 | | |
460 | | /// Deprecated, use `is_multiple_of` instead. |
461 | | #[inline] |
462 | 0 | fn divides(&self, other: &BigInt) -> bool { |
463 | 0 | self.is_multiple_of(other) |
464 | 0 | } |
465 | | |
466 | | /// Returns `true` if the number is a multiple of `other`. |
467 | | #[inline] |
468 | 0 | fn is_multiple_of(&self, other: &BigInt) -> bool { |
469 | 0 | self.data.is_multiple_of(&other.data) |
470 | 0 | } |
471 | | |
472 | | /// Returns `true` if the number is divisible by `2`. |
473 | | #[inline] |
474 | 0 | fn is_even(&self) -> bool { |
475 | 0 | self.data.is_even() |
476 | 0 | } |
477 | | |
478 | | /// Returns `true` if the number is not divisible by `2`. |
479 | | #[inline] |
480 | 0 | fn is_odd(&self) -> bool { |
481 | 0 | self.data.is_odd() |
482 | 0 | } |
483 | | |
484 | | /// Rounds up to nearest multiple of argument. |
485 | | #[inline] |
486 | 0 | fn next_multiple_of(&self, other: &Self) -> Self { |
487 | 0 | let m = self.mod_floor(other); |
488 | 0 | if m.is_zero() { |
489 | 0 | self.clone() |
490 | | } else { |
491 | 0 | self + (other - m) |
492 | | } |
493 | 0 | } |
494 | | /// Rounds down to nearest multiple of argument. |
495 | | #[inline] |
496 | 0 | fn prev_multiple_of(&self, other: &Self) -> Self { |
497 | 0 | self - self.mod_floor(other) |
498 | 0 | } |
499 | | |
500 | 0 | fn dec(&mut self) { |
501 | 0 | *self -= 1u32; |
502 | 0 | } |
503 | | |
504 | 0 | fn inc(&mut self) { |
505 | 0 | *self += 1u32; |
506 | 0 | } |
507 | | } |
508 | | |
509 | | impl Roots for BigInt { |
510 | 0 | fn nth_root(&self, n: u32) -> Self { |
511 | 0 | assert!( |
512 | 0 | !(self.is_negative() && n.is_even()), |
513 | 0 | "root of degree {} is imaginary", |
514 | | n |
515 | | ); |
516 | | |
517 | 0 | BigInt::from_biguint(self.sign, self.data.nth_root(n)) |
518 | 0 | } |
519 | | |
520 | 0 | fn sqrt(&self) -> Self { |
521 | 0 | assert!(!self.is_negative(), "square root is imaginary"); |
522 | | |
523 | 0 | BigInt::from_biguint(self.sign, self.data.sqrt()) |
524 | 0 | } |
525 | | |
526 | 0 | fn cbrt(&self) -> Self { |
527 | 0 | BigInt::from_biguint(self.sign, self.data.cbrt()) |
528 | 0 | } |
529 | | } |
530 | | |
531 | | impl IntDigits for BigInt { |
532 | | #[inline] |
533 | 0 | fn digits(&self) -> &[BigDigit] { |
534 | 0 | self.data.digits() |
535 | 0 | } |
536 | | #[inline] |
537 | 0 | fn digits_mut(&mut self) -> &mut Vec<BigDigit> { |
538 | 0 | self.data.digits_mut() |
539 | 0 | } |
540 | | #[inline] |
541 | 0 | fn normalize(&mut self) { |
542 | 0 | self.data.normalize(); |
543 | 0 | if self.data.is_zero() { |
544 | 0 | self.sign = NoSign; |
545 | 0 | } |
546 | 0 | } |
547 | | #[inline] |
548 | 0 | fn capacity(&self) -> usize { |
549 | 0 | self.data.capacity() |
550 | 0 | } |
551 | | #[inline] |
552 | 0 | fn len(&self) -> usize { |
553 | 0 | self.data.len() |
554 | 0 | } |
555 | | } |
556 | | |
557 | | /// A generic trait for converting a value to a [`BigInt`]. This may return |
558 | | /// `None` when converting from `f32` or `f64`, and will always succeed |
559 | | /// when converting from any integer or unsigned primitive, or [`BigUint`]. |
560 | | pub trait ToBigInt { |
561 | | /// Converts the value of `self` to a [`BigInt`]. |
562 | | fn to_bigint(&self) -> Option<BigInt>; |
563 | | } |
564 | | |
565 | | impl BigInt { |
566 | | /// A constant `BigInt` with value 0, useful for static initialization. |
567 | | pub const ZERO: Self = BigInt { |
568 | | sign: NoSign, |
569 | | data: BigUint::ZERO, |
570 | | }; |
571 | | |
572 | | /// Creates and initializes a [`BigInt`]. |
573 | | /// |
574 | | /// The base 2<sup>32</sup> digits are ordered least significant digit first. |
575 | | #[inline] |
576 | 0 | pub fn new(sign: Sign, digits: Vec<u32>) -> BigInt { |
577 | 0 | BigInt::from_biguint(sign, BigUint::new(digits)) |
578 | 0 | } |
579 | | |
580 | | /// Creates and initializes a [`BigInt`]. |
581 | | /// |
582 | | /// The base 2<sup>32</sup> digits are ordered least significant digit first. |
583 | | #[inline] |
584 | 19.5k | pub fn from_biguint(mut sign: Sign, mut data: BigUint) -> BigInt { |
585 | 19.5k | if sign == NoSign { |
586 | 0 | data.assign_from_slice(&[]); |
587 | 19.5k | } else if data.is_zero() { |
588 | 1.45k | sign = NoSign; |
589 | 18.1k | } |
590 | | |
591 | 19.5k | BigInt { sign, data } |
592 | 19.5k | } <num_bigint::bigint::BigInt>::from_biguint Line | Count | Source | 584 | 19.5k | pub fn from_biguint(mut sign: Sign, mut data: BigUint) -> BigInt { | 585 | 19.5k | if sign == NoSign { | 586 | 0 | data.assign_from_slice(&[]); | 587 | 19.5k | } else if data.is_zero() { | 588 | 1.45k | sign = NoSign; | 589 | 18.1k | } | 590 | | | 591 | 19.5k | BigInt { sign, data } | 592 | 19.5k | } |
Unexecuted instantiation: <num_bigint::bigint::BigInt>::from_biguint |
593 | | |
594 | | /// Creates and initializes a [`BigInt`]. |
595 | | /// |
596 | | /// The base 2<sup>32</sup> digits are ordered least significant digit first. |
597 | | #[inline] |
598 | 0 | pub fn from_slice(sign: Sign, slice: &[u32]) -> BigInt { |
599 | 0 | BigInt::from_biguint(sign, BigUint::from_slice(slice)) |
600 | 0 | } |
601 | | |
602 | | /// Reinitializes a [`BigInt`]. |
603 | | /// |
604 | | /// The base 2<sup>32</sup> digits are ordered least significant digit first. |
605 | | #[inline] |
606 | 0 | pub fn assign_from_slice(&mut self, sign: Sign, slice: &[u32]) { |
607 | 0 | if sign == NoSign { |
608 | 0 | self.set_zero(); |
609 | 0 | } else { |
610 | 0 | self.data.assign_from_slice(slice); |
611 | 0 | self.sign = if self.data.is_zero() { NoSign } else { sign }; |
612 | | } |
613 | 0 | } |
614 | | |
615 | | /// Creates and initializes a [`BigInt`]. |
616 | | /// |
617 | | /// The bytes are in big-endian byte order. |
618 | | /// |
619 | | /// # Examples |
620 | | /// |
621 | | /// ``` |
622 | | /// use num_bigint::{BigInt, Sign}; |
623 | | /// |
624 | | /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"A"), |
625 | | /// BigInt::parse_bytes(b"65", 10).unwrap()); |
626 | | /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"AA"), |
627 | | /// BigInt::parse_bytes(b"16705", 10).unwrap()); |
628 | | /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"AB"), |
629 | | /// BigInt::parse_bytes(b"16706", 10).unwrap()); |
630 | | /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"Hello world!"), |
631 | | /// BigInt::parse_bytes(b"22405534230753963835153736737", 10).unwrap()); |
632 | | /// ``` |
633 | | #[inline] |
634 | 0 | pub fn from_bytes_be(sign: Sign, bytes: &[u8]) -> BigInt { |
635 | 0 | BigInt::from_biguint(sign, BigUint::from_bytes_be(bytes)) |
636 | 0 | } |
637 | | |
638 | | /// Creates and initializes a [`BigInt`]. |
639 | | /// |
640 | | /// The bytes are in little-endian byte order. |
641 | | #[inline] |
642 | 0 | pub fn from_bytes_le(sign: Sign, bytes: &[u8]) -> BigInt { |
643 | 0 | BigInt::from_biguint(sign, BigUint::from_bytes_le(bytes)) |
644 | 0 | } |
645 | | |
646 | | /// Creates and initializes a [`BigInt`] from an array of bytes in |
647 | | /// two's complement binary representation. |
648 | | /// |
649 | | /// The digits are in big-endian base 2<sup>8</sup>. |
650 | | #[inline] |
651 | 0 | pub fn from_signed_bytes_be(digits: &[u8]) -> BigInt { |
652 | 0 | convert::from_signed_bytes_be(digits) |
653 | 0 | } |
654 | | |
655 | | /// Creates and initializes a [`BigInt`] from an array of bytes in two's complement. |
656 | | /// |
657 | | /// The digits are in little-endian base 2<sup>8</sup>. |
658 | | #[inline] |
659 | 0 | pub fn from_signed_bytes_le(digits: &[u8]) -> BigInt { |
660 | 0 | convert::from_signed_bytes_le(digits) |
661 | 0 | } |
662 | | |
663 | | /// Creates and initializes a [`BigInt`]. |
664 | | /// |
665 | | /// # Examples |
666 | | /// |
667 | | /// ``` |
668 | | /// use num_bigint::{BigInt, ToBigInt}; |
669 | | /// |
670 | | /// assert_eq!(BigInt::parse_bytes(b"1234", 10), ToBigInt::to_bigint(&1234)); |
671 | | /// assert_eq!(BigInt::parse_bytes(b"ABCD", 16), ToBigInt::to_bigint(&0xABCD)); |
672 | | /// assert_eq!(BigInt::parse_bytes(b"G", 16), None); |
673 | | /// ``` |
674 | | #[inline] |
675 | 19.7k | pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigInt> { |
676 | 19.7k | let s = str::from_utf8(buf).ok()?; |
677 | 19.7k | BigInt::from_str_radix(s, radix).ok() |
678 | 19.7k | } <num_bigint::bigint::BigInt>::parse_bytes Line | Count | Source | 675 | 19.7k | pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigInt> { | 676 | 19.7k | let s = str::from_utf8(buf).ok()?; | 677 | 19.7k | BigInt::from_str_radix(s, radix).ok() | 678 | 19.7k | } |
Unexecuted instantiation: <num_bigint::bigint::BigInt>::parse_bytes |
679 | | |
680 | | /// Creates and initializes a [`BigInt`]. Each `u8` of the input slice is |
681 | | /// interpreted as one digit of the number |
682 | | /// and must therefore be less than `radix`. |
683 | | /// |
684 | | /// The bytes are in big-endian byte order. |
685 | | /// `radix` must be in the range `2...256`. |
686 | | /// |
687 | | /// # Examples |
688 | | /// |
689 | | /// ``` |
690 | | /// use num_bigint::{BigInt, Sign}; |
691 | | /// |
692 | | /// let inbase190 = vec![15, 33, 125, 12, 14]; |
693 | | /// let a = BigInt::from_radix_be(Sign::Minus, &inbase190, 190).unwrap(); |
694 | | /// assert_eq!(a.to_radix_be(190), (Sign:: Minus, inbase190)); |
695 | | /// ``` |
696 | 0 | pub fn from_radix_be(sign: Sign, buf: &[u8], radix: u32) -> Option<BigInt> { |
697 | 0 | let u = BigUint::from_radix_be(buf, radix)?; |
698 | 0 | Some(BigInt::from_biguint(sign, u)) |
699 | 0 | } |
700 | | |
701 | | /// Creates and initializes a [`BigInt`]. Each `u8` of the input slice is |
702 | | /// interpreted as one digit of the number |
703 | | /// and must therefore be less than `radix`. |
704 | | /// |
705 | | /// The bytes are in little-endian byte order. |
706 | | /// `radix` must be in the range `2...256`. |
707 | | /// |
708 | | /// # Examples |
709 | | /// |
710 | | /// ``` |
711 | | /// use num_bigint::{BigInt, Sign}; |
712 | | /// |
713 | | /// let inbase190 = vec![14, 12, 125, 33, 15]; |
714 | | /// let a = BigInt::from_radix_be(Sign::Minus, &inbase190, 190).unwrap(); |
715 | | /// assert_eq!(a.to_radix_be(190), (Sign::Minus, inbase190)); |
716 | | /// ``` |
717 | 0 | pub fn from_radix_le(sign: Sign, buf: &[u8], radix: u32) -> Option<BigInt> { |
718 | 0 | let u = BigUint::from_radix_le(buf, radix)?; |
719 | 0 | Some(BigInt::from_biguint(sign, u)) |
720 | 0 | } |
721 | | |
722 | | /// Returns the sign and the byte representation of the [`BigInt`] in big-endian byte order. |
723 | | /// |
724 | | /// # Examples |
725 | | /// |
726 | | /// ``` |
727 | | /// use num_bigint::{ToBigInt, Sign}; |
728 | | /// |
729 | | /// let i = -1125.to_bigint().unwrap(); |
730 | | /// assert_eq!(i.to_bytes_be(), (Sign::Minus, vec![4, 101])); |
731 | | /// ``` |
732 | | #[inline] |
733 | 0 | pub fn to_bytes_be(&self) -> (Sign, Vec<u8>) { |
734 | 0 | (self.sign, self.data.to_bytes_be()) |
735 | 0 | } |
736 | | |
737 | | /// Returns the sign and the byte representation of the [`BigInt`] in little-endian byte order. |
738 | | /// |
739 | | /// # Examples |
740 | | /// |
741 | | /// ``` |
742 | | /// use num_bigint::{ToBigInt, Sign}; |
743 | | /// |
744 | | /// let i = -1125.to_bigint().unwrap(); |
745 | | /// assert_eq!(i.to_bytes_le(), (Sign::Minus, vec![101, 4])); |
746 | | /// ``` |
747 | | #[inline] |
748 | 0 | pub fn to_bytes_le(&self) -> (Sign, Vec<u8>) { |
749 | 0 | (self.sign, self.data.to_bytes_le()) |
750 | 0 | } |
751 | | |
752 | | /// Returns the sign and the `u32` digits representation of the [`BigInt`] ordered least |
753 | | /// significant digit first. |
754 | | /// |
755 | | /// # Examples |
756 | | /// |
757 | | /// ``` |
758 | | /// use num_bigint::{BigInt, Sign}; |
759 | | /// |
760 | | /// assert_eq!(BigInt::from(-1125).to_u32_digits(), (Sign::Minus, vec![1125])); |
761 | | /// assert_eq!(BigInt::from(4294967295u32).to_u32_digits(), (Sign::Plus, vec![4294967295])); |
762 | | /// assert_eq!(BigInt::from(4294967296u64).to_u32_digits(), (Sign::Plus, vec![0, 1])); |
763 | | /// assert_eq!(BigInt::from(-112500000000i64).to_u32_digits(), (Sign::Minus, vec![830850304, 26])); |
764 | | /// assert_eq!(BigInt::from(112500000000i64).to_u32_digits(), (Sign::Plus, vec![830850304, 26])); |
765 | | /// ``` |
766 | | #[inline] |
767 | 0 | pub fn to_u32_digits(&self) -> (Sign, Vec<u32>) { |
768 | 0 | (self.sign, self.data.to_u32_digits()) |
769 | 0 | } |
770 | | |
771 | | /// Returns the sign and the `u64` digits representation of the [`BigInt`] ordered least |
772 | | /// significant digit first. |
773 | | /// |
774 | | /// # Examples |
775 | | /// |
776 | | /// ``` |
777 | | /// use num_bigint::{BigInt, Sign}; |
778 | | /// |
779 | | /// assert_eq!(BigInt::from(-1125).to_u64_digits(), (Sign::Minus, vec![1125])); |
780 | | /// assert_eq!(BigInt::from(4294967295u32).to_u64_digits(), (Sign::Plus, vec![4294967295])); |
781 | | /// assert_eq!(BigInt::from(4294967296u64).to_u64_digits(), (Sign::Plus, vec![4294967296])); |
782 | | /// assert_eq!(BigInt::from(-112500000000i64).to_u64_digits(), (Sign::Minus, vec![112500000000])); |
783 | | /// assert_eq!(BigInt::from(112500000000i64).to_u64_digits(), (Sign::Plus, vec![112500000000])); |
784 | | /// assert_eq!(BigInt::from(1u128 << 64).to_u64_digits(), (Sign::Plus, vec![0, 1])); |
785 | | /// ``` |
786 | | #[inline] |
787 | 0 | pub fn to_u64_digits(&self) -> (Sign, Vec<u64>) { |
788 | 0 | (self.sign, self.data.to_u64_digits()) |
789 | 0 | } |
790 | | |
791 | | /// Returns an iterator of `u32` digits representation of the [`BigInt`] ordered least |
792 | | /// significant digit first. |
793 | | /// |
794 | | /// # Examples |
795 | | /// |
796 | | /// ``` |
797 | | /// use num_bigint::BigInt; |
798 | | /// |
799 | | /// assert_eq!(BigInt::from(-1125).iter_u32_digits().collect::<Vec<u32>>(), vec![1125]); |
800 | | /// assert_eq!(BigInt::from(4294967295u32).iter_u32_digits().collect::<Vec<u32>>(), vec![4294967295]); |
801 | | /// assert_eq!(BigInt::from(4294967296u64).iter_u32_digits().collect::<Vec<u32>>(), vec![0, 1]); |
802 | | /// assert_eq!(BigInt::from(-112500000000i64).iter_u32_digits().collect::<Vec<u32>>(), vec![830850304, 26]); |
803 | | /// assert_eq!(BigInt::from(112500000000i64).iter_u32_digits().collect::<Vec<u32>>(), vec![830850304, 26]); |
804 | | /// ``` |
805 | | #[inline] |
806 | 0 | pub fn iter_u32_digits(&self) -> U32Digits<'_> { |
807 | 0 | self.data.iter_u32_digits() |
808 | 0 | } |
809 | | |
810 | | /// Returns an iterator of `u64` digits representation of the [`BigInt`] ordered least |
811 | | /// significant digit first. |
812 | | /// |
813 | | /// # Examples |
814 | | /// |
815 | | /// ``` |
816 | | /// use num_bigint::BigInt; |
817 | | /// |
818 | | /// assert_eq!(BigInt::from(-1125).iter_u64_digits().collect::<Vec<u64>>(), vec![1125u64]); |
819 | | /// assert_eq!(BigInt::from(4294967295u32).iter_u64_digits().collect::<Vec<u64>>(), vec![4294967295u64]); |
820 | | /// assert_eq!(BigInt::from(4294967296u64).iter_u64_digits().collect::<Vec<u64>>(), vec![4294967296u64]); |
821 | | /// assert_eq!(BigInt::from(-112500000000i64).iter_u64_digits().collect::<Vec<u64>>(), vec![112500000000u64]); |
822 | | /// assert_eq!(BigInt::from(112500000000i64).iter_u64_digits().collect::<Vec<u64>>(), vec![112500000000u64]); |
823 | | /// assert_eq!(BigInt::from(1u128 << 64).iter_u64_digits().collect::<Vec<u64>>(), vec![0, 1]); |
824 | | /// ``` |
825 | | #[inline] |
826 | 0 | pub fn iter_u64_digits(&self) -> U64Digits<'_> { |
827 | 0 | self.data.iter_u64_digits() |
828 | 0 | } |
829 | | |
830 | | /// Returns the two's-complement byte representation of the [`BigInt`] in big-endian byte order. |
831 | | /// |
832 | | /// # Examples |
833 | | /// |
834 | | /// ``` |
835 | | /// use num_bigint::ToBigInt; |
836 | | /// |
837 | | /// let i = -1125.to_bigint().unwrap(); |
838 | | /// assert_eq!(i.to_signed_bytes_be(), vec![251, 155]); |
839 | | /// ``` |
840 | | #[inline] |
841 | 0 | pub fn to_signed_bytes_be(&self) -> Vec<u8> { |
842 | 0 | convert::to_signed_bytes_be(self) |
843 | 0 | } |
844 | | |
845 | | /// Returns the two's-complement byte representation of the [`BigInt`] in little-endian byte order. |
846 | | /// |
847 | | /// # Examples |
848 | | /// |
849 | | /// ``` |
850 | | /// use num_bigint::ToBigInt; |
851 | | /// |
852 | | /// let i = -1125.to_bigint().unwrap(); |
853 | | /// assert_eq!(i.to_signed_bytes_le(), vec![155, 251]); |
854 | | /// ``` |
855 | | #[inline] |
856 | 0 | pub fn to_signed_bytes_le(&self) -> Vec<u8> { |
857 | 0 | convert::to_signed_bytes_le(self) |
858 | 0 | } |
859 | | |
860 | | /// Returns the integer formatted as a string in the given radix. |
861 | | /// `radix` must be in the range `2...36`. |
862 | | /// |
863 | | /// # Examples |
864 | | /// |
865 | | /// ``` |
866 | | /// use num_bigint::BigInt; |
867 | | /// |
868 | | /// let i = BigInt::parse_bytes(b"ff", 16).unwrap(); |
869 | | /// assert_eq!(i.to_str_radix(16), "ff"); |
870 | | /// ``` |
871 | | #[inline] |
872 | 0 | pub fn to_str_radix(&self, radix: u32) -> String { |
873 | 0 | let mut v = to_str_radix_reversed(&self.data, radix); |
874 | | |
875 | 0 | if self.is_negative() { |
876 | 0 | v.push(b'-'); |
877 | 0 | } |
878 | | |
879 | 0 | v.reverse(); |
880 | 0 | unsafe { String::from_utf8_unchecked(v) } |
881 | 0 | } |
882 | | |
883 | | /// Returns the integer in the requested base in big-endian digit order. |
884 | | /// The output is not given in a human readable alphabet but as a zero |
885 | | /// based `u8` number. |
886 | | /// `radix` must be in the range `2...256`. |
887 | | /// |
888 | | /// # Examples |
889 | | /// |
890 | | /// ``` |
891 | | /// use num_bigint::{BigInt, Sign}; |
892 | | /// |
893 | | /// assert_eq!(BigInt::from(-0xFFFFi64).to_radix_be(159), |
894 | | /// (Sign::Minus, vec![2, 94, 27])); |
895 | | /// // 0xFFFF = 65535 = 2*(159^2) + 94*159 + 27 |
896 | | /// ``` |
897 | | #[inline] |
898 | 0 | pub fn to_radix_be(&self, radix: u32) -> (Sign, Vec<u8>) { |
899 | 0 | (self.sign, self.data.to_radix_be(radix)) |
900 | 0 | } |
901 | | |
902 | | /// Returns the integer in the requested base in little-endian digit order. |
903 | | /// The output is not given in a human readable alphabet but as a zero |
904 | | /// based `u8` number. |
905 | | /// `radix` must be in the range `2...256`. |
906 | | /// |
907 | | /// # Examples |
908 | | /// |
909 | | /// ``` |
910 | | /// use num_bigint::{BigInt, Sign}; |
911 | | /// |
912 | | /// assert_eq!(BigInt::from(-0xFFFFi64).to_radix_le(159), |
913 | | /// (Sign::Minus, vec![27, 94, 2])); |
914 | | /// // 0xFFFF = 65535 = 27 + 94*159 + 2*(159^2) |
915 | | /// ``` |
916 | | #[inline] |
917 | 0 | pub fn to_radix_le(&self, radix: u32) -> (Sign, Vec<u8>) { |
918 | 0 | (self.sign, self.data.to_radix_le(radix)) |
919 | 0 | } |
920 | | |
921 | | /// Returns the sign of the [`BigInt`] as a [`Sign`]. |
922 | | /// |
923 | | /// # Examples |
924 | | /// |
925 | | /// ``` |
926 | | /// use num_bigint::{BigInt, Sign}; |
927 | | /// |
928 | | /// assert_eq!(BigInt::from(1234).sign(), Sign::Plus); |
929 | | /// assert_eq!(BigInt::from(-4321).sign(), Sign::Minus); |
930 | | /// assert_eq!(BigInt::ZERO.sign(), Sign::NoSign); |
931 | | /// ``` |
932 | | #[inline] |
933 | 0 | pub fn sign(&self) -> Sign { |
934 | 0 | self.sign |
935 | 0 | } |
936 | | |
937 | | /// Returns the magnitude of the [`BigInt`] as a [`BigUint`]. |
938 | | /// |
939 | | /// # Examples |
940 | | /// |
941 | | /// ``` |
942 | | /// use num_bigint::{BigInt, BigUint}; |
943 | | /// use num_traits::Zero; |
944 | | /// |
945 | | /// assert_eq!(BigInt::from(1234).magnitude(), &BigUint::from(1234u32)); |
946 | | /// assert_eq!(BigInt::from(-4321).magnitude(), &BigUint::from(4321u32)); |
947 | | /// assert!(BigInt::ZERO.magnitude().is_zero()); |
948 | | /// ``` |
949 | | #[inline] |
950 | 0 | pub fn magnitude(&self) -> &BigUint { |
951 | 0 | &self.data |
952 | 0 | } |
953 | | |
954 | | /// Convert this [`BigInt`] into its [`Sign`] and [`BigUint`] magnitude, |
955 | | /// the reverse of [`BigInt::from_biguint()`]. |
956 | | /// |
957 | | /// # Examples |
958 | | /// |
959 | | /// ``` |
960 | | /// use num_bigint::{BigInt, BigUint, Sign}; |
961 | | /// |
962 | | /// assert_eq!(BigInt::from(1234).into_parts(), (Sign::Plus, BigUint::from(1234u32))); |
963 | | /// assert_eq!(BigInt::from(-4321).into_parts(), (Sign::Minus, BigUint::from(4321u32))); |
964 | | /// assert_eq!(BigInt::ZERO.into_parts(), (Sign::NoSign, BigUint::ZERO)); |
965 | | /// ``` |
966 | | #[inline] |
967 | 0 | pub fn into_parts(self) -> (Sign, BigUint) { |
968 | 0 | (self.sign, self.data) |
969 | 0 | } |
970 | | |
971 | | /// Determines the fewest bits necessary to express the [`BigInt`], |
972 | | /// not including the sign. |
973 | | #[inline] |
974 | 0 | pub fn bits(&self) -> u64 { |
975 | 0 | self.data.bits() |
976 | 0 | } |
977 | | |
978 | | /// Converts this [`BigInt`] into a [`BigUint`], if it's not negative. |
979 | | #[inline] |
980 | 0 | pub fn to_biguint(&self) -> Option<BigUint> { |
981 | 0 | match self.sign { |
982 | 0 | Plus => Some(self.data.clone()), |
983 | 0 | NoSign => Some(BigUint::ZERO), |
984 | 0 | Minus => None, |
985 | | } |
986 | 0 | } |
987 | | |
988 | | #[inline] |
989 | 0 | pub fn checked_add(&self, v: &BigInt) -> Option<BigInt> { |
990 | 0 | Some(self + v) |
991 | 0 | } |
992 | | |
993 | | #[inline] |
994 | 0 | pub fn checked_sub(&self, v: &BigInt) -> Option<BigInt> { |
995 | 0 | Some(self - v) |
996 | 0 | } |
997 | | |
998 | | #[inline] |
999 | 0 | pub fn checked_mul(&self, v: &BigInt) -> Option<BigInt> { |
1000 | 0 | Some(self * v) |
1001 | 0 | } |
1002 | | |
1003 | | #[inline] |
1004 | 0 | pub fn checked_div(&self, v: &BigInt) -> Option<BigInt> { |
1005 | 0 | if v.is_zero() { |
1006 | 0 | return None; |
1007 | 0 | } |
1008 | 0 | Some(self / v) |
1009 | 0 | } |
1010 | | |
1011 | | /// Returns `self ^ exponent`. |
1012 | 0 | pub fn pow(&self, exponent: u32) -> Self { |
1013 | 0 | Pow::pow(self, exponent) |
1014 | 0 | } |
1015 | | |
1016 | | /// Returns `(self ^ exponent) mod modulus` |
1017 | | /// |
1018 | | /// Note that this rounds like `mod_floor`, not like the `%` operator, |
1019 | | /// which makes a difference when given a negative `self` or `modulus`. |
1020 | | /// The result will be in the interval `[0, modulus)` for `modulus > 0`, |
1021 | | /// or in the interval `(modulus, 0]` for `modulus < 0` |
1022 | | /// |
1023 | | /// Panics if the exponent is negative or the modulus is zero. |
1024 | 0 | pub fn modpow(&self, exponent: &Self, modulus: &Self) -> Self { |
1025 | 0 | power::modpow(self, exponent, modulus) |
1026 | 0 | } |
1027 | | |
1028 | | /// Returns the modular multiplicative inverse if it exists, otherwise `None`. |
1029 | | /// |
1030 | | /// This solves for `x` such that `self * x ≡ 1 (mod modulus)`. |
1031 | | /// Note that this rounds like `mod_floor`, not like the `%` operator, |
1032 | | /// which makes a difference when given a negative `self` or `modulus`. |
1033 | | /// The solution will be in the interval `[0, modulus)` for `modulus > 0`, |
1034 | | /// or in the interval `(modulus, 0]` for `modulus < 0`, |
1035 | | /// and it exists if and only if `gcd(self, modulus) == 1`. |
1036 | | /// |
1037 | | /// ``` |
1038 | | /// use num_bigint::BigInt; |
1039 | | /// use num_integer::Integer; |
1040 | | /// use num_traits::{One, Zero}; |
1041 | | /// |
1042 | | /// let m = BigInt::from(383); |
1043 | | /// |
1044 | | /// // Trivial cases |
1045 | | /// assert_eq!(BigInt::zero().modinv(&m), None); |
1046 | | /// assert_eq!(BigInt::one().modinv(&m), Some(BigInt::one())); |
1047 | | /// let neg1 = &m - 1u32; |
1048 | | /// assert_eq!(neg1.modinv(&m), Some(neg1)); |
1049 | | /// |
1050 | | /// // Positive self and modulus |
1051 | | /// let a = BigInt::from(271); |
1052 | | /// let x = a.modinv(&m).unwrap(); |
1053 | | /// assert_eq!(x, BigInt::from(106)); |
1054 | | /// assert_eq!(x.modinv(&m).unwrap(), a); |
1055 | | /// assert_eq!((&a * x).mod_floor(&m), BigInt::one()); |
1056 | | /// |
1057 | | /// // Negative self and positive modulus |
1058 | | /// let b = -&a; |
1059 | | /// let x = b.modinv(&m).unwrap(); |
1060 | | /// assert_eq!(x, BigInt::from(277)); |
1061 | | /// assert_eq!((&b * x).mod_floor(&m), BigInt::one()); |
1062 | | /// |
1063 | | /// // Positive self and negative modulus |
1064 | | /// let n = -&m; |
1065 | | /// let x = a.modinv(&n).unwrap(); |
1066 | | /// assert_eq!(x, BigInt::from(-277)); |
1067 | | /// assert_eq!((&a * x).mod_floor(&n), &n + 1); |
1068 | | /// |
1069 | | /// // Negative self and modulus |
1070 | | /// let x = b.modinv(&n).unwrap(); |
1071 | | /// assert_eq!(x, BigInt::from(-106)); |
1072 | | /// assert_eq!((&b * x).mod_floor(&n), &n + 1); |
1073 | | /// ``` |
1074 | 0 | pub fn modinv(&self, modulus: &Self) -> Option<Self> { |
1075 | 0 | let result = self.data.modinv(&modulus.data)?; |
1076 | | // The sign of the result follows the modulus, like `mod_floor`. |
1077 | 0 | let (sign, mag) = match (self.is_negative(), modulus.is_negative()) { |
1078 | 0 | (false, false) => (Plus, result), |
1079 | 0 | (true, false) => (Plus, &modulus.data - result), |
1080 | 0 | (false, true) => (Minus, &modulus.data - result), |
1081 | 0 | (true, true) => (Minus, result), |
1082 | | }; |
1083 | 0 | Some(BigInt::from_biguint(sign, mag)) |
1084 | 0 | } |
1085 | | |
1086 | | /// Returns the truncated principal square root of `self` -- |
1087 | | /// see [`num_integer::Roots::sqrt()`]. |
1088 | 0 | pub fn sqrt(&self) -> Self { |
1089 | 0 | Roots::sqrt(self) |
1090 | 0 | } |
1091 | | |
1092 | | /// Returns the truncated principal cube root of `self` -- |
1093 | | /// see [`num_integer::Roots::cbrt()`]. |
1094 | 0 | pub fn cbrt(&self) -> Self { |
1095 | 0 | Roots::cbrt(self) |
1096 | 0 | } |
1097 | | |
1098 | | /// Returns the truncated principal `n`th root of `self` -- |
1099 | | /// See [`num_integer::Roots::nth_root()`]. |
1100 | 0 | pub fn nth_root(&self, n: u32) -> Self { |
1101 | 0 | Roots::nth_root(self, n) |
1102 | 0 | } |
1103 | | |
1104 | | /// Returns the number of least-significant bits that are zero, |
1105 | | /// or `None` if the entire number is zero. |
1106 | 0 | pub fn trailing_zeros(&self) -> Option<u64> { |
1107 | 0 | self.data.trailing_zeros() |
1108 | 0 | } |
1109 | | |
1110 | | /// Returns whether the bit in position `bit` is set, |
1111 | | /// using the two's complement for negative numbers |
1112 | 0 | pub fn bit(&self, bit: u64) -> bool { |
1113 | 0 | if self.is_negative() { |
1114 | | // Let the binary representation of a number be |
1115 | | // ... 0 x 1 0 ... 0 |
1116 | | // Then the two's complement is |
1117 | | // ... 1 !x 1 0 ... 0 |
1118 | | // where !x is obtained from x by flipping each bit |
1119 | 0 | if bit >= u64::from(crate::big_digit::BITS) * self.len() as u64 { |
1120 | 0 | true |
1121 | | } else { |
1122 | 0 | let trailing_zeros = self.data.trailing_zeros().unwrap(); |
1123 | 0 | match Ord::cmp(&bit, &trailing_zeros) { |
1124 | 0 | Ordering::Less => false, |
1125 | 0 | Ordering::Equal => true, |
1126 | 0 | Ordering::Greater => !self.data.bit(bit), |
1127 | | } |
1128 | | } |
1129 | | } else { |
1130 | 0 | self.data.bit(bit) |
1131 | | } |
1132 | 0 | } |
1133 | | |
1134 | | /// Sets or clears the bit in the given position, |
1135 | | /// using the two's complement for negative numbers |
1136 | | /// |
1137 | | /// Note that setting/clearing a bit (for positive/negative numbers, |
1138 | | /// respectively) greater than the current bit length, a reallocation |
1139 | | /// may be needed to store the new digits |
1140 | 0 | pub fn set_bit(&mut self, bit: u64, value: bool) { |
1141 | 0 | match self.sign { |
1142 | 0 | Sign::Plus => self.data.set_bit(bit, value), |
1143 | 0 | Sign::Minus => bits::set_negative_bit(self, bit, value), |
1144 | | Sign::NoSign => { |
1145 | 0 | if value { |
1146 | 0 | self.data.set_bit(bit, true); |
1147 | 0 | self.sign = Sign::Plus; |
1148 | 0 | } else { |
1149 | 0 | // Clearing a bit for zero is a no-op |
1150 | 0 | } |
1151 | | } |
1152 | | } |
1153 | | // The top bit may have been cleared, so normalize |
1154 | 0 | self.normalize(); |
1155 | 0 | } |
1156 | | } |
1157 | | |
1158 | | impl num_traits::FromBytes for BigInt { |
1159 | | type Bytes = [u8]; |
1160 | | |
1161 | 0 | fn from_be_bytes(bytes: &Self::Bytes) -> Self { |
1162 | 0 | Self::from_signed_bytes_be(bytes) |
1163 | 0 | } |
1164 | | |
1165 | 0 | fn from_le_bytes(bytes: &Self::Bytes) -> Self { |
1166 | 0 | Self::from_signed_bytes_le(bytes) |
1167 | 0 | } |
1168 | | } |
1169 | | |
1170 | | impl num_traits::ToBytes for BigInt { |
1171 | | type Bytes = Vec<u8>; |
1172 | | |
1173 | 0 | fn to_be_bytes(&self) -> Self::Bytes { |
1174 | 0 | self.to_signed_bytes_be() |
1175 | 0 | } |
1176 | | |
1177 | 0 | fn to_le_bytes(&self) -> Self::Bytes { |
1178 | 0 | self.to_signed_bytes_le() |
1179 | 0 | } |
1180 | | } |
1181 | | |
1182 | | #[test] |
1183 | | fn test_from_biguint() { |
1184 | | fn check(inp_s: Sign, inp_n: usize, ans_s: Sign, ans_n: usize) { |
1185 | | let inp = BigInt::from_biguint(inp_s, BigUint::from(inp_n)); |
1186 | | let ans = BigInt { |
1187 | | sign: ans_s, |
1188 | | data: BigUint::from(ans_n), |
1189 | | }; |
1190 | | assert_eq!(inp, ans); |
1191 | | } |
1192 | | check(Plus, 1, Plus, 1); |
1193 | | check(Plus, 0, NoSign, 0); |
1194 | | check(Minus, 1, Minus, 1); |
1195 | | check(NoSign, 1, NoSign, 0); |
1196 | | } |
1197 | | |
1198 | | #[test] |
1199 | | fn test_from_slice() { |
1200 | | fn check(inp_s: Sign, inp_n: u32, ans_s: Sign, ans_n: u32) { |
1201 | | let inp = BigInt::from_slice(inp_s, &[inp_n]); |
1202 | | let ans = BigInt { |
1203 | | sign: ans_s, |
1204 | | data: BigUint::from(ans_n), |
1205 | | }; |
1206 | | assert_eq!(inp, ans); |
1207 | | } |
1208 | | check(Plus, 1, Plus, 1); |
1209 | | check(Plus, 0, NoSign, 0); |
1210 | | check(Minus, 1, Minus, 1); |
1211 | | check(NoSign, 1, NoSign, 0); |
1212 | | } |
1213 | | |
1214 | | #[test] |
1215 | | fn test_assign_from_slice() { |
1216 | | fn check(inp_s: Sign, inp_n: u32, ans_s: Sign, ans_n: u32) { |
1217 | | let mut inp = BigInt::from_slice(Minus, &[2627_u32, 0_u32, 9182_u32, 42_u32]); |
1218 | | inp.assign_from_slice(inp_s, &[inp_n]); |
1219 | | let ans = BigInt { |
1220 | | sign: ans_s, |
1221 | | data: BigUint::from(ans_n), |
1222 | | }; |
1223 | | assert_eq!(inp, ans); |
1224 | | } |
1225 | | check(Plus, 1, Plus, 1); |
1226 | | check(Plus, 0, NoSign, 0); |
1227 | | check(Minus, 1, Minus, 1); |
1228 | | check(NoSign, 1, NoSign, 0); |
1229 | | } |