1
1
use hexf_parse;
2
2
use num_bigint:: { BigInt , ToBigInt } ;
3
3
use num_rational:: Ratio ;
4
- use num_traits:: { float:: Float , sign:: Signed , ToPrimitive , Zero } ;
4
+ use num_traits:: { float:: Float , pow , sign:: Signed , ToPrimitive , Zero } ;
5
5
6
6
use super :: objbytes;
7
7
use super :: objint;
@@ -477,7 +477,6 @@ impl PyFloat {
477
477
}
478
478
}
479
479
} ;
480
-
481
480
if let Some ( ndigits) = ndigits {
482
481
if ndigits. is_zero ( ) {
483
482
let fract = self . value . fract ( ) ;
@@ -492,7 +491,29 @@ impl PyFloat {
492
491
} ;
493
492
Ok ( vm. ctx . new_float ( value) )
494
493
} else {
495
- Ok ( vm. ctx . not_implemented ( ) )
494
+ let ndigits = match ndigits {
495
+ ndigits if * ndigits > i32:: max_value ( ) . to_bigint ( ) . unwrap ( ) => i32:: max_value ( ) ,
496
+ ndigits if * ndigits < i32:: min_value ( ) . to_bigint ( ) . unwrap ( ) => i32:: min_value ( ) ,
497
+ _ => ndigits. to_i32 ( ) . unwrap ( ) ,
498
+ } ;
499
+ if ( self . value > 1e+16_f64 && ndigits >= 0i32 )
500
+ || ( ndigits + self . value . log10 ( ) . floor ( ) as i32 > 16i32 )
501
+ {
502
+ return Ok ( vm. ctx . new_float ( self . value ) ) ;
503
+ }
504
+ if ndigits >= 0i32 {
505
+ Ok ( vm. ctx . new_float (
506
+ ( self . value * pow ( 10.0 , ndigits as usize ) ) . round ( )
507
+ / pow ( 10.0 , ndigits as usize ) ,
508
+ ) )
509
+ } else {
510
+ let result = ( self . value / pow ( 10.0 , ( -ndigits) as usize ) ) . round ( )
511
+ * pow ( 10.0 , ( -ndigits) as usize ) ;
512
+ if result. is_nan ( ) {
513
+ return Ok ( vm. ctx . new_float ( 0.0 ) ) ;
514
+ }
515
+ Ok ( vm. ctx . new_float ( result) )
516
+ }
496
517
}
497
518
} else {
498
519
let fract = self . value . fract ( ) ;
0 commit comments