20
20
#![ macro_use]
21
21
22
22
use crate :: intrinsics;
23
- use crate :: mem;
24
23
25
24
/// Arithmetic operations required by bignums.
26
25
pub trait FullOps : Sized {
@@ -58,25 +57,22 @@ macro_rules! impl_full_ops {
58
57
// This cannot overflow;
59
58
// the output is between `0` and `2^nbits * (2^nbits - 1)`.
60
59
// FIXME: will LLVM optimize this into ADC or similar?
61
- let nbits = mem:: size_of:: <$ty>( ) * 8 ;
62
60
let v = ( self as $bigty) * ( other as $bigty) + ( carry as $bigty) ;
63
- ( ( v >> nbits ) as $ty, v as $ty)
61
+ ( ( v >> <$ty> :: BITS ) as $ty, v as $ty)
64
62
}
65
63
66
64
fn full_mul_add( self , other: $ty, other2: $ty, carry: $ty) -> ( $ty, $ty) {
67
65
// This cannot overflow;
68
66
// the output is between `0` and `2^nbits * (2^nbits - 1)`.
69
- let nbits = mem:: size_of:: <$ty>( ) * 8 ;
70
67
let v = ( self as $bigty) * ( other as $bigty) + ( other2 as $bigty) +
71
68
( carry as $bigty) ;
72
- ( ( v >> nbits ) as $ty, v as $ty)
69
+ ( ( v >> <$ty> :: BITS ) as $ty, v as $ty)
73
70
}
74
71
75
72
fn full_div_rem( self , other: $ty, borrow: $ty) -> ( $ty, $ty) {
76
73
debug_assert!( borrow < other) ;
77
74
// This cannot overflow; the output is between `0` and `other * (2^nbits - 1)`.
78
- let nbits = mem:: size_of:: <$ty>( ) * 8 ;
79
- let lhs = ( ( borrow as $bigty) << nbits) | ( self as $bigty) ;
75
+ let lhs = ( ( borrow as $bigty) << <$ty>:: BITS ) | ( self as $bigty) ;
80
76
let rhs = other as $bigty;
81
77
( ( lhs / rhs) as $ty, ( lhs % rhs) as $ty)
82
78
}
@@ -128,13 +124,11 @@ macro_rules! define_bignum {
128
124
129
125
/// Makes a bignum from `u64` value.
130
126
pub fn from_u64( mut v: u64 ) -> $name {
131
- use crate :: mem;
132
-
133
127
let mut base = [ 0 ; $n] ;
134
128
let mut sz = 0 ;
135
129
while v > 0 {
136
130
base[ sz] = v as $ty;
137
- v >>= mem :: size_of :: <$ty>( ) * 8 ;
131
+ v >>= <$ty>:: BITS ;
138
132
sz += 1 ;
139
133
}
140
134
$name { size: sz, base: base }
@@ -150,9 +144,7 @@ macro_rules! define_bignum {
150
144
/// Returns the `i`-th bit where bit 0 is the least significant one.
151
145
/// In other words, the bit with weight `2^i`.
152
146
pub fn get_bit( & self , i: usize ) -> u8 {
153
- use crate :: mem;
154
-
155
- let digitbits = mem:: size_of:: <$ty>( ) * 8 ;
147
+ let digitbits = <$ty>:: BITS as usize ;
156
148
let d = i / digitbits;
157
149
let b = i % digitbits;
158
150
( ( self . base[ d] >> b) & 1 ) as u8
@@ -166,8 +158,6 @@ macro_rules! define_bignum {
166
158
/// Returns the number of bits necessary to represent this value. Note that zero
167
159
/// is considered to need 0 bits.
168
160
pub fn bit_length( & self ) -> usize {
169
- use crate :: mem;
170
-
171
161
// Skip over the most significant digits which are zero.
172
162
let digits = self . digits( ) ;
173
163
let zeros = digits. iter( ) . rev( ) . take_while( |&&x| x == 0 ) . count( ) ;
@@ -180,7 +170,7 @@ macro_rules! define_bignum {
180
170
}
181
171
// This could be optimized with leading_zeros() and bit shifts, but that's
182
172
// probably not worth the hassle.
183
- let digitbits = mem :: size_of :: <$ty>( ) * 8 ;
173
+ let digitbits = <$ty>:: BITS as usize ;
184
174
let mut i = nonzero. len( ) * digitbits - 1 ;
185
175
while self . get_bit( i) == 0 {
186
176
i -= 1 ;
@@ -265,9 +255,7 @@ macro_rules! define_bignum {
265
255
266
256
/// Multiplies itself by `2^bits` and returns its own mutable reference.
267
257
pub fn mul_pow2( & mut self , bits: usize ) -> & mut $name {
268
- use crate :: mem;
269
-
270
- let digitbits = mem:: size_of:: <$ty>( ) * 8 ;
258
+ let digitbits = <$ty>:: BITS as usize ;
271
259
let digits = bits / digitbits;
272
260
let bits = bits % digitbits;
273
261
@@ -393,13 +381,11 @@ macro_rules! define_bignum {
393
381
/// Divide self by another bignum, overwriting `q` with the quotient and `r` with the
394
382
/// remainder.
395
383
pub fn div_rem( & self , d: & $name, q: & mut $name, r: & mut $name) {
396
- use crate :: mem;
397
-
398
384
// Stupid slow base-2 long division taken from
399
385
// https://en.wikipedia.org/wiki/Division_algorithm
400
386
// FIXME use a greater base ($ty) for the long division.
401
387
assert!( !d. is_zero( ) ) ;
402
- let digitbits = mem :: size_of :: <$ty>( ) * 8 ;
388
+ let digitbits = <$ty>:: BITS as usize ;
403
389
for digit in & mut q. base[ ..] {
404
390
* digit = 0 ;
405
391
}
@@ -462,10 +448,8 @@ macro_rules! define_bignum {
462
448
463
449
impl crate :: fmt:: Debug for $name {
464
450
fn fmt( & self , f: & mut crate :: fmt:: Formatter <' _>) -> crate :: fmt:: Result {
465
- use crate :: mem;
466
-
467
451
let sz = if self . size < 1 { 1 } else { self . size } ;
468
- let digitlen = mem :: size_of :: <$ty>( ) * 2 ;
452
+ let digitlen = <$ty>:: BITS as usize / 4 ;
469
453
470
454
write!( f, "{:#x}" , self . base[ sz - 1 ] ) ?;
471
455
for & v in self . base[ ..sz - 1 ] . iter( ) . rev( ) {
0 commit comments