@@ -506,10 +506,10 @@ impl ToPrimitive for BigUint {
506
506
fn to_i64 ( & self ) -> Option < i64 > {
507
507
do self . to_u64 ( ) . and_then |n| {
508
508
// If top bit of u64 is set, it's too large to convert to i64.
509
- if ( n >> ( 2 * BigDigit :: bits - 1 ) != 0 ) {
510
- None
511
- } else {
509
+ if n >> 63 == 0 {
512
510
Some ( n as i64 )
511
+ } else {
512
+ None
513
513
}
514
514
}
515
515
}
@@ -562,10 +562,12 @@ impl ToPrimitive for BigUint {
562
562
impl FromPrimitive for BigUint {
563
563
#[ inline]
564
564
fn from_i64 ( n : i64 ) -> Option < BigUint > {
565
- if ( n < 0 ) {
565
+ if ( n > 0 ) {
566
+ FromPrimitive :: from_u64 ( n as u64 )
567
+ } else if ( n == 0 ) {
566
568
Some ( Zero :: zero ( ) )
567
569
} else {
568
- FromPrimitive :: from_u64 ( n as u64 )
570
+ None
569
571
}
570
572
}
571
573
@@ -802,30 +804,6 @@ impl BigUint {
802
804
}
803
805
}
804
806
805
- #[ cfg( target_word_size = "64" ) ]
806
- #[ inline]
807
- fn get_radix_base ( radix : uint ) -> ( uint , uint ) {
808
- assert ! ( 1 < radix && radix <= 16 ) ;
809
- match radix {
810
- 2 => ( 4294967296 , 32 ) ,
811
- 3 => ( 3486784401 , 20 ) ,
812
- 4 => ( 4294967296 , 16 ) ,
813
- 5 => ( 1220703125 , 13 ) ,
814
- 6 => ( 2176782336 , 12 ) ,
815
- 7 => ( 1977326743 , 11 ) ,
816
- 8 => ( 1073741824 , 10 ) ,
817
- 9 => ( 3486784401 , 10 ) ,
818
- 10 => ( 1000000000 , 9 ) ,
819
- 11 => ( 2357947691 , 9 ) ,
820
- 12 => ( 429981696 , 8 ) ,
821
- 13 => ( 815730721 , 8 ) ,
822
- 14 => ( 1475789056 , 8 ) ,
823
- 15 => ( 2562890625 , 8 ) ,
824
- 16 => ( 4294967296 , 8 ) ,
825
- _ => fail2 ! ( )
826
- }
827
- }
828
-
829
807
#[ cfg( target_word_size = "32" ) ]
830
808
#[ inline]
831
809
fn get_radix_base ( radix : uint ) -> ( uint , uint ) {
@@ -850,6 +828,30 @@ fn get_radix_base(radix: uint) -> (uint, uint) {
850
828
}
851
829
}
852
830
831
+ #[ cfg( target_word_size = "64" ) ]
832
+ #[ inline]
833
+ fn get_radix_base ( radix : uint ) -> ( uint , uint ) {
834
+ assert ! ( 1 < radix && radix <= 16 ) ;
835
+ match radix {
836
+ 2 => ( 4294967296 , 32 ) ,
837
+ 3 => ( 3486784401 , 20 ) ,
838
+ 4 => ( 4294967296 , 16 ) ,
839
+ 5 => ( 1220703125 , 13 ) ,
840
+ 6 => ( 2176782336 , 12 ) ,
841
+ 7 => ( 1977326743 , 11 ) ,
842
+ 8 => ( 1073741824 , 10 ) ,
843
+ 9 => ( 3486784401 , 10 ) ,
844
+ 10 => ( 1000000000 , 9 ) ,
845
+ 11 => ( 2357947691 , 9 ) ,
846
+ 12 => ( 429981696 , 8 ) ,
847
+ 13 => ( 815730721 , 8 ) ,
848
+ 14 => ( 1475789056 , 8 ) ,
849
+ 15 => ( 2562890625 , 8 ) ,
850
+ 16 => ( 4294967296 , 8 ) ,
851
+ _ => fail2 ! ( )
852
+ }
853
+ }
854
+
853
855
/// A Sign is a `BigInt`'s composing element.
854
856
#[ deriving( Eq , Clone ) ]
855
857
pub enum Sign { Minus , Zero , Plus }
@@ -1181,13 +1183,13 @@ impl ToPrimitive for BigInt {
1181
1183
Zero => Some ( 0 ) ,
1182
1184
Minus => {
1183
1185
do self . data . to_u64 ( ) . and_then |n| {
1184
- let m: u64 = 1 << ( 2 * BigDigit :: bits- 1 ) ;
1185
- if ( n > m ) {
1186
- None
1187
- } else if ( n == m) {
1186
+ let m: u64 = 1 << 63 ;
1187
+ if n < m {
1188
+ Some ( - ( n as i64 ) )
1189
+ } else if n == m {
1188
1190
Some ( i64:: min_value)
1189
1191
} else {
1190
- Some ( - ( n as i64 ) )
1192
+ None
1191
1193
}
1192
1194
}
1193
1195
}
@@ -1431,16 +1433,15 @@ impl BigInt {
1431
1433
1432
1434
#[cfg(test)]
1433
1435
mod biguint_tests {
1434
-
1435
1436
use super::*;
1436
1437
1437
1438
use std::cmp::{Less, Equal, Greater};
1438
- use std::int ;
1439
+ use std::i64 ;
1439
1440
use std::num::{Zero, One, FromStrRadix};
1440
1441
use std::num::{ToPrimitive, FromPrimitive};
1441
1442
use std::rand::{task_rng};
1442
1443
use std::str;
1443
- use std::uint ;
1444
+ use std::u64 ;
1444
1445
use std::vec;
1445
1446
1446
1447
#[test]
@@ -1612,44 +1613,110 @@ mod biguint_tests {
1612
1613
"88887777666655554444333322221111" ) ;
1613
1614
}
1614
1615
1616
+ #[ cfg( target_word_size = "32" ) ]
1617
+ #[ test]
1618
+ fn test_convert_i64( ) {
1619
+ fn check( b1: BigUint , i: i64) {
1620
+ let b2: BigUint = FromPrimitive :: from_i64( i) . unwrap( ) ;
1621
+ assert ! ( b1 == b2) ;
1622
+ assert ! ( b1. to_i64( ) . unwrap( ) == i) ;
1623
+ }
1624
+
1625
+ check( Zero :: zero( ) , 0 ) ;
1626
+ check( One :: one( ) , 1 ) ;
1627
+ check( i64:: max_value. to_biguint( ) . unwrap( ) , i64:: max_value) ;
1628
+
1629
+ check( BigUint :: new( ~[ ] ) , 0 ) ;
1630
+ check( BigUint :: new( ~[ 1 ] ) , ( 1 << ( 0 * BigDigit :: bits) ) ) ;
1631
+ check( BigUint :: new( ~[ -1 ] ) , ( 1 << ( 1 * BigDigit :: bits) ) - 1 ) ;
1632
+ check( BigUint :: new( ~[ 0 , 1 ] ) , ( 1 << ( 1 * BigDigit :: bits) ) ) ;
1633
+ check( BigUint :: new( ~[ -1 , -1 ] ) , ( 1 << ( 2 * BigDigit :: bits) ) - 1 ) ;
1634
+ check( BigUint :: new( ~[ 0 , 0 , 1 ] ) , ( 1 << ( 2 * BigDigit :: bits) ) ) ;
1635
+ check( BigUint :: new( ~[ -1 , -1 , -1 ] ) , ( 1 << ( 3 * BigDigit :: bits) ) - 1 ) ;
1636
+ check( BigUint :: new( ~[ 0 , 0 , 0 , 1 ] ) , ( 1 << ( 3 * BigDigit :: bits) ) ) ;
1637
+ check( BigUint :: new( ~[ -1 , -1 , -1 , -1 >> 1 ] ) , i64:: max_value) ;
1638
+
1639
+ assert_eq ! ( i64 :: min_value. to_biguint( ) , None ) ;
1640
+ assert_eq ! ( BigUint :: new( ~[ -1 , -1 , -1 , -1 ] ) . to_i64( ) , None ) ;
1641
+ assert_eq ! ( BigUint :: new( ~[ 0 , 0 , 0 , 0 , 1 ] ) . to_i64( ) , None ) ;
1642
+ assert_eq ! ( BigUint :: new( ~[ -1 , -1 , -1 , -1 , -1 ] ) . to_i64( ) , None ) ;
1643
+ }
1644
+
1645
+ #[ cfg( target_word_size = "64" ) ]
1615
1646
#[ test]
1616
- fn test_convert_int( ) {
1617
- fn check( v: ~[ BigDigit ] , i: int) {
1618
- let b1 = BigUint :: new( v) ;
1619
- let b2: BigUint = FromPrimitive :: from_int( i) . unwrap( ) ;
1647
+ fn test_convert_i64( ) {
1648
+ fn check( b1: BigUint , i: i64) {
1649
+ let b2: BigUint = FromPrimitive :: from_i64( i) . unwrap( ) ;
1650
+ assert ! ( b1 == b2) ;
1651
+ assert ! ( b1. to_i64( ) . unwrap( ) == i) ;
1652
+ }
1653
+
1654
+ check( Zero :: zero( ) , 0 ) ;
1655
+ check( One :: one( ) , 1 ) ;
1656
+ check( i64:: max_value. to_biguint( ) . unwrap( ) , i64:: max_value) ;
1657
+
1658
+ check( BigUint :: new( ~[ ] ) , 0 ) ;
1659
+ check( BigUint :: new( ~[ 1 ] ) , ( 1 << ( 0 * BigDigit :: bits) ) ) ;
1660
+ check( BigUint :: new( ~[ -1 ] ) , ( 1 << ( 1 * BigDigit :: bits) ) - 1 ) ;
1661
+ check( BigUint :: new( ~[ 0 , 1 ] ) , ( 1 << ( 1 * BigDigit :: bits) ) ) ;
1662
+ check( BigUint :: new( ~[ -1 , -1 >> 1 ] ) , i64:: max_value) ;
1663
+
1664
+ assert_eq ! ( i64 :: min_value. to_biguint( ) , None ) ;
1665
+ assert_eq ! ( BigUint :: new( ~[ -1 , -1 ] ) . to_i64( ) , None ) ;
1666
+ assert_eq ! ( BigUint :: new( ~[ 0 , 0 , 1 ] ) . to_i64( ) , None ) ;
1667
+ assert_eq ! ( BigUint :: new( ~[ -1 , -1 , -1 ] ) . to_i64( ) , None ) ;
1668
+ }
1669
+
1670
+ #[ cfg( target_word_size = "32" ) ]
1671
+ #[ test]
1672
+ fn test_convert_u64( ) {
1673
+ fn check( b1: BigUint , u: u64) {
1674
+ let b2: BigUint = FromPrimitive :: from_u64( u) . unwrap( ) ;
1620
1675
assert ! ( b1 == b2) ;
1621
- assert ! ( b1. to_int ( ) . unwrap( ) == i ) ;
1676
+ assert ! ( b1. to_u64 ( ) . unwrap( ) == u ) ;
1622
1677
}
1623
1678
1624
- check( ~[ ] , 0 ) ;
1625
- check( ~[ 1 ] , 1 ) ;
1626
- check( ~[ -1 ] , ( uint:: max_value >> BigDigit :: bits) as int) ;
1627
- check( ~[ 0 , 1 ] , ( ( uint:: max_value >> BigDigit :: bits) + 1 ) as int) ;
1628
- check( ~[ -1 , -1 >> 1 ] , int:: max_value) ;
1679
+ check( Zero :: zero( ) , 0 ) ;
1680
+ check( One :: one( ) , 1 ) ;
1681
+ check( u64:: min_value. to_biguint( ) . unwrap( ) , u64:: min_value) ;
1682
+ check( u64:: max_value. to_biguint( ) . unwrap( ) , u64:: max_value) ;
1683
+
1684
+ check( BigUint :: new( ~[ ] ) , 0 ) ;
1685
+ check( BigUint :: new( ~[ 1 ] ) , ( 1 << ( 0 * BigDigit :: bits) ) ) ;
1686
+ check( BigUint :: new( ~[ -1 ] ) , ( 1 << ( 1 * BigDigit :: bits) ) - 1 ) ;
1687
+ check( BigUint :: new( ~[ 0 , 1 ] ) , ( 1 << ( 1 * BigDigit :: bits) ) ) ;
1688
+ check( BigUint :: new( ~[ -1 , -1 ] ) , ( 1 << ( 2 * BigDigit :: bits) ) - 1 ) ;
1689
+ check( BigUint :: new( ~[ 0 , 0 , 1 ] ) , ( 1 << ( 2 * BigDigit :: bits) ) ) ;
1690
+ check( BigUint :: new( ~[ -1 , -1 , -1 ] ) , ( 1 << ( 3 * BigDigit :: bits) ) - 1 ) ;
1691
+ check( BigUint :: new( ~[ 0 , 0 , 0 , 1 ] ) , ( 1 << ( 3 * BigDigit :: bits) ) ) ;
1692
+ check( BigUint :: new( ~[ -1 , -1 , -1 , -1 ] ) , u64:: max_value) ;
1629
1693
1630
- assert_eq ! ( BigUint :: new( ~[ 0 , -1 ] ) . to_int( ) , None ) ;
1631
- assert_eq ! ( BigUint :: new( ~[ 0 , 0 , 1 ] ) . to_int( ) , None ) ;
1632
- assert_eq ! ( BigUint :: new( ~[ 0 , 0 , -1 ] ) . to_int( ) , None ) ;
1694
+ assert_eq ! ( BigUint :: new( ~[ 0 , 0 , 0 , 0 , 1 ] ) . to_u64( ) , None ) ;
1695
+ assert_eq ! ( BigUint :: new( ~[ -1 , -1 , -1 , -1 , -1 ] ) . to_u64( ) , None ) ;
1633
1696
}
1634
1697
1698
+ #[ cfg( target_word_size = "64" ) ]
1635
1699
#[ test]
1636
- fn test_convert_uint( ) {
1637
- fn check( v: ~[ BigDigit ] , u: uint) {
1638
- let b1 = BigUint :: new( v) ;
1639
- let b2: BigUint = FromPrimitive :: from_uint( u) . unwrap( ) ;
1700
+ fn test_convert_u64( ) {
1701
+ fn check( b1: BigUint , u: u64) {
1702
+ let b2: BigUint = FromPrimitive :: from_u64( u) . unwrap( ) ;
1640
1703
assert ! ( b1 == b2) ;
1641
- assert ! ( b1. to_uint ( ) . unwrap( ) == u) ;
1704
+ assert ! ( b1. to_u64 ( ) . unwrap( ) == u) ;
1642
1705
}
1643
1706
1644
- check( ~[ ] , 0 ) ;
1645
- check( ~[ 1 ] , 1 ) ;
1646
- check( ~[ -1 ] , uint:: max_value >> BigDigit :: bits) ;
1647
- check( ~[ 0 , 1 ] , ( uint:: max_value >> BigDigit :: bits) + 1 ) ;
1648
- check( ~[ 0 , -1 ] , uint:: max_value << BigDigit :: bits ) ;
1649
- check ( ~[ -1 , -1 ] , uint:: max_value ) ;
1707
+ check( Zero :: zero( ) , 0 ) ;
1708
+ check( One :: one( ) , 1 ) ;
1709
+ check( u64:: min_value. to_biguint( ) . unwrap( ) , u64:: min_value) ;
1710
+ check( u64:: max_value. to_biguint( ) . unwrap( ) , u64:: max_value) ;
1711
+
1712
+ check( BigUint :: new( ~[ ] ) , 0 ) ;
1713
+ check( BigUint :: new( ~[ 1 ] ) , ( 1 << ( 0 * BigDigit :: bits) ) ) ;
1714
+ check( BigUint :: new( ~[ -1 ] ) , ( 1 << ( 1 * BigDigit :: bits) ) - 1 ) ;
1715
+ check( BigUint :: new( ~[ 0 , 1 ] ) , ( 1 << ( 1 * BigDigit :: bits) ) ) ;
1716
+ check( BigUint :: new( ~[ -1 , -1 ] ) , u64:: max_value) ;
1650
1717
1651
- assert_eq ! ( BigUint :: new( ~[ 0 , 0 , 1 ] ) . to_uint ( ) , None ) ;
1652
- assert_eq ! ( BigUint :: new( ~[ 0 , 0 , -1 ] ) . to_uint ( ) , None ) ;
1718
+ assert_eq ! ( BigUint :: new( ~[ 0 , 0 , 1 ] ) . to_u64 ( ) , None ) ;
1719
+ assert_eq ! ( BigUint :: new( ~[ - 1 , - 1 , -1 ] ) . to_u64 ( ) , None ) ;
1653
1720
}
1654
1721
1655
1722
#[ test]
@@ -2025,10 +2092,11 @@ mod bigint_tests {
2025
2092
use super :: * ;
2026
2093
2027
2094
use std:: cmp:: { Less , Equal , Greater } ;
2028
- use std:: { int , i64, uint , u64 } ;
2095
+ use std:: i64;
2029
2096
use std:: num:: { Zero , One , FromStrRadix } ;
2030
2097
use std:: num:: { ToPrimitive , FromPrimitive } ;
2031
2098
use std:: rand:: { task_rng} ;
2099
+ use std:: u64;
2032
2100
2033
2101
#[ test]
2034
2102
fn test_from_biguint ( ) {
@@ -2086,59 +2154,6 @@ mod bigint_tests {
2086
2154
}
2087
2155
}
2088
2156
2089
- #[ test]
2090
- fn test_convert_int ( ) {
2091
- fn check ( b1 : BigInt , i : int ) {
2092
- let b2: BigInt = FromPrimitive :: from_int ( i) . unwrap ( ) ;
2093
- assert ! ( b1 == b2) ;
2094
- assert ! ( b1. to_int( ) . unwrap( ) == i) ;
2095
- }
2096
-
2097
- check ( Zero :: zero ( ) , 0 ) ;
2098
- check ( One :: one ( ) , 1 ) ;
2099
- check ( BigInt :: from_biguint (
2100
- Plus , FromPrimitive :: from_uint ( int:: max_value as uint ) . unwrap ( )
2101
- ) , int:: max_value) ;
2102
-
2103
- assert_eq ! ( BigInt :: from_biguint(
2104
- Plus , FromPrimitive :: from_uint( int:: max_value as uint + 1 ) . unwrap( )
2105
- ) . to_int( ) , None ) ;
2106
- assert_eq ! ( BigInt :: from_biguint(
2107
- Plus , BigUint :: new( ~[ 1 , 2 , 3 ] )
2108
- ) . to_int( ) , None ) ;
2109
-
2110
- check ( BigInt :: from_biguint (
2111
- Minus , BigUint :: new ( ~[ 0 , 1 <<( BigDigit :: bits-1 ) ] )
2112
- ) , int:: min_value) ;
2113
- assert_eq ! ( BigInt :: from_biguint(
2114
- Minus , BigUint :: new( ~[ 1 , 1 <<( BigDigit :: bits-1 ) ] )
2115
- ) . to_int( ) , None ) ;
2116
- assert_eq ! ( BigInt :: from_biguint(
2117
- Minus , BigUint :: new( ~[ 1 , 2 , 3 ] ) ) . to_int( ) , None ) ;
2118
- }
2119
-
2120
- #[ test]
2121
- fn test_convert_uint ( ) {
2122
- fn check ( b1 : BigInt , u : uint ) {
2123
- let b2: BigInt = FromPrimitive :: from_uint ( u) . unwrap ( ) ;
2124
- assert ! ( b1 == b2) ;
2125
- assert ! ( b1. to_uint( ) . unwrap( ) == u) ;
2126
- }
2127
-
2128
- check ( Zero :: zero ( ) , 0 ) ;
2129
- check ( One :: one ( ) , 1 ) ;
2130
-
2131
- check (
2132
- BigInt :: from_biguint ( Plus , FromPrimitive :: from_uint ( uint:: max_value) . unwrap ( ) ) ,
2133
- uint:: max_value) ;
2134
- assert_eq ! ( BigInt :: from_biguint(
2135
- Plus , BigUint :: new( ~[ 1 , 2 , 3 ] ) ) . to_uint( ) , None ) ;
2136
-
2137
- let max_value: BigUint = FromPrimitive :: from_uint ( uint:: max_value) . unwrap ( ) ;
2138
- assert_eq ! ( BigInt :: from_biguint( Minus , max_value) . to_uint( ) , None ) ;
2139
- assert_eq ! ( BigInt :: from_biguint( Minus , BigUint :: new( ~[ 1 , 2 , 3 ] ) ) . to_uint( ) , None ) ;
2140
- }
2141
-
2142
2157
#[ test]
2143
2158
fn test_convert_i64 ( ) {
2144
2159
fn check ( b1 : BigInt , i : i64 ) {
@@ -2153,19 +2168,15 @@ mod bigint_tests {
2153
2168
check ( i64:: max_value. to_bigint ( ) . unwrap ( ) , i64:: max_value) ;
2154
2169
2155
2170
assert_eq ! (
2156
- ( i64 :: max_value as uint + 1 ) . to_bigint( ) . unwrap( ) . to_i64( ) ,
2171
+ ( i64 :: max_value as u64 + 1 ) . to_bigint( ) . unwrap( ) . to_i64( ) ,
2157
2172
None ) ;
2158
2173
2159
2174
assert_eq ! (
2160
- BigInt :: from_biguint( Plus , BigUint :: new( ~[ 1 , 2 , 3 , 4 , 5 ] ) ) . to_i64( ) ,
2175
+ BigInt :: from_biguint( Plus , BigUint :: new( ~[ 1 , 2 , 3 , 4 , 5 ] ) ) . to_i64( ) ,
2161
2176
None ) ;
2162
2177
2163
- check (
2164
- BigInt :: from_biguint ( Minus , BigUint :: new ( ~[ 0 , 1 <<( BigDigit :: bits-1 ) ] ) ) ,
2165
- i64:: min_value) ;
2166
-
2167
2178
assert_eq ! (
2168
- BigInt :: from_biguint( Minus , BigUint :: new( ~[ 1 , 1 <<( BigDigit :: bits-1 ) ] ) ) . to_i64( ) ,
2179
+ BigInt :: from_biguint( Minus , BigUint :: new( ~[ 1 , 0 , 0 , 1 <<( BigDigit :: bits-1 ) ] ) ) . to_i64( ) ,
2169
2180
None ) ;
2170
2181
2171
2182
assert_eq ! (
@@ -2183,15 +2194,16 @@ mod bigint_tests {
2183
2194
2184
2195
check ( Zero :: zero ( ) , 0 ) ;
2185
2196
check ( One :: one ( ) , 1 ) ;
2197
+ check ( u64:: min_value. to_bigint ( ) . unwrap ( ) , u64:: min_value) ;
2186
2198
check ( u64:: max_value. to_bigint ( ) . unwrap ( ) , u64:: max_value) ;
2187
2199
2188
2200
assert_eq ! (
2189
- BigInt :: from_biguint( Plus , BigUint :: new( ~[ 1 , 2 , 3 , 4 , 5 ] ) ) . to_uint ( ) ,
2201
+ BigInt :: from_biguint( Plus , BigUint :: new( ~[ 1 , 2 , 3 , 4 , 5 ] ) ) . to_u64 ( ) ,
2190
2202
None ) ;
2191
2203
2192
- let max_value: BigUint = FromPrimitive :: from_uint ( uint :: max_value) . unwrap ( ) ;
2204
+ let max_value: BigUint = FromPrimitive :: from_u64 ( u64 :: max_value) . unwrap ( ) ;
2193
2205
assert_eq ! ( BigInt :: from_biguint( Minus , max_value) . to_u64( ) , None ) ;
2194
- assert_eq ! ( BigInt :: from_biguint( Minus , BigUint :: new( ~[ 1 , 2 , 3 ] ) ) . to_u64( ) , None ) ;
2206
+ assert_eq ! ( BigInt :: from_biguint( Minus , BigUint :: new( ~[ 1 , 2 , 3 , 4 , 5 ] ) ) . to_u64( ) , None ) ;
2195
2207
}
2196
2208
2197
2209
#[ test]
0 commit comments