@@ -60,6 +60,50 @@ impl NumberTraits for Number {
6060 ret
6161 }
6262
63+ fn to_signed_bytes ( & self ) -> Vec < u8 > {
64+ let size = ( self . bits ( ) + 7 ) / 8 ;
65+ let mut ret: Vec < u8 > = Vec :: new ( ) ;
66+ if size == 0 {
67+ return ret;
68+ }
69+ ret. resize ( size + 1 , 0 ) ;
70+ let sign = self . sign ( ) ;
71+ let mut out_size: usize = size;
72+ unsafe {
73+ gmp:: mpz_export (
74+ ret. as_mut_slice ( ) [ 1 ..] . as_mut_ptr ( ) as * mut c_void ,
75+ & mut out_size,
76+ 1 ,
77+ 1 ,
78+ 0 ,
79+ 0 ,
80+ & self . v ,
81+ ) ;
82+ }
83+ // apparently mpz_export prints 0 bytes to the buffer if the value is 0
84+ // hence the special case in the assert below.
85+ assert ! ( out_size == ret. len( ) - 1 ) ;
86+ if sign == Sign :: Minus {
87+ // If the value is negative, we need to convert it to two's
88+ // complement. We can't do that in-place.
89+ let mut carry = true ;
90+ for digit in & mut ret. iter_mut ( ) . rev ( ) {
91+ let res = ( !* digit) . overflowing_add ( carry as u8 ) ;
92+ * digit = res. 0 ;
93+ carry = res. 1 ;
94+ }
95+ assert ! ( !carry) ;
96+ assert ! ( ret[ 0 ] & 0x80 != 0 ) ;
97+ if ( ret[ 1 ] & 0x80 ) != 0 {
98+ ret. remove ( 0 ) ;
99+ }
100+ } else if ret[ 1 ] & 0x80 == 0 {
101+ ret. remove ( 0 ) ;
102+ }
103+ ret
104+ }
105+
106+
63107 fn zero ( ) -> Number {
64108 let mut v = MaybeUninit :: < gmp:: mpz_t > :: uninit ( ) ;
65109 unsafe {
@@ -74,8 +118,8 @@ impl NumberTraits for Number {
74118 Number :: from_signed_bytes_be ( v)
75119 }
76120
77- fn to_u64 ( n : & Number ) -> u64 {
78- n . into ( )
121+ fn to_u64 ( & self ) -> u64 {
122+ u64 :: from ( self )
79123 }
80124
81125 // returns the quotient and remained, from dividing self with denominator
@@ -95,6 +139,18 @@ impl NumberTraits for Number {
95139 }
96140 r
97141 }
142+
143+ fn equal ( & self , other : i64 ) -> bool {
144+ self == & other
145+ }
146+
147+ fn not_equal ( & self , other : i64 ) -> bool {
148+ self != & other
149+ }
150+
151+ fn greater_than ( & self , other : u64 ) -> bool {
152+ self > & other
153+ }
98154}
99155
100156impl Number {
@@ -128,49 +184,6 @@ impl Number {
128184 ret
129185 }
130186
131- pub fn to_signed_bytes_be ( & self ) -> Vec < u8 > {
132- let size = ( self . bits ( ) + 7 ) / 8 ;
133- let mut ret: Vec < u8 > = Vec :: new ( ) ;
134- if size == 0 {
135- return ret;
136- }
137- ret. resize ( size + 1 , 0 ) ;
138- let sign = self . sign ( ) ;
139- let mut out_size: usize = size;
140- unsafe {
141- gmp:: mpz_export (
142- ret. as_mut_slice ( ) [ 1 ..] . as_mut_ptr ( ) as * mut c_void ,
143- & mut out_size,
144- 1 ,
145- 1 ,
146- 0 ,
147- 0 ,
148- & self . v ,
149- ) ;
150- }
151- // apparently mpz_export prints 0 bytes to the buffer if the value is 0
152- // hence the special case in the assert below.
153- assert ! ( out_size == ret. len( ) - 1 ) ;
154- if sign == Sign :: Minus {
155- // If the value is negative, we need to convert it to two's
156- // complement. We can't do that in-place.
157- let mut carry = true ;
158- for digit in & mut ret. iter_mut ( ) . rev ( ) {
159- let res = ( !* digit) . overflowing_add ( carry as u8 ) ;
160- * digit = res. 0 ;
161- carry = res. 1 ;
162- }
163- assert ! ( !carry) ;
164- assert ! ( ret[ 0 ] & 0x80 != 0 ) ;
165- if ( ret[ 1 ] & 0x80 ) != 0 {
166- ret. remove ( 0 ) ;
167- }
168- } else if ret[ 1 ] & 0x80 == 0 {
169- ret. remove ( 0 ) ;
170- }
171- ret
172- }
173-
174187 pub fn to_bytes_le ( & self ) -> ( Sign , Vec < u8 > ) {
175188 let sgn = self . sign ( ) ;
176189
@@ -345,8 +358,8 @@ impl From<usize> for Number {
345358 }
346359}
347360
348- impl From < Number > for u64 {
349- fn from ( n : Number ) -> u64 {
361+ impl From < & Number > for u64 {
362+ fn from ( n : & Number ) -> u64 {
350363 unsafe {
351364 assert ! ( gmp:: mpz_sizeinbase( & n. v, 2 ) <= 64 ) ;
352365 assert ! ( gmp:: mpz_cmp_si( & n. v, 0 ) >= 0 ) ;
@@ -355,8 +368,8 @@ impl From<Number> for u64 {
355368 }
356369}
357370
358- impl From < Number > for i64 {
359- fn from ( n : Number ) -> i64 {
371+ impl From < & Number > for i64 {
372+ fn from ( n : & Number ) -> i64 {
360373 unsafe {
361374 assert ! ( gmp:: mpz_sizeinbase( & n. v, 2 ) <= 64 ) ;
362375 gmp:: mpz_get_si ( & n. v )
@@ -456,6 +469,9 @@ impl From<&Node<'_>> for Option<Number> {
456469 }
457470}
458471
472+ // TODO: move all tests to number.rs so we can test both the GMP and num-bigint
473+ // versions
474+
459475// ==== TESTS ====
460476
461477#[ cfg( test) ]
@@ -489,7 +505,7 @@ fn roundtrip_bytes(b: &[u8]) {
489505 assert ! ( num. sign( ) == Sign :: Plus ) ;
490506 }
491507
492- let round_trip = num. to_signed_bytes_be ( ) ;
508+ let round_trip = num. to_signed_bytes ( ) ;
493509
494510 assert_eq ! ( round_trip, b) ;
495511
@@ -516,7 +532,7 @@ fn roundtrip_bytes(b: &[u8]) {
516532 unsafe {
517533 gmp:: mpz_neg ( & mut negated. v , & num. v ) ;
518534 }
519- let magnitude = negated. to_signed_bytes_be ( ) ;
535+ let magnitude = negated. to_signed_bytes ( ) ;
520536 assert ! ( buf_le. iter( ) . eq( magnitude. iter( ) . rev( ) ) ) ;
521537 }
522538 }
@@ -525,7 +541,7 @@ fn roundtrip_bytes(b: &[u8]) {
525541 {
526542 let unsigned_num = Number :: from_unsigned_bytes_be ( b) ;
527543 assert ! ( unsigned_num. sign( ) != Sign :: Minus ) ;
528- let unsigned_round_trip = unsigned_num. to_signed_bytes_be ( ) ;
544+ let unsigned_round_trip = unsigned_num. to_signed_bytes ( ) ;
529545 let unsigned_round_trip = if unsigned_round_trip == & [ 0 ] {
530546 & unsigned_round_trip[ 1 ..]
531547 } else {
@@ -610,7 +626,7 @@ fn roundtrip_u64(v: u64) {
610626 assert ! ( num >= v - 1 ) ;
611627 }
612628
613- let round_trip: u64 = num. into ( ) ;
629+ let round_trip: u64 = ( & num) . into ( ) ;
614630 assert_eq ! ( round_trip, v) ;
615631}
616632
@@ -656,7 +672,7 @@ fn roundtrip_i64(v: i64) {
656672 }
657673
658674 assert ! ( num. bits( ) <= 64 ) ;
659- let round_trip: i64 = num. into ( ) ;
675+ let round_trip: i64 = ( & num) . into ( ) ;
660676 assert_eq ! ( round_trip, v) ;
661677}
662678
0 commit comments