@@ -1244,6 +1244,104 @@ from_primitive_integer!(u64, approximate_float_unsigned);
1244
1244
from_primitive_integer ! ( u128 , approximate_float_unsigned) ;
1245
1245
from_primitive_integer ! ( usize , approximate_float_unsigned) ;
1246
1246
1247
+ macro_rules! try_from_impl {
1248
+ ( $typ: ty, $approx: ident) => {
1249
+ // impl TryFrom<i32> for Ratio<$typ> {
1250
+ // type Error = ();
1251
+ // fn try_from(n: i32) -> Result<Self, ()> {
1252
+ // <$typ as FromPrimitive>::from_i32(n)
1253
+ // .map(Ratio::from_integer)
1254
+ // .ok_or(())
1255
+ // }
1256
+ // }
1257
+
1258
+ impl TryFrom <i64 > for Ratio <$typ> {
1259
+ type Error = ( ) ;
1260
+ fn try_from( n: i64 ) -> Result <Self , ( ) > {
1261
+ <$typ as FromPrimitive >:: from_i64( n)
1262
+ . map( Ratio :: from_integer)
1263
+ . ok_or( ( ) )
1264
+ }
1265
+ }
1266
+
1267
+ impl TryFrom <i128 > for Ratio <$typ> {
1268
+ type Error = ( ) ;
1269
+ fn try_from( n: i128 ) -> Result <Self , ( ) > {
1270
+ <$typ as FromPrimitive >:: from_i128( n)
1271
+ . map( Ratio :: from_integer)
1272
+ . ok_or( ( ) )
1273
+ }
1274
+ }
1275
+
1276
+ // impl TryFrom<u32> for Ratio<$typ> {
1277
+ // type Error = ();
1278
+ // fn try_from(n: u32) -> Result<Self, ()> {
1279
+ // <$typ as FromPrimitive>::from_u32(n)
1280
+ // .map(Ratio::from_integer)
1281
+ // .ok_or(())
1282
+ // }
1283
+ // }
1284
+
1285
+ impl TryFrom <u64 > for Ratio <$typ> {
1286
+ type Error = ( ) ;
1287
+ fn try_from( n: u64 ) -> Result <Self , ( ) > {
1288
+ <$typ as FromPrimitive >:: from_u64( n)
1289
+ . map( Ratio :: from_integer)
1290
+ . ok_or( ( ) )
1291
+ }
1292
+ }
1293
+
1294
+ impl TryFrom <u128 > for Ratio <$typ> {
1295
+ type Error = ( ) ;
1296
+ fn try_from( n: u128 ) -> Result <Self , ( ) > {
1297
+ <$typ as FromPrimitive >:: from_u128( n)
1298
+ . map( Ratio :: from_integer)
1299
+ . ok_or( ( ) )
1300
+ }
1301
+ }
1302
+
1303
+ impl TryFrom <f32 > for Ratio <$typ> {
1304
+ type Error = ( ) ;
1305
+ fn try_from( n: f32 ) -> Result <Self , ( ) > {
1306
+ $approx( n, 10e-20 , 30 ) . ok_or( ( ) )
1307
+ }
1308
+ }
1309
+
1310
+ impl TryFrom <f64 > for Ratio <$typ> {
1311
+ type Error = ( ) ;
1312
+ fn try_from( n: f64 ) -> Result <Self , ( ) > {
1313
+ $approx( n, 10e-20 , 30 ) . ok_or( ( ) )
1314
+ }
1315
+ }
1316
+ } ;
1317
+ }
1318
+ use std:: convert:: TryFrom ;
1319
+
1320
+ // TODO
1321
+ // need to exclude generation of the version for the same value
1322
+ try_from_impl ! ( i8 , approximate_float) ;
1323
+ try_from_impl ! ( i16 , approximate_float) ;
1324
+ try_from_impl ! ( i32 , approximate_float) ;
1325
+ // try_from_impl!(i64, approximate_float);
1326
+ // try_from_impl!(i128, approximate_float);
1327
+ try_from_impl ! ( isize , approximate_float) ;
1328
+
1329
+ try_from_impl ! ( u8 , approximate_float_unsigned) ;
1330
+ try_from_impl ! ( u16 , approximate_float_unsigned) ;
1331
+ try_from_impl ! ( u32 , approximate_float_unsigned) ;
1332
+ // try_from_impl!(u64, approximate_float_unsigned);
1333
+ // try_from_impl!(u128, approximate_float_unsigned);
1334
+ try_from_impl ! ( usize , approximate_float_unsigned) ;
1335
+
1336
+ #[ test]
1337
+ fn try_from_impl ( ) {
1338
+ debug_assert_eq ! ( Err ( ( ) ) , Ratio :: <i8 >:: try_from( 1000000i64 ) ) ;
1339
+ debug_assert_eq ! (
1340
+ Ok ( Ratio :: <i8 >:: from_integer( 11 ) ) ,
1341
+ Ratio :: <i8 >:: try_from( 11i64 )
1342
+ ) ;
1343
+ }
1344
+
1247
1345
impl < T : Integer + Signed + Bounded + NumCast + Clone > Ratio < T > {
1248
1346
pub fn approximate_float < F : FloatCore + NumCast > ( f : F ) -> Option < Ratio < T > > {
1249
1347
// 1/10e-20 < 1/2**32 which seems like a good default, and 30 seems
@@ -2205,13 +2303,10 @@ mod test {
2205
2303
let big = T :: max_value ( ) / two. clone ( ) / two. clone ( ) * two. clone ( ) ;
2206
2304
let _1_big: Ratio < T > = Ratio :: new ( T :: one ( ) , big. clone ( ) ) ;
2207
2305
let _2_3: Ratio < T > = Ratio :: new ( two. clone ( ) , _3. clone ( ) ) ;
2208
- assert_eq ! ( None , big. clone ( ) . checked_mul( & _3. clone ( ) ) ) ;
2306
+ assert_eq ! ( None , big. checked_mul( & _3) ) ;
2209
2307
let expected = Ratio :: new ( T :: one ( ) , big / two. clone ( ) * _3. clone ( ) ) ;
2210
- assert_eq ! ( expected. clone( ) , _1_big. clone( ) * _2_3. clone( ) ) ;
2211
- assert_eq ! (
2212
- Some ( expected. clone( ) ) ,
2213
- _1_big. clone( ) . checked_mul( & _2_3. clone( ) )
2214
- ) ;
2308
+ assert_eq ! ( expected, _1_big. clone( ) * _2_3. clone( ) ) ;
2309
+ assert_eq ! ( Some ( expected. clone( ) ) , _1_big. checked_mul( & _2_3) ) ;
2215
2310
assert_eq ! ( expected, {
2216
2311
let mut tmp = _1_big;
2217
2312
tmp *= _2_3;
@@ -2221,7 +2316,7 @@ mod test {
2221
2316
// big/3 * 3 = big/1
2222
2317
// make big = max/2, but make it indivisible by 3
2223
2318
let big = T :: max_value ( ) / two / _3. clone ( ) * _3. clone ( ) + T :: one ( ) ;
2224
- assert_eq ! ( None , big. clone ( ) . checked_mul( & _3. clone ( ) ) ) ;
2319
+ assert_eq ! ( None , big. checked_mul( & _3) ) ;
2225
2320
let big_3 = Ratio :: new ( big. clone ( ) , _3. clone ( ) ) ;
2226
2321
let expected = Ratio :: new ( big, T :: one ( ) ) ;
2227
2322
assert_eq ! ( expected, big_3. clone( ) * _3. clone( ) ) ;
@@ -2292,15 +2387,12 @@ mod test {
2292
2387
// 1/big / 3/2 = 1/(max/4*3), where big is max/2
2293
2388
// big ~ max/2, and big is divisible by 2
2294
2389
let big = T :: max_value ( ) / two. clone ( ) / two. clone ( ) * two. clone ( ) ;
2295
- assert_eq ! ( None , big. clone ( ) . checked_mul( & _3. clone ( ) ) ) ;
2390
+ assert_eq ! ( None , big. checked_mul( & _3) ) ;
2296
2391
let _1_big: Ratio < T > = Ratio :: new ( T :: one ( ) , big. clone ( ) ) ;
2297
2392
let _3_two: Ratio < T > = Ratio :: new ( _3. clone ( ) , two. clone ( ) ) ;
2298
2393
let expected = Ratio :: new ( T :: one ( ) , big / two. clone ( ) * _3. clone ( ) ) ;
2299
- assert_eq ! ( expected. clone( ) , _1_big. clone( ) / _3_two. clone( ) ) ;
2300
- assert_eq ! (
2301
- Some ( expected. clone( ) ) ,
2302
- _1_big. clone( ) . checked_div( & _3_two. clone( ) )
2303
- ) ;
2394
+ assert_eq ! ( expected, _1_big. clone( ) / _3_two. clone( ) ) ;
2395
+ assert_eq ! ( Some ( expected. clone( ) ) , _1_big. checked_div( & _3_two) ) ;
2304
2396
assert_eq ! ( expected, {
2305
2397
let mut tmp = _1_big;
2306
2398
tmp /= _3_two;
@@ -2310,7 +2402,7 @@ mod test {
2310
2402
// 3/big / 3 = 1/big where big is max/2
2311
2403
// big ~ max/2, and big is not divisible by 3
2312
2404
let big = T :: max_value ( ) / two / _3. clone ( ) * _3. clone ( ) + T :: one ( ) ;
2313
- assert_eq ! ( None , big. clone ( ) . checked_mul( & _3. clone ( ) ) ) ;
2405
+ assert_eq ! ( None , big. checked_mul( & _3) ) ;
2314
2406
let _3_big = Ratio :: new ( _3. clone ( ) , big. clone ( ) ) ;
2315
2407
let expected = Ratio :: new ( T :: one ( ) , big) ;
2316
2408
assert_eq ! ( expected, _3_big. clone( ) / _3. clone( ) ) ;
@@ -2688,8 +2780,8 @@ mod test {
2688
2780
1.0 / 2f32 . powf ( 100. ) ,
2689
2781
( "1" , "1267650600228229401496703205376" ) ,
2690
2782
) ;
2691
- test ( 684729.48391f32 , ( "1369459" , "2" ) ) ;
2692
- test ( -8573.5918555f32 , ( "-4389679" , "512" ) ) ;
2783
+ test ( 684_729.5_f32 , ( "1369459" , "2" ) ) ;
2784
+ test ( -8_573.592_f32 , ( "-4389679" , "512" ) ) ;
2693
2785
2694
2786
// f64
2695
2787
test (
0 commit comments