Struct sp_arithmetic::biguint::BigUint
source · pub struct BigUint { /* private fields */ }
Expand description
Simple wrapper around an infinitely large integer, represented as limbs of Single
.
Implementations§
source§impl BigUint
impl BigUint
sourcepub fn with_capacity(size: usize) -> Self
pub fn with_capacity(size: usize) -> Self
Create a new instance with size
limbs. This prevents any number with zero limbs to be
created.
The behavior of the type is undefined with zero limbs.
Examples found in repository?
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
pub fn add(self, other: &Self) -> Self {
let n = self.len().max(other.len());
let mut k: Double = 0;
let mut w = Self::with_capacity(n + 1);
for j in 0..n {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
let s = u + v + k;
// proof: any number % B will fit into `Single`.
w.set(j, (s % B) as Single);
k = s / B;
}
// k is always 0 or 1.
w.set(n, k as Single);
w
}
/// Subtracts `other` from `self`. self and other do not have to have any particular size.
/// Given that the `n = max{size(self), size(other)}`, it will produce a number of size `n`.
///
/// If `other` is bigger than `self`, `Err(B - borrow)` is returned.
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn sub(self, other: &Self) -> Result<Self, Self> {
let n = self.len().max(other.len());
let mut k = 0;
let mut w = Self::with_capacity(n);
for j in 0..n {
let s = {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
if let Some(v2) = u.checked_sub(v).and_then(|v1| v1.checked_sub(k)) {
// no borrow is needed. u - v - k can be computed as-is
let t = v2;
k = 0;
t
} else {
// borrow is needed. Add a `B` to u, before subtracting.
// PROOF: addition: `u + B < 2*B`, thus can fit in double.
// PROOF: subtraction: if `u - v - k < 0`, then `u + B - v - k < B`.
// NOTE: the order of operations is critical to ensure underflow won't happen.
let t = u + B - v - k;
k = 1;
t
}
};
w.set(j, s as Single);
}
if k.is_zero() {
Ok(w)
} else {
Err(w)
}
}
/// Multiplies n-limb number `self` with m-limb number `other`.
///
/// The resulting number will always have `n + m` limbs.
///
/// This function does not strip the output and returns the original allocated `n + m`
/// limbs. The caller may strip the output if desired.
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn mul(self, other: &Self) -> Self {
let n = self.len();
let m = other.len();
let mut w = Self::with_capacity(m + n);
for j in 0..n {
if self.get(j) == 0 {
// Note: `with_capacity` allocates with 0. Explicitly set j + m to zero if
// otherwise.
continue
}
let mut k = 0;
for i in 0..m {
// PROOF: (B−1) × (B−1) + (B−1) + (B−1) = B^2 −1 < B^2. addition is safe.
let t = mul_single(self.get(j), other.get(i)) +
Double::from(w.get(i + j)) +
Double::from(k);
w.set(i + j, (t % B) as Single);
// PROOF: (B^2 - 1) / B < B. conversion is safe.
k = (t / B) as Single;
}
w.set(j + m, k);
}
w
}
/// Divides `self` by a single limb `other`. This can be used in cases where the original
/// division cannot work due to the divisor (`other`) being just one limb.
///
/// Invariant: `other` cannot be zero.
pub fn div_unit(self, mut other: Single) -> Self {
other = other.max(1);
let n = self.len();
let mut out = Self::with_capacity(n);
let mut r: Single = 0;
// PROOF: (B-1) * B + (B-1) still fits in double
let with_r = |x: Single, r: Single| Double::from(r) * B + Double::from(x);
for d in (0..n).rev() {
let (q, rr) = div_single(with_r(self.get(d), r), other);
out.set(d, q as Single);
r = rr;
}
out
}
/// Divides an `n + m` limb self by a `n` limb `other`. The result is a `m + 1` limb
/// quotient and a `n` limb remainder, if enabled by passing `true` in `rem` argument, both
/// in the form of an option's `Ok`.
///
/// - requires `other` to be stripped and have no leading zeros.
/// - requires `self` to be stripped and have no leading zeros.
/// - requires `other` to have at least two limbs.
/// - requires `self` to have a greater length compared to `other`.
///
/// All arguments are examined without being stripped for the above conditions. If any of
/// the above fails, `None` is returned.`
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> {
if other.len() <= 1 || other.msb() == 0 || self.msb() == 0 || self.len() <= other.len() {
return None
}
let n = other.len();
let m = self.len() - n;
let mut q = Self::with_capacity(m + 1);
let mut r = Self::with_capacity(n);
// PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are
// safe.
let normalizer_bits = other.msb().leading_zeros() as Single;
let normalizer = 2_u32.pow(normalizer_bits as u32) as Single;
// step D1.
let mut self_norm = self.mul(&Self::from(normalizer));
let mut other_norm = other.clone().mul(&Self::from(normalizer));
// defensive only; the mul implementation should always create this.
self_norm.lpad(n + m + 1);
other_norm.lstrip();
// step D2.
for j in (0..=m).rev() {
// step D3.0 Find an estimate of q[j], named qhat.
let (qhat, rhat) = {
// PROOF: this always fits into `Double`. In the context of Single = u8, and
// Double = u16, think of 255 * 256 + 255 which is just u16::MAX.
let dividend =
Double::from(self_norm.get(j + n)) * B + Double::from(self_norm.get(j + n - 1));
let divisor = other_norm.get(n - 1);
div_single(dividend, divisor)
};
// D3.1 test qhat
// replace qhat and rhat with RefCells. This helps share state with the closure
let qhat = RefCell::new(qhat);
let rhat = RefCell::new(Double::from(rhat));
let test = || {
// decrease qhat if it is bigger than the base (B)
let qhat_local = *qhat.borrow();
let rhat_local = *rhat.borrow();
let predicate_1 = qhat_local >= B;
let predicate_2 = {
let lhs = qhat_local * Double::from(other_norm.get(n - 2));
let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2));
lhs > rhs
};
if predicate_1 || predicate_2 {
*qhat.borrow_mut() -= 1;
*rhat.borrow_mut() += Double::from(other_norm.get(n - 1));
true
} else {
false
}
};
test();
while (*rhat.borrow() as Double) < B {
if !test() {
break
}
}
let qhat = qhat.into_inner();
// we don't need rhat anymore. just let it go out of scope when it does.
// step D4
let lhs = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let rhs = other_norm.clone().mul(&Self::from(qhat));
let maybe_sub = lhs.sub(&rhs);
let mut negative = false;
let sub = match maybe_sub {
Ok(t) => t,
Err(t) => {
negative = true;
t
},
};
(j..=j + n).for_each(|d| {
self_norm.set(d, sub.get(d - j));
});
// step D5
// PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion
// is safe.
q.set(j, qhat as Single);
// step D6: add back if negative happened.
if negative {
q.set(j, q.get(j) - 1);
let u = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let r = other_norm.clone().add(&u);
(j..=j + n).rev().for_each(|d| {
self_norm.set(d, r.get(d - j));
})
}
}
// if requested, calculate remainder.
if rem {
// undo the normalization.
if normalizer_bits > 0 {
let s = SHIFT as u32;
let nb = normalizer_bits;
for d in 0..n - 1 {
let v = self_norm.get(d) >> nb | self_norm.get(d + 1).overflowing_shl(s - nb).0;
r.set(d, v);
}
r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits);
} else {
r = self_norm;
}
}
Some((q, r))
}
sourcepub fn from_limbs(limbs: &[Single]) -> Self
pub fn from_limbs(limbs: &[Single]) -> Self
Raw constructor from custom limbs. If limbs
is empty, Zero::zero()
implementation is
used.
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Number of limbs.
Examples found in repository?
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 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
pub fn get(&self, index: usize) -> Single {
self.digits[self.len() - 1 - index]
}
/// A naive getter for limb at `index`. Note that the order is lsb -> msb.
pub fn checked_get(&self, index: usize) -> Option<Single> {
let i = self.len().checked_sub(1)?;
let j = i.checked_sub(index)?;
self.digits.get(j).cloned()
}
/// A naive setter for limb at `index`. Note that the order is lsb -> msb.
///
/// #### Panics
///
/// This panics if index is out of range.
pub fn set(&mut self, index: usize, value: Single) {
let len = self.digits.len();
self.digits[len - 1 - index] = value;
}
/// returns the least significant limb of the number.
///
/// #### Panics
///
/// While the constructor of the type prevents this, this can panic if `self` has no digits.
pub fn lsb(&self) -> Single {
self.digits[self.len() - 1]
}
/// returns the most significant limb of the number.
///
/// #### Panics
///
/// While the constructor of the type prevents this, this can panic if `self` has no digits.
pub fn msb(&self) -> Single {
self.digits[0]
}
/// Strips zeros from the left side (the most significant limbs) of `self`, if any.
pub fn lstrip(&mut self) {
// by definition, a big-int number should never have leading zero limbs. This function
// has the ability to cause this. There is nothing to do if the number already has 1
// limb only. call it a day and return.
if self.len().is_zero() {
return
}
let index = self.digits.iter().position(|&elem| elem != 0).unwrap_or(self.len() - 1);
if index > 0 {
self.digits = self.digits[index..].to_vec()
}
}
/// Zero-pad `self` from left to reach `size` limbs. Will not make any difference if `self`
/// is already bigger than `size` limbs.
pub fn lpad(&mut self, size: usize) {
let n = self.len();
if n >= size {
return
}
let pad = size - n;
let mut new_digits = (0..pad).map(|_| 0).collect::<Vec<Single>>();
new_digits.extend(self.digits.iter());
self.digits = new_digits;
}
/// Adds `self` with `other`. self and other do not have to have any particular size. Given
/// that the `n = max{size(self), size(other)}`, it will produce a number with `n + 1`
/// limbs.
///
/// This function does not strip the output and returns the original allocated `n + 1`
/// limbs. The caller may strip the output if desired.
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn add(self, other: &Self) -> Self {
let n = self.len().max(other.len());
let mut k: Double = 0;
let mut w = Self::with_capacity(n + 1);
for j in 0..n {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
let s = u + v + k;
// proof: any number % B will fit into `Single`.
w.set(j, (s % B) as Single);
k = s / B;
}
// k is always 0 or 1.
w.set(n, k as Single);
w
}
/// Subtracts `other` from `self`. self and other do not have to have any particular size.
/// Given that the `n = max{size(self), size(other)}`, it will produce a number of size `n`.
///
/// If `other` is bigger than `self`, `Err(B - borrow)` is returned.
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn sub(self, other: &Self) -> Result<Self, Self> {
let n = self.len().max(other.len());
let mut k = 0;
let mut w = Self::with_capacity(n);
for j in 0..n {
let s = {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
if let Some(v2) = u.checked_sub(v).and_then(|v1| v1.checked_sub(k)) {
// no borrow is needed. u - v - k can be computed as-is
let t = v2;
k = 0;
t
} else {
// borrow is needed. Add a `B` to u, before subtracting.
// PROOF: addition: `u + B < 2*B`, thus can fit in double.
// PROOF: subtraction: if `u - v - k < 0`, then `u + B - v - k < B`.
// NOTE: the order of operations is critical to ensure underflow won't happen.
let t = u + B - v - k;
k = 1;
t
}
};
w.set(j, s as Single);
}
if k.is_zero() {
Ok(w)
} else {
Err(w)
}
}
/// Multiplies n-limb number `self` with m-limb number `other`.
///
/// The resulting number will always have `n + m` limbs.
///
/// This function does not strip the output and returns the original allocated `n + m`
/// limbs. The caller may strip the output if desired.
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn mul(self, other: &Self) -> Self {
let n = self.len();
let m = other.len();
let mut w = Self::with_capacity(m + n);
for j in 0..n {
if self.get(j) == 0 {
// Note: `with_capacity` allocates with 0. Explicitly set j + m to zero if
// otherwise.
continue
}
let mut k = 0;
for i in 0..m {
// PROOF: (B−1) × (B−1) + (B−1) + (B−1) = B^2 −1 < B^2. addition is safe.
let t = mul_single(self.get(j), other.get(i)) +
Double::from(w.get(i + j)) +
Double::from(k);
w.set(i + j, (t % B) as Single);
// PROOF: (B^2 - 1) / B < B. conversion is safe.
k = (t / B) as Single;
}
w.set(j + m, k);
}
w
}
/// Divides `self` by a single limb `other`. This can be used in cases where the original
/// division cannot work due to the divisor (`other`) being just one limb.
///
/// Invariant: `other` cannot be zero.
pub fn div_unit(self, mut other: Single) -> Self {
other = other.max(1);
let n = self.len();
let mut out = Self::with_capacity(n);
let mut r: Single = 0;
// PROOF: (B-1) * B + (B-1) still fits in double
let with_r = |x: Single, r: Single| Double::from(r) * B + Double::from(x);
for d in (0..n).rev() {
let (q, rr) = div_single(with_r(self.get(d), r), other);
out.set(d, q as Single);
r = rr;
}
out
}
/// Divides an `n + m` limb self by a `n` limb `other`. The result is a `m + 1` limb
/// quotient and a `n` limb remainder, if enabled by passing `true` in `rem` argument, both
/// in the form of an option's `Ok`.
///
/// - requires `other` to be stripped and have no leading zeros.
/// - requires `self` to be stripped and have no leading zeros.
/// - requires `other` to have at least two limbs.
/// - requires `self` to have a greater length compared to `other`.
///
/// All arguments are examined without being stripped for the above conditions. If any of
/// the above fails, `None` is returned.`
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> {
if other.len() <= 1 || other.msb() == 0 || self.msb() == 0 || self.len() <= other.len() {
return None
}
let n = other.len();
let m = self.len() - n;
let mut q = Self::with_capacity(m + 1);
let mut r = Self::with_capacity(n);
// PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are
// safe.
let normalizer_bits = other.msb().leading_zeros() as Single;
let normalizer = 2_u32.pow(normalizer_bits as u32) as Single;
// step D1.
let mut self_norm = self.mul(&Self::from(normalizer));
let mut other_norm = other.clone().mul(&Self::from(normalizer));
// defensive only; the mul implementation should always create this.
self_norm.lpad(n + m + 1);
other_norm.lstrip();
// step D2.
for j in (0..=m).rev() {
// step D3.0 Find an estimate of q[j], named qhat.
let (qhat, rhat) = {
// PROOF: this always fits into `Double`. In the context of Single = u8, and
// Double = u16, think of 255 * 256 + 255 which is just u16::MAX.
let dividend =
Double::from(self_norm.get(j + n)) * B + Double::from(self_norm.get(j + n - 1));
let divisor = other_norm.get(n - 1);
div_single(dividend, divisor)
};
// D3.1 test qhat
// replace qhat and rhat with RefCells. This helps share state with the closure
let qhat = RefCell::new(qhat);
let rhat = RefCell::new(Double::from(rhat));
let test = || {
// decrease qhat if it is bigger than the base (B)
let qhat_local = *qhat.borrow();
let rhat_local = *rhat.borrow();
let predicate_1 = qhat_local >= B;
let predicate_2 = {
let lhs = qhat_local * Double::from(other_norm.get(n - 2));
let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2));
lhs > rhs
};
if predicate_1 || predicate_2 {
*qhat.borrow_mut() -= 1;
*rhat.borrow_mut() += Double::from(other_norm.get(n - 1));
true
} else {
false
}
};
test();
while (*rhat.borrow() as Double) < B {
if !test() {
break
}
}
let qhat = qhat.into_inner();
// we don't need rhat anymore. just let it go out of scope when it does.
// step D4
let lhs = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let rhs = other_norm.clone().mul(&Self::from(qhat));
let maybe_sub = lhs.sub(&rhs);
let mut negative = false;
let sub = match maybe_sub {
Ok(t) => t,
Err(t) => {
negative = true;
t
},
};
(j..=j + n).for_each(|d| {
self_norm.set(d, sub.get(d - j));
});
// step D5
// PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion
// is safe.
q.set(j, qhat as Single);
// step D6: add back if negative happened.
if negative {
q.set(j, q.get(j) - 1);
let u = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let r = other_norm.clone().add(&u);
(j..=j + n).rev().for_each(|d| {
self_norm.set(d, r.get(d - j));
})
}
}
// if requested, calculate remainder.
if rem {
// undo the normalization.
if normalizer_bits > 0 {
let s = SHIFT as u32;
let nb = normalizer_bits;
for d in 0..n - 1 {
let v = self_norm.get(d) >> nb | self_norm.get(d + 1).overflowing_shl(s - nb).0;
r.set(d, v);
}
r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits);
} else {
r = self_norm;
}
}
Some((q, r))
}
sourcepub fn get(&self, index: usize) -> Single
pub fn get(&self, index: usize) -> Single
A naive getter for limb at index
. Note that the order is lsb -> msb.
Panics
This panics if index is out of range.
Examples found in repository?
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
pub fn mul(self, other: &Self) -> Self {
let n = self.len();
let m = other.len();
let mut w = Self::with_capacity(m + n);
for j in 0..n {
if self.get(j) == 0 {
// Note: `with_capacity` allocates with 0. Explicitly set j + m to zero if
// otherwise.
continue
}
let mut k = 0;
for i in 0..m {
// PROOF: (B−1) × (B−1) + (B−1) + (B−1) = B^2 −1 < B^2. addition is safe.
let t = mul_single(self.get(j), other.get(i)) +
Double::from(w.get(i + j)) +
Double::from(k);
w.set(i + j, (t % B) as Single);
// PROOF: (B^2 - 1) / B < B. conversion is safe.
k = (t / B) as Single;
}
w.set(j + m, k);
}
w
}
/// Divides `self` by a single limb `other`. This can be used in cases where the original
/// division cannot work due to the divisor (`other`) being just one limb.
///
/// Invariant: `other` cannot be zero.
pub fn div_unit(self, mut other: Single) -> Self {
other = other.max(1);
let n = self.len();
let mut out = Self::with_capacity(n);
let mut r: Single = 0;
// PROOF: (B-1) * B + (B-1) still fits in double
let with_r = |x: Single, r: Single| Double::from(r) * B + Double::from(x);
for d in (0..n).rev() {
let (q, rr) = div_single(with_r(self.get(d), r), other);
out.set(d, q as Single);
r = rr;
}
out
}
/// Divides an `n + m` limb self by a `n` limb `other`. The result is a `m + 1` limb
/// quotient and a `n` limb remainder, if enabled by passing `true` in `rem` argument, both
/// in the form of an option's `Ok`.
///
/// - requires `other` to be stripped and have no leading zeros.
/// - requires `self` to be stripped and have no leading zeros.
/// - requires `other` to have at least two limbs.
/// - requires `self` to have a greater length compared to `other`.
///
/// All arguments are examined without being stripped for the above conditions. If any of
/// the above fails, `None` is returned.`
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> {
if other.len() <= 1 || other.msb() == 0 || self.msb() == 0 || self.len() <= other.len() {
return None
}
let n = other.len();
let m = self.len() - n;
let mut q = Self::with_capacity(m + 1);
let mut r = Self::with_capacity(n);
// PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are
// safe.
let normalizer_bits = other.msb().leading_zeros() as Single;
let normalizer = 2_u32.pow(normalizer_bits as u32) as Single;
// step D1.
let mut self_norm = self.mul(&Self::from(normalizer));
let mut other_norm = other.clone().mul(&Self::from(normalizer));
// defensive only; the mul implementation should always create this.
self_norm.lpad(n + m + 1);
other_norm.lstrip();
// step D2.
for j in (0..=m).rev() {
// step D3.0 Find an estimate of q[j], named qhat.
let (qhat, rhat) = {
// PROOF: this always fits into `Double`. In the context of Single = u8, and
// Double = u16, think of 255 * 256 + 255 which is just u16::MAX.
let dividend =
Double::from(self_norm.get(j + n)) * B + Double::from(self_norm.get(j + n - 1));
let divisor = other_norm.get(n - 1);
div_single(dividend, divisor)
};
// D3.1 test qhat
// replace qhat and rhat with RefCells. This helps share state with the closure
let qhat = RefCell::new(qhat);
let rhat = RefCell::new(Double::from(rhat));
let test = || {
// decrease qhat if it is bigger than the base (B)
let qhat_local = *qhat.borrow();
let rhat_local = *rhat.borrow();
let predicate_1 = qhat_local >= B;
let predicate_2 = {
let lhs = qhat_local * Double::from(other_norm.get(n - 2));
let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2));
lhs > rhs
};
if predicate_1 || predicate_2 {
*qhat.borrow_mut() -= 1;
*rhat.borrow_mut() += Double::from(other_norm.get(n - 1));
true
} else {
false
}
};
test();
while (*rhat.borrow() as Double) < B {
if !test() {
break
}
}
let qhat = qhat.into_inner();
// we don't need rhat anymore. just let it go out of scope when it does.
// step D4
let lhs = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let rhs = other_norm.clone().mul(&Self::from(qhat));
let maybe_sub = lhs.sub(&rhs);
let mut negative = false;
let sub = match maybe_sub {
Ok(t) => t,
Err(t) => {
negative = true;
t
},
};
(j..=j + n).for_each(|d| {
self_norm.set(d, sub.get(d - j));
});
// step D5
// PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion
// is safe.
q.set(j, qhat as Single);
// step D6: add back if negative happened.
if negative {
q.set(j, q.get(j) - 1);
let u = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let r = other_norm.clone().add(&u);
(j..=j + n).rev().for_each(|d| {
self_norm.set(d, r.get(d - j));
})
}
}
// if requested, calculate remainder.
if rem {
// undo the normalization.
if normalizer_bits > 0 {
let s = SHIFT as u32;
let nb = normalizer_bits;
for d in 0..n - 1 {
let v = self_norm.get(d) >> nb | self_norm.get(d + 1).overflowing_shl(s - nb).0;
r.set(d, v);
}
r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits);
} else {
r = self_norm;
}
}
Some((q, r))
}
sourcepub fn checked_get(&self, index: usize) -> Option<Single>
pub fn checked_get(&self, index: usize) -> Option<Single>
A naive getter for limb at index
. Note that the order is lsb -> msb.
Examples found in repository?
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
pub fn add(self, other: &Self) -> Self {
let n = self.len().max(other.len());
let mut k: Double = 0;
let mut w = Self::with_capacity(n + 1);
for j in 0..n {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
let s = u + v + k;
// proof: any number % B will fit into `Single`.
w.set(j, (s % B) as Single);
k = s / B;
}
// k is always 0 or 1.
w.set(n, k as Single);
w
}
/// Subtracts `other` from `self`. self and other do not have to have any particular size.
/// Given that the `n = max{size(self), size(other)}`, it will produce a number of size `n`.
///
/// If `other` is bigger than `self`, `Err(B - borrow)` is returned.
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn sub(self, other: &Self) -> Result<Self, Self> {
let n = self.len().max(other.len());
let mut k = 0;
let mut w = Self::with_capacity(n);
for j in 0..n {
let s = {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
if let Some(v2) = u.checked_sub(v).and_then(|v1| v1.checked_sub(k)) {
// no borrow is needed. u - v - k can be computed as-is
let t = v2;
k = 0;
t
} else {
// borrow is needed. Add a `B` to u, before subtracting.
// PROOF: addition: `u + B < 2*B`, thus can fit in double.
// PROOF: subtraction: if `u - v - k < 0`, then `u + B - v - k < B`.
// NOTE: the order of operations is critical to ensure underflow won't happen.
let t = u + B - v - k;
k = 1;
t
}
};
w.set(j, s as Single);
}
if k.is_zero() {
Ok(w)
} else {
Err(w)
}
}
sourcepub fn set(&mut self, index: usize, value: Single)
pub fn set(&mut self, index: usize, value: Single)
A naive setter for limb at index
. Note that the order is lsb -> msb.
Panics
This panics if index is out of range.
Examples found in repository?
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
pub fn add(self, other: &Self) -> Self {
let n = self.len().max(other.len());
let mut k: Double = 0;
let mut w = Self::with_capacity(n + 1);
for j in 0..n {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
let s = u + v + k;
// proof: any number % B will fit into `Single`.
w.set(j, (s % B) as Single);
k = s / B;
}
// k is always 0 or 1.
w.set(n, k as Single);
w
}
/// Subtracts `other` from `self`. self and other do not have to have any particular size.
/// Given that the `n = max{size(self), size(other)}`, it will produce a number of size `n`.
///
/// If `other` is bigger than `self`, `Err(B - borrow)` is returned.
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn sub(self, other: &Self) -> Result<Self, Self> {
let n = self.len().max(other.len());
let mut k = 0;
let mut w = Self::with_capacity(n);
for j in 0..n {
let s = {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
if let Some(v2) = u.checked_sub(v).and_then(|v1| v1.checked_sub(k)) {
// no borrow is needed. u - v - k can be computed as-is
let t = v2;
k = 0;
t
} else {
// borrow is needed. Add a `B` to u, before subtracting.
// PROOF: addition: `u + B < 2*B`, thus can fit in double.
// PROOF: subtraction: if `u - v - k < 0`, then `u + B - v - k < B`.
// NOTE: the order of operations is critical to ensure underflow won't happen.
let t = u + B - v - k;
k = 1;
t
}
};
w.set(j, s as Single);
}
if k.is_zero() {
Ok(w)
} else {
Err(w)
}
}
/// Multiplies n-limb number `self` with m-limb number `other`.
///
/// The resulting number will always have `n + m` limbs.
///
/// This function does not strip the output and returns the original allocated `n + m`
/// limbs. The caller may strip the output if desired.
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn mul(self, other: &Self) -> Self {
let n = self.len();
let m = other.len();
let mut w = Self::with_capacity(m + n);
for j in 0..n {
if self.get(j) == 0 {
// Note: `with_capacity` allocates with 0. Explicitly set j + m to zero if
// otherwise.
continue
}
let mut k = 0;
for i in 0..m {
// PROOF: (B−1) × (B−1) + (B−1) + (B−1) = B^2 −1 < B^2. addition is safe.
let t = mul_single(self.get(j), other.get(i)) +
Double::from(w.get(i + j)) +
Double::from(k);
w.set(i + j, (t % B) as Single);
// PROOF: (B^2 - 1) / B < B. conversion is safe.
k = (t / B) as Single;
}
w.set(j + m, k);
}
w
}
/// Divides `self` by a single limb `other`. This can be used in cases where the original
/// division cannot work due to the divisor (`other`) being just one limb.
///
/// Invariant: `other` cannot be zero.
pub fn div_unit(self, mut other: Single) -> Self {
other = other.max(1);
let n = self.len();
let mut out = Self::with_capacity(n);
let mut r: Single = 0;
// PROOF: (B-1) * B + (B-1) still fits in double
let with_r = |x: Single, r: Single| Double::from(r) * B + Double::from(x);
for d in (0..n).rev() {
let (q, rr) = div_single(with_r(self.get(d), r), other);
out.set(d, q as Single);
r = rr;
}
out
}
/// Divides an `n + m` limb self by a `n` limb `other`. The result is a `m + 1` limb
/// quotient and a `n` limb remainder, if enabled by passing `true` in `rem` argument, both
/// in the form of an option's `Ok`.
///
/// - requires `other` to be stripped and have no leading zeros.
/// - requires `self` to be stripped and have no leading zeros.
/// - requires `other` to have at least two limbs.
/// - requires `self` to have a greater length compared to `other`.
///
/// All arguments are examined without being stripped for the above conditions. If any of
/// the above fails, `None` is returned.`
///
/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> {
if other.len() <= 1 || other.msb() == 0 || self.msb() == 0 || self.len() <= other.len() {
return None
}
let n = other.len();
let m = self.len() - n;
let mut q = Self::with_capacity(m + 1);
let mut r = Self::with_capacity(n);
// PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are
// safe.
let normalizer_bits = other.msb().leading_zeros() as Single;
let normalizer = 2_u32.pow(normalizer_bits as u32) as Single;
// step D1.
let mut self_norm = self.mul(&Self::from(normalizer));
let mut other_norm = other.clone().mul(&Self::from(normalizer));
// defensive only; the mul implementation should always create this.
self_norm.lpad(n + m + 1);
other_norm.lstrip();
// step D2.
for j in (0..=m).rev() {
// step D3.0 Find an estimate of q[j], named qhat.
let (qhat, rhat) = {
// PROOF: this always fits into `Double`. In the context of Single = u8, and
// Double = u16, think of 255 * 256 + 255 which is just u16::MAX.
let dividend =
Double::from(self_norm.get(j + n)) * B + Double::from(self_norm.get(j + n - 1));
let divisor = other_norm.get(n - 1);
div_single(dividend, divisor)
};
// D3.1 test qhat
// replace qhat and rhat with RefCells. This helps share state with the closure
let qhat = RefCell::new(qhat);
let rhat = RefCell::new(Double::from(rhat));
let test = || {
// decrease qhat if it is bigger than the base (B)
let qhat_local = *qhat.borrow();
let rhat_local = *rhat.borrow();
let predicate_1 = qhat_local >= B;
let predicate_2 = {
let lhs = qhat_local * Double::from(other_norm.get(n - 2));
let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2));
lhs > rhs
};
if predicate_1 || predicate_2 {
*qhat.borrow_mut() -= 1;
*rhat.borrow_mut() += Double::from(other_norm.get(n - 1));
true
} else {
false
}
};
test();
while (*rhat.borrow() as Double) < B {
if !test() {
break
}
}
let qhat = qhat.into_inner();
// we don't need rhat anymore. just let it go out of scope when it does.
// step D4
let lhs = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let rhs = other_norm.clone().mul(&Self::from(qhat));
let maybe_sub = lhs.sub(&rhs);
let mut negative = false;
let sub = match maybe_sub {
Ok(t) => t,
Err(t) => {
negative = true;
t
},
};
(j..=j + n).for_each(|d| {
self_norm.set(d, sub.get(d - j));
});
// step D5
// PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion
// is safe.
q.set(j, qhat as Single);
// step D6: add back if negative happened.
if negative {
q.set(j, q.get(j) - 1);
let u = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let r = other_norm.clone().add(&u);
(j..=j + n).rev().for_each(|d| {
self_norm.set(d, r.get(d - j));
})
}
}
// if requested, calculate remainder.
if rem {
// undo the normalization.
if normalizer_bits > 0 {
let s = SHIFT as u32;
let nb = normalizer_bits;
for d in 0..n - 1 {
let v = self_norm.get(d) >> nb | self_norm.get(d + 1).overflowing_shl(s - nb).0;
r.set(d, v);
}
r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits);
} else {
r = self_norm;
}
}
Some((q, r))
}
sourcepub fn lsb(&self) -> Single
pub fn lsb(&self) -> Single
returns the least significant limb of the number.
Panics
While the constructor of the type prevents this, this can panic if self
has no digits.
sourcepub fn msb(&self) -> Single
pub fn msb(&self) -> Single
returns the most significant limb of the number.
Panics
While the constructor of the type prevents this, this can panic if self
has no digits.
Examples found in repository?
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> {
if other.len() <= 1 || other.msb() == 0 || self.msb() == 0 || self.len() <= other.len() {
return None
}
let n = other.len();
let m = self.len() - n;
let mut q = Self::with_capacity(m + 1);
let mut r = Self::with_capacity(n);
// PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are
// safe.
let normalizer_bits = other.msb().leading_zeros() as Single;
let normalizer = 2_u32.pow(normalizer_bits as u32) as Single;
// step D1.
let mut self_norm = self.mul(&Self::from(normalizer));
let mut other_norm = other.clone().mul(&Self::from(normalizer));
// defensive only; the mul implementation should always create this.
self_norm.lpad(n + m + 1);
other_norm.lstrip();
// step D2.
for j in (0..=m).rev() {
// step D3.0 Find an estimate of q[j], named qhat.
let (qhat, rhat) = {
// PROOF: this always fits into `Double`. In the context of Single = u8, and
// Double = u16, think of 255 * 256 + 255 which is just u16::MAX.
let dividend =
Double::from(self_norm.get(j + n)) * B + Double::from(self_norm.get(j + n - 1));
let divisor = other_norm.get(n - 1);
div_single(dividend, divisor)
};
// D3.1 test qhat
// replace qhat and rhat with RefCells. This helps share state with the closure
let qhat = RefCell::new(qhat);
let rhat = RefCell::new(Double::from(rhat));
let test = || {
// decrease qhat if it is bigger than the base (B)
let qhat_local = *qhat.borrow();
let rhat_local = *rhat.borrow();
let predicate_1 = qhat_local >= B;
let predicate_2 = {
let lhs = qhat_local * Double::from(other_norm.get(n - 2));
let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2));
lhs > rhs
};
if predicate_1 || predicate_2 {
*qhat.borrow_mut() -= 1;
*rhat.borrow_mut() += Double::from(other_norm.get(n - 1));
true
} else {
false
}
};
test();
while (*rhat.borrow() as Double) < B {
if !test() {
break
}
}
let qhat = qhat.into_inner();
// we don't need rhat anymore. just let it go out of scope when it does.
// step D4
let lhs = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let rhs = other_norm.clone().mul(&Self::from(qhat));
let maybe_sub = lhs.sub(&rhs);
let mut negative = false;
let sub = match maybe_sub {
Ok(t) => t,
Err(t) => {
negative = true;
t
},
};
(j..=j + n).for_each(|d| {
self_norm.set(d, sub.get(d - j));
});
// step D5
// PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion
// is safe.
q.set(j, qhat as Single);
// step D6: add back if negative happened.
if negative {
q.set(j, q.get(j) - 1);
let u = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let r = other_norm.clone().add(&u);
(j..=j + n).rev().for_each(|d| {
self_norm.set(d, r.get(d - j));
})
}
}
// if requested, calculate remainder.
if rem {
// undo the normalization.
if normalizer_bits > 0 {
let s = SHIFT as u32;
let nb = normalizer_bits;
for d in 0..n - 1 {
let v = self_norm.get(d) >> nb | self_norm.get(d + 1).overflowing_shl(s - nb).0;
r.set(d, v);
}
r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits);
} else {
r = self_norm;
}
}
Some((q, r))
}
sourcepub fn lstrip(&mut self)
pub fn lstrip(&mut self)
Strips zeros from the left side (the most significant limbs) of self
, if any.
Examples found in repository?
More examples
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> {
if other.len() <= 1 || other.msb() == 0 || self.msb() == 0 || self.len() <= other.len() {
return None
}
let n = other.len();
let m = self.len() - n;
let mut q = Self::with_capacity(m + 1);
let mut r = Self::with_capacity(n);
// PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are
// safe.
let normalizer_bits = other.msb().leading_zeros() as Single;
let normalizer = 2_u32.pow(normalizer_bits as u32) as Single;
// step D1.
let mut self_norm = self.mul(&Self::from(normalizer));
let mut other_norm = other.clone().mul(&Self::from(normalizer));
// defensive only; the mul implementation should always create this.
self_norm.lpad(n + m + 1);
other_norm.lstrip();
// step D2.
for j in (0..=m).rev() {
// step D3.0 Find an estimate of q[j], named qhat.
let (qhat, rhat) = {
// PROOF: this always fits into `Double`. In the context of Single = u8, and
// Double = u16, think of 255 * 256 + 255 which is just u16::MAX.
let dividend =
Double::from(self_norm.get(j + n)) * B + Double::from(self_norm.get(j + n - 1));
let divisor = other_norm.get(n - 1);
div_single(dividend, divisor)
};
// D3.1 test qhat
// replace qhat and rhat with RefCells. This helps share state with the closure
let qhat = RefCell::new(qhat);
let rhat = RefCell::new(Double::from(rhat));
let test = || {
// decrease qhat if it is bigger than the base (B)
let qhat_local = *qhat.borrow();
let rhat_local = *rhat.borrow();
let predicate_1 = qhat_local >= B;
let predicate_2 = {
let lhs = qhat_local * Double::from(other_norm.get(n - 2));
let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2));
lhs > rhs
};
if predicate_1 || predicate_2 {
*qhat.borrow_mut() -= 1;
*rhat.borrow_mut() += Double::from(other_norm.get(n - 1));
true
} else {
false
}
};
test();
while (*rhat.borrow() as Double) < B {
if !test() {
break
}
}
let qhat = qhat.into_inner();
// we don't need rhat anymore. just let it go out of scope when it does.
// step D4
let lhs = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let rhs = other_norm.clone().mul(&Self::from(qhat));
let maybe_sub = lhs.sub(&rhs);
let mut negative = false;
let sub = match maybe_sub {
Ok(t) => t,
Err(t) => {
negative = true;
t
},
};
(j..=j + n).for_each(|d| {
self_norm.set(d, sub.get(d - j));
});
// step D5
// PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion
// is safe.
q.set(j, qhat as Single);
// step D6: add back if negative happened.
if negative {
q.set(j, q.get(j) - 1);
let u = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let r = other_norm.clone().add(&u);
(j..=j + n).rev().for_each(|d| {
self_norm.set(d, r.get(d - j));
})
}
}
// if requested, calculate remainder.
if rem {
// undo the normalization.
if normalizer_bits > 0 {
let s = SHIFT as u32;
let nb = normalizer_bits;
for d in 0..n - 1 {
let v = self_norm.get(d) >> nb | self_norm.get(d + 1).overflowing_shl(s - nb).0;
r.set(d, v);
}
r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits);
} else {
r = self_norm;
}
}
Some((q, r))
}
sourcepub fn lpad(&mut self, size: usize)
pub fn lpad(&mut self, size: usize)
Zero-pad self
from left to reach size
limbs. Will not make any difference if self
is already bigger than size
limbs.
Examples found in repository?
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> {
if other.len() <= 1 || other.msb() == 0 || self.msb() == 0 || self.len() <= other.len() {
return None
}
let n = other.len();
let m = self.len() - n;
let mut q = Self::with_capacity(m + 1);
let mut r = Self::with_capacity(n);
// PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are
// safe.
let normalizer_bits = other.msb().leading_zeros() as Single;
let normalizer = 2_u32.pow(normalizer_bits as u32) as Single;
// step D1.
let mut self_norm = self.mul(&Self::from(normalizer));
let mut other_norm = other.clone().mul(&Self::from(normalizer));
// defensive only; the mul implementation should always create this.
self_norm.lpad(n + m + 1);
other_norm.lstrip();
// step D2.
for j in (0..=m).rev() {
// step D3.0 Find an estimate of q[j], named qhat.
let (qhat, rhat) = {
// PROOF: this always fits into `Double`. In the context of Single = u8, and
// Double = u16, think of 255 * 256 + 255 which is just u16::MAX.
let dividend =
Double::from(self_norm.get(j + n)) * B + Double::from(self_norm.get(j + n - 1));
let divisor = other_norm.get(n - 1);
div_single(dividend, divisor)
};
// D3.1 test qhat
// replace qhat and rhat with RefCells. This helps share state with the closure
let qhat = RefCell::new(qhat);
let rhat = RefCell::new(Double::from(rhat));
let test = || {
// decrease qhat if it is bigger than the base (B)
let qhat_local = *qhat.borrow();
let rhat_local = *rhat.borrow();
let predicate_1 = qhat_local >= B;
let predicate_2 = {
let lhs = qhat_local * Double::from(other_norm.get(n - 2));
let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2));
lhs > rhs
};
if predicate_1 || predicate_2 {
*qhat.borrow_mut() -= 1;
*rhat.borrow_mut() += Double::from(other_norm.get(n - 1));
true
} else {
false
}
};
test();
while (*rhat.borrow() as Double) < B {
if !test() {
break
}
}
let qhat = qhat.into_inner();
// we don't need rhat anymore. just let it go out of scope when it does.
// step D4
let lhs = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let rhs = other_norm.clone().mul(&Self::from(qhat));
let maybe_sub = lhs.sub(&rhs);
let mut negative = false;
let sub = match maybe_sub {
Ok(t) => t,
Err(t) => {
negative = true;
t
},
};
(j..=j + n).for_each(|d| {
self_norm.set(d, sub.get(d - j));
});
// step D5
// PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion
// is safe.
q.set(j, qhat as Single);
// step D6: add back if negative happened.
if negative {
q.set(j, q.get(j) - 1);
let u = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let r = other_norm.clone().add(&u);
(j..=j + n).rev().for_each(|d| {
self_norm.set(d, r.get(d - j));
})
}
}
// if requested, calculate remainder.
if rem {
// undo the normalization.
if normalizer_bits > 0 {
let s = SHIFT as u32;
let nb = normalizer_bits;
for d in 0..n - 1 {
let v = self_norm.get(d) >> nb | self_norm.get(d + 1).overflowing_shl(s - nb).0;
r.set(d, v);
}
r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits);
} else {
r = self_norm;
}
}
Some((q, r))
}
sourcepub fn add(self, other: &Self) -> Self
pub fn add(self, other: &Self) -> Self
Adds self
with other
. self and other do not have to have any particular size. Given
that the n = max{size(self), size(other)}
, it will produce a number with n + 1
limbs.
This function does not strip the output and returns the original allocated n + 1
limbs. The caller may strip the output if desired.
Taken from “The Art of Computer Programming” by D.E. Knuth, vol 2, chapter 4.
Examples found in repository?
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> {
if other.len() <= 1 || other.msb() == 0 || self.msb() == 0 || self.len() <= other.len() {
return None
}
let n = other.len();
let m = self.len() - n;
let mut q = Self::with_capacity(m + 1);
let mut r = Self::with_capacity(n);
// PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are
// safe.
let normalizer_bits = other.msb().leading_zeros() as Single;
let normalizer = 2_u32.pow(normalizer_bits as u32) as Single;
// step D1.
let mut self_norm = self.mul(&Self::from(normalizer));
let mut other_norm = other.clone().mul(&Self::from(normalizer));
// defensive only; the mul implementation should always create this.
self_norm.lpad(n + m + 1);
other_norm.lstrip();
// step D2.
for j in (0..=m).rev() {
// step D3.0 Find an estimate of q[j], named qhat.
let (qhat, rhat) = {
// PROOF: this always fits into `Double`. In the context of Single = u8, and
// Double = u16, think of 255 * 256 + 255 which is just u16::MAX.
let dividend =
Double::from(self_norm.get(j + n)) * B + Double::from(self_norm.get(j + n - 1));
let divisor = other_norm.get(n - 1);
div_single(dividend, divisor)
};
// D3.1 test qhat
// replace qhat and rhat with RefCells. This helps share state with the closure
let qhat = RefCell::new(qhat);
let rhat = RefCell::new(Double::from(rhat));
let test = || {
// decrease qhat if it is bigger than the base (B)
let qhat_local = *qhat.borrow();
let rhat_local = *rhat.borrow();
let predicate_1 = qhat_local >= B;
let predicate_2 = {
let lhs = qhat_local * Double::from(other_norm.get(n - 2));
let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2));
lhs > rhs
};
if predicate_1 || predicate_2 {
*qhat.borrow_mut() -= 1;
*rhat.borrow_mut() += Double::from(other_norm.get(n - 1));
true
} else {
false
}
};
test();
while (*rhat.borrow() as Double) < B {
if !test() {
break
}
}
let qhat = qhat.into_inner();
// we don't need rhat anymore. just let it go out of scope when it does.
// step D4
let lhs = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let rhs = other_norm.clone().mul(&Self::from(qhat));
let maybe_sub = lhs.sub(&rhs);
let mut negative = false;
let sub = match maybe_sub {
Ok(t) => t,
Err(t) => {
negative = true;
t
},
};
(j..=j + n).for_each(|d| {
self_norm.set(d, sub.get(d - j));
});
// step D5
// PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion
// is safe.
q.set(j, qhat as Single);
// step D6: add back if negative happened.
if negative {
q.set(j, q.get(j) - 1);
let u = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let r = other_norm.clone().add(&u);
(j..=j + n).rev().for_each(|d| {
self_norm.set(d, r.get(d - j));
})
}
}
// if requested, calculate remainder.
if rem {
// undo the normalization.
if normalizer_bits > 0 {
let s = SHIFT as u32;
let nb = normalizer_bits;
for d in 0..n - 1 {
let v = self_norm.get(d) >> nb | self_norm.get(d + 1).overflowing_shl(s - nb).0;
r.set(d, v);
}
r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits);
} else {
r = self_norm;
}
}
Some((q, r))
}
}
impl sp_std::fmt::Debug for BigUint {
#[cfg(feature = "std")]
fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result {
write!(
f,
"BigUint {{ {:?} ({:?})}}",
self.digits,
u128::try_from(self.clone()).unwrap_or(0),
)
}
#[cfg(not(feature = "std"))]
fn fmt(&self, _: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result {
Ok(())
}
}
impl PartialEq for BigUint {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal
}
}
impl Eq for BigUint {}
impl Ord for BigUint {
fn cmp(&self, other: &Self) -> Ordering {
let lhs_first = self.digits.iter().position(|&e| e != 0);
let rhs_first = other.digits.iter().position(|&e| e != 0);
match (lhs_first, rhs_first) {
// edge cases that should not happen. This basically means that one or both were
// zero.
(None, None) => Ordering::Equal,
(Some(_), None) => Ordering::Greater,
(None, Some(_)) => Ordering::Less,
(Some(lhs_idx), Some(rhs_idx)) => {
let lhs = &self.digits[lhs_idx..];
let rhs = &other.digits[rhs_idx..];
let len_cmp = lhs.len().cmp(&rhs.len());
match len_cmp {
Ordering::Equal => lhs.cmp(rhs),
_ => len_cmp,
}
},
}
}
}
impl PartialOrd for BigUint {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl ops::Add for BigUint {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
self.add(&rhs)
}
sourcepub fn sub(self, other: &Self) -> Result<Self, Self>
pub fn sub(self, other: &Self) -> Result<Self, Self>
Subtracts other
from self
. self and other do not have to have any particular size.
Given that the n = max{size(self), size(other)}
, it will produce a number of size n
.
If other
is bigger than self
, Err(B - borrow)
is returned.
Taken from “The Art of Computer Programming” by D.E. Knuth, vol 2, chapter 4.
Examples found in repository?
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> {
if other.len() <= 1 || other.msb() == 0 || self.msb() == 0 || self.len() <= other.len() {
return None
}
let n = other.len();
let m = self.len() - n;
let mut q = Self::with_capacity(m + 1);
let mut r = Self::with_capacity(n);
// PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are
// safe.
let normalizer_bits = other.msb().leading_zeros() as Single;
let normalizer = 2_u32.pow(normalizer_bits as u32) as Single;
// step D1.
let mut self_norm = self.mul(&Self::from(normalizer));
let mut other_norm = other.clone().mul(&Self::from(normalizer));
// defensive only; the mul implementation should always create this.
self_norm.lpad(n + m + 1);
other_norm.lstrip();
// step D2.
for j in (0..=m).rev() {
// step D3.0 Find an estimate of q[j], named qhat.
let (qhat, rhat) = {
// PROOF: this always fits into `Double`. In the context of Single = u8, and
// Double = u16, think of 255 * 256 + 255 which is just u16::MAX.
let dividend =
Double::from(self_norm.get(j + n)) * B + Double::from(self_norm.get(j + n - 1));
let divisor = other_norm.get(n - 1);
div_single(dividend, divisor)
};
// D3.1 test qhat
// replace qhat and rhat with RefCells. This helps share state with the closure
let qhat = RefCell::new(qhat);
let rhat = RefCell::new(Double::from(rhat));
let test = || {
// decrease qhat if it is bigger than the base (B)
let qhat_local = *qhat.borrow();
let rhat_local = *rhat.borrow();
let predicate_1 = qhat_local >= B;
let predicate_2 = {
let lhs = qhat_local * Double::from(other_norm.get(n - 2));
let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2));
lhs > rhs
};
if predicate_1 || predicate_2 {
*qhat.borrow_mut() -= 1;
*rhat.borrow_mut() += Double::from(other_norm.get(n - 1));
true
} else {
false
}
};
test();
while (*rhat.borrow() as Double) < B {
if !test() {
break
}
}
let qhat = qhat.into_inner();
// we don't need rhat anymore. just let it go out of scope when it does.
// step D4
let lhs = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let rhs = other_norm.clone().mul(&Self::from(qhat));
let maybe_sub = lhs.sub(&rhs);
let mut negative = false;
let sub = match maybe_sub {
Ok(t) => t,
Err(t) => {
negative = true;
t
},
};
(j..=j + n).for_each(|d| {
self_norm.set(d, sub.get(d - j));
});
// step D5
// PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion
// is safe.
q.set(j, qhat as Single);
// step D6: add back if negative happened.
if negative {
q.set(j, q.get(j) - 1);
let u = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let r = other_norm.clone().add(&u);
(j..=j + n).rev().for_each(|d| {
self_norm.set(d, r.get(d - j));
})
}
}
// if requested, calculate remainder.
if rem {
// undo the normalization.
if normalizer_bits > 0 {
let s = SHIFT as u32;
let nb = normalizer_bits;
for d in 0..n - 1 {
let v = self_norm.get(d) >> nb | self_norm.get(d + 1).overflowing_shl(s - nb).0;
r.set(d, v);
}
r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits);
} else {
r = self_norm;
}
}
Some((q, r))
}
}
impl sp_std::fmt::Debug for BigUint {
#[cfg(feature = "std")]
fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result {
write!(
f,
"BigUint {{ {:?} ({:?})}}",
self.digits,
u128::try_from(self.clone()).unwrap_or(0),
)
}
#[cfg(not(feature = "std"))]
fn fmt(&self, _: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result {
Ok(())
}
}
impl PartialEq for BigUint {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal
}
}
impl Eq for BigUint {}
impl Ord for BigUint {
fn cmp(&self, other: &Self) -> Ordering {
let lhs_first = self.digits.iter().position(|&e| e != 0);
let rhs_first = other.digits.iter().position(|&e| e != 0);
match (lhs_first, rhs_first) {
// edge cases that should not happen. This basically means that one or both were
// zero.
(None, None) => Ordering::Equal,
(Some(_), None) => Ordering::Greater,
(None, Some(_)) => Ordering::Less,
(Some(lhs_idx), Some(rhs_idx)) => {
let lhs = &self.digits[lhs_idx..];
let rhs = &other.digits[rhs_idx..];
let len_cmp = lhs.len().cmp(&rhs.len());
match len_cmp {
Ordering::Equal => lhs.cmp(rhs),
_ => len_cmp,
}
},
}
}
}
impl PartialOrd for BigUint {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl ops::Add for BigUint {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
self.add(&rhs)
}
}
impl ops::Sub for BigUint {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
self.sub(&rhs).unwrap_or_else(|e| e)
}
sourcepub fn mul(self, other: &Self) -> Self
pub fn mul(self, other: &Self) -> Self
Multiplies n-limb number self
with m-limb number other
.
The resulting number will always have n + m
limbs.
This function does not strip the output and returns the original allocated n + m
limbs. The caller may strip the output if desired.
Taken from “The Art of Computer Programming” by D.E. Knuth, vol 2, chapter 4.
Examples found in repository?
63 64 65 66 67 68 69 70 71 72 73 74 75
fn cmp(&self, other: &Self) -> Ordering {
// handle some edge cases.
if self.d() == other.d() {
self.n().cmp(other.n())
} else if self.d().is_zero() {
Ordering::Greater
} else if other.d().is_zero() {
Ordering::Less
} else {
// (a/b) cmp (c/d) => (a*d) cmp (c*b)
self.n().clone().mul(other.d()).cmp(&other.n().clone().mul(self.d()))
}
}
More examples
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> {
if other.len() <= 1 || other.msb() == 0 || self.msb() == 0 || self.len() <= other.len() {
return None
}
let n = other.len();
let m = self.len() - n;
let mut q = Self::with_capacity(m + 1);
let mut r = Self::with_capacity(n);
// PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are
// safe.
let normalizer_bits = other.msb().leading_zeros() as Single;
let normalizer = 2_u32.pow(normalizer_bits as u32) as Single;
// step D1.
let mut self_norm = self.mul(&Self::from(normalizer));
let mut other_norm = other.clone().mul(&Self::from(normalizer));
// defensive only; the mul implementation should always create this.
self_norm.lpad(n + m + 1);
other_norm.lstrip();
// step D2.
for j in (0..=m).rev() {
// step D3.0 Find an estimate of q[j], named qhat.
let (qhat, rhat) = {
// PROOF: this always fits into `Double`. In the context of Single = u8, and
// Double = u16, think of 255 * 256 + 255 which is just u16::MAX.
let dividend =
Double::from(self_norm.get(j + n)) * B + Double::from(self_norm.get(j + n - 1));
let divisor = other_norm.get(n - 1);
div_single(dividend, divisor)
};
// D3.1 test qhat
// replace qhat and rhat with RefCells. This helps share state with the closure
let qhat = RefCell::new(qhat);
let rhat = RefCell::new(Double::from(rhat));
let test = || {
// decrease qhat if it is bigger than the base (B)
let qhat_local = *qhat.borrow();
let rhat_local = *rhat.borrow();
let predicate_1 = qhat_local >= B;
let predicate_2 = {
let lhs = qhat_local * Double::from(other_norm.get(n - 2));
let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2));
lhs > rhs
};
if predicate_1 || predicate_2 {
*qhat.borrow_mut() -= 1;
*rhat.borrow_mut() += Double::from(other_norm.get(n - 1));
true
} else {
false
}
};
test();
while (*rhat.borrow() as Double) < B {
if !test() {
break
}
}
let qhat = qhat.into_inner();
// we don't need rhat anymore. just let it go out of scope when it does.
// step D4
let lhs = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let rhs = other_norm.clone().mul(&Self::from(qhat));
let maybe_sub = lhs.sub(&rhs);
let mut negative = false;
let sub = match maybe_sub {
Ok(t) => t,
Err(t) => {
negative = true;
t
},
};
(j..=j + n).for_each(|d| {
self_norm.set(d, sub.get(d - j));
});
// step D5
// PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion
// is safe.
q.set(j, qhat as Single);
// step D6: add back if negative happened.
if negative {
q.set(j, q.get(j) - 1);
let u = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
let r = other_norm.clone().add(&u);
(j..=j + n).rev().for_each(|d| {
self_norm.set(d, r.get(d - j));
})
}
}
// if requested, calculate remainder.
if rem {
// undo the normalization.
if normalizer_bits > 0 {
let s = SHIFT as u32;
let nb = normalizer_bits;
for d in 0..n - 1 {
let v = self_norm.get(d) >> nb | self_norm.get(d + 1).overflowing_shl(s - nb).0;
r.set(d, v);
}
r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits);
} else {
r = self_norm;
}
}
Some((q, r))
}
}
impl sp_std::fmt::Debug for BigUint {
#[cfg(feature = "std")]
fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result {
write!(
f,
"BigUint {{ {:?} ({:?})}}",
self.digits,
u128::try_from(self.clone()).unwrap_or(0),
)
}
#[cfg(not(feature = "std"))]
fn fmt(&self, _: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result {
Ok(())
}
}
impl PartialEq for BigUint {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal
}
}
impl Eq for BigUint {}
impl Ord for BigUint {
fn cmp(&self, other: &Self) -> Ordering {
let lhs_first = self.digits.iter().position(|&e| e != 0);
let rhs_first = other.digits.iter().position(|&e| e != 0);
match (lhs_first, rhs_first) {
// edge cases that should not happen. This basically means that one or both were
// zero.
(None, None) => Ordering::Equal,
(Some(_), None) => Ordering::Greater,
(None, Some(_)) => Ordering::Less,
(Some(lhs_idx), Some(rhs_idx)) => {
let lhs = &self.digits[lhs_idx..];
let rhs = &other.digits[rhs_idx..];
let len_cmp = lhs.len().cmp(&rhs.len());
match len_cmp {
Ordering::Equal => lhs.cmp(rhs),
_ => len_cmp,
}
},
}
}
}
impl PartialOrd for BigUint {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl ops::Add for BigUint {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
self.add(&rhs)
}
}
impl ops::Sub for BigUint {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
self.sub(&rhs).unwrap_or_else(|e| e)
}
}
impl ops::Mul for BigUint {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
self.mul(&rhs)
}
sourcepub fn div_unit(self, other: Single) -> Self
pub fn div_unit(self, other: Single) -> Self
Divides self
by a single limb other
. This can be used in cases where the original
division cannot work due to the divisor (other
) being just one limb.
Invariant: other
cannot be zero.
sourcepub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)>
pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)>
Divides an n + m
limb self by a n
limb other
. The result is a m + 1
limb
quotient and a n
limb remainder, if enabled by passing true
in rem
argument, both
in the form of an option’s Ok
.
- requires
other
to be stripped and have no leading zeros. - requires
self
to be stripped and have no leading zeros. - requires
other
to have at least two limbs. - requires
self
to have a greater length compared toother
.
All arguments are examined without being stripped for the above conditions. If any of
the above fails, None
is returned.`
Taken from “The Art of Computer Programming” by D.E. Knuth, vol 2, chapter 4.
Trait Implementations§
source§impl Decode for BigUint
impl Decode for BigUint
source§impl Encode for BigUint
impl Encode for BigUint
source§fn encode_to<__CodecOutputEdqy: Output + ?Sized>(
&self,
__codec_dest_edqy: &mut __CodecOutputEdqy
)
fn encode_to<__CodecOutputEdqy: Output + ?Sized>(
&self,
__codec_dest_edqy: &mut __CodecOutputEdqy
)
source§fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R
source§fn size_hint(&self) -> usize
fn size_hint(&self) -> usize
source§fn encoded_size(&self) -> usize
fn encoded_size(&self) -> usize
source§impl Ord for BigUint
impl Ord for BigUint
source§impl PartialEq<BigUint> for BigUint
impl PartialEq<BigUint> for BigUint
source§impl PartialOrd<BigUint> for BigUint
impl PartialOrd<BigUint> for BigUint
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read moreimpl EncodeLike<BigUint> for BigUint
impl Eq for BigUint
Auto Trait Implementations§
impl RefUnwindSafe for BigUint
impl Send for BigUint
impl Sync for BigUint
impl Unpin for BigUint
impl UnwindSafe for BigUint
Blanket Implementations§
source§impl<T> DecodeLimit for Twhere
T: Decode,
impl<T> DecodeLimit for Twhere
T: Decode,
source§impl<T> SaturatedConversion for T
impl<T> SaturatedConversion for T
source§fn saturated_from<T>(t: T) -> Selfwhere
Self: UniqueSaturatedFrom<T>,
fn saturated_from<T>(t: T) -> Selfwhere
Self: UniqueSaturatedFrom<T>,
source§fn saturated_into<T>(self) -> Twhere
Self: UniqueSaturatedInto<T>,
fn saturated_into<T>(self) -> Twhere
Self: UniqueSaturatedInto<T>,
T
. Read moresource§impl<T, S> UniqueSaturatedInto<T> for Swhere
T: Bounded,
S: TryInto<T>,
impl<T, S> UniqueSaturatedInto<T> for Swhere
T: Bounded,
S: TryInto<T>,
source§fn unique_saturated_into(self) -> T
fn unique_saturated_into(self) -> T
T
.