This repository was archived by the owner on Apr 28, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 9 files changed +81
-89
lines changed Expand file tree Collapse file tree 9 files changed +81
-89
lines changed Original file line number Diff line number Diff line change 450450 "frexp" : {
451451 "sources" : [
452452 " src/libm_helper.rs" ,
453- " src/math/frexp.rs"
453+ " src/math/frexp.rs" ,
454+ " src/math/generic/frexp.rs"
454455 ],
455456 "type" : " f64"
456457 },
457458 "frexpf" : {
458459 "sources" : [
459- " src/math/frexpf.rs"
460+ " src/math/frexpf.rs" ,
461+ " src/math/generic/frexp.rs"
460462 ],
461463 "type" : " f32"
462464 },
476478 "ilogb" : {
477479 "sources" : [
478480 " src/libm_helper.rs" ,
481+ " src/math/generic/ilogb.rs" ,
479482 " src/math/ilogb.rs"
480483 ],
481484 "type" : " f64"
482485 },
483486 "ilogbf" : {
484487 "sources" : [
488+ " src/math/generic/ilogb.rs" ,
485489 " src/math/ilogbf.rs"
486490 ],
487491 "type" : " f32"
Original file line number Diff line number Diff line change 1+ /// Decompose a float into a normalized value within the range `[0.5, 1)`, and a power of 2.
2+ ///
3+ /// That is, `x * 2^p` will represent the input value.
4+ #[ cfg_attr( all( test, assert_no_panic) , no_panic:: no_panic) ]
15pub fn frexp ( x : f64 ) -> ( f64 , i32 ) {
2- let mut y = x. to_bits ( ) ;
3- let ee = ( ( y >> 52 ) & 0x7ff ) as i32 ;
4-
5- if ee == 0 {
6- if x != 0.0 {
7- let x1p64 = f64:: from_bits ( 0x43f0000000000000 ) ;
8- let ( x, e) = frexp ( x * x1p64) ;
9- return ( x, e - 64 ) ;
10- }
11- return ( x, 0 ) ;
12- } else if ee == 0x7ff {
13- return ( x, 0 ) ;
14- }
15-
16- let e = ee - 0x3fe ;
17- y &= 0x800fffffffffffff ;
18- y |= 0x3fe0000000000000 ;
19- return ( f64:: from_bits ( y) , e) ;
6+ super :: generic:: frexp ( x)
207}
Original file line number Diff line number Diff line change 1+ /// Decompose a float into a normalized value within the range `[0.5, 1)`, and a power of 2.
2+ ///
3+ /// That is, `x * 2^p` will represent the input value.
4+ #[ cfg_attr( all( test, assert_no_panic) , no_panic:: no_panic) ]
15pub fn frexpf ( x : f32 ) -> ( f32 , i32 ) {
2- let mut y = x. to_bits ( ) ;
3- let ee: i32 = ( ( y >> 23 ) & 0xff ) as i32 ;
4-
5- if ee == 0 {
6- if x != 0.0 {
7- let x1p64 = f32:: from_bits ( 0x5f800000 ) ;
8- let ( x, e) = frexpf ( x * x1p64) ;
9- return ( x, e - 64 ) ;
10- } else {
11- return ( x, 0 ) ;
12- }
13- } else if ee == 0xff {
14- return ( x, 0 ) ;
15- }
16-
17- let e = ee - 0x7e ;
18- y &= 0x807fffff ;
19- y |= 0x3f000000 ;
20- ( f32:: from_bits ( y) , e)
6+ super :: generic:: frexp ( x)
217}
Original file line number Diff line number Diff line change 1+ use super :: super :: { CastFrom , Float , MinInt } ;
2+
3+ pub fn frexp < F : Float > ( x : F ) -> ( F , i32 ) {
4+ let mut ix = x. to_bits ( ) ;
5+ let ee = x. exp ( ) ;
6+
7+ if ee == 0 {
8+ if x != F :: ZERO {
9+ // normalize via multiplication; 1p64 for `f64`
10+ let magic = F :: from_parts ( false , F :: EXP_BIAS + F :: BITS , F :: Int :: ZERO ) ;
11+ magic. to_bits ( ) ;
12+
13+ let ( x, e) = frexp ( x * magic) ;
14+ return ( x, e - F :: BITS as i32 ) ;
15+ }
16+ return ( x, 0 ) ;
17+ } else if ee == F :: EXP_MAX {
18+ return ( x, 0 ) ;
19+ }
20+
21+ let e = ee as i32 - ( F :: EXP_BIAS as i32 - 1 ) ;
22+ ix &= F :: SIGN_MASK | F :: SIG_MASK ;
23+ ix |= F :: Int :: cast_from ( F :: EXP_BIAS - 1 ) << F :: SIG_BITS ;
24+ ( F :: from_bits ( ix) , e)
25+ }
Original file line number Diff line number Diff line change 1+ use super :: super :: { Float , MinInt } ;
2+
3+ const FP_ILOGBNAN : i32 = i32:: MIN ;
4+ const FP_ILOGB0 : i32 = FP_ILOGBNAN ;
5+
6+ pub fn ilogb < F : Float > ( x : F ) -> i32 {
7+ let zero = F :: Int :: ZERO ;
8+ let mut i = x. to_bits ( ) ;
9+ let e = x. exp ( ) as i32 ;
10+
11+ if e == 0 {
12+ i <<= F :: EXP_BITS + 1 ;
13+ if i == F :: Int :: ZERO {
14+ force_eval ! ( 0.0 / 0.0 ) ;
15+ return FP_ILOGB0 ;
16+ }
17+ /* subnormal x */
18+ let mut e = -( F :: EXP_BIAS as i32 ) ;
19+ while i >> ( F :: BITS - 1 ) == zero {
20+ e -= 1 ;
21+ i <<= 1 ;
22+ }
23+ e
24+ } else if e == F :: EXP_MAX as i32 {
25+ force_eval ! ( 0.0 / 0.0 ) ;
26+ if i << ( F :: EXP_BITS + 1 ) != zero { FP_ILOGBNAN } else { i32:: MAX }
27+ } else {
28+ e - F :: EXP_BIAS as i32
29+ }
30+ }
Original file line number Diff line number Diff line change @@ -5,6 +5,8 @@ mod fdim;
55mod floor;
66mod fmax;
77mod fmin;
8+ mod frexp;
9+ mod ilogb;
810mod rint;
911mod round;
1012mod scalbn;
@@ -18,6 +20,8 @@ pub use fdim::fdim;
1820pub use floor:: floor;
1921pub use fmax:: fmax;
2022pub use fmin:: fmin;
23+ pub use frexp:: frexp;
24+ pub use ilogb:: ilogb;
2125pub use rint:: rint;
2226pub use round:: round;
2327pub use scalbn:: scalbn;
Original file line number Diff line number Diff line change 1- const FP_ILOGBNAN : i32 = -1 - 0x7fffffff ;
2- const FP_ILOGB0 : i32 = FP_ILOGBNAN ;
3-
1+ /// Extract the binary exponent of `x`.
42#[ cfg_attr( all( test, assert_no_panic) , no_panic:: no_panic) ]
53pub fn ilogb ( x : f64 ) -> i32 {
6- let mut i: u64 = x. to_bits ( ) ;
7- let e = ( ( i >> 52 ) & 0x7ff ) as i32 ;
8-
9- if e == 0 {
10- i <<= 12 ;
11- if i == 0 {
12- force_eval ! ( 0.0 / 0.0 ) ;
13- return FP_ILOGB0 ;
14- }
15- /* subnormal x */
16- let mut e = -0x3ff ;
17- while ( i >> 63 ) == 0 {
18- e -= 1 ;
19- i <<= 1 ;
20- }
21- e
22- } else if e == 0x7ff {
23- force_eval ! ( 0.0 / 0.0 ) ;
24- if ( i << 12 ) != 0 { FP_ILOGBNAN } else { i32:: MAX }
25- } else {
26- e - 0x3ff
27- }
4+ super :: generic:: ilogb ( x)
285}
Original file line number Diff line number Diff line change 1- const FP_ILOGBNAN : i32 = -1 - 0x7fffffff ;
2- const FP_ILOGB0 : i32 = FP_ILOGBNAN ;
3-
1+ /// Extract the binary exponent of `x`.
42#[ cfg_attr( all( test, assert_no_panic) , no_panic:: no_panic) ]
53pub fn ilogbf ( x : f32 ) -> i32 {
6- let mut i = x. to_bits ( ) ;
7- let e = ( ( i >> 23 ) & 0xff ) as i32 ;
8-
9- if e == 0 {
10- i <<= 9 ;
11- if i == 0 {
12- force_eval ! ( 0.0 / 0.0 ) ;
13- return FP_ILOGB0 ;
14- }
15- /* subnormal x */
16- let mut e = -0x7f ;
17- while ( i >> 31 ) == 0 {
18- e -= 1 ;
19- i <<= 1 ;
20- }
21- e
22- } else if e == 0xff {
23- force_eval ! ( 0.0 / 0.0 ) ;
24- if ( i << 9 ) != 0 { FP_ILOGBNAN } else { i32:: MAX }
25- } else {
26- e - 0x7f
27- }
4+ super :: generic:: ilogb ( x)
285}
Original file line number Diff line number Diff line change @@ -45,6 +45,8 @@ pub trait Int:
4545 + ops:: BitOrAssign
4646 + ops:: BitXorAssign
4747 + ops:: ShlAssign < i32 >
48+ + ops:: ShlAssign < u32 >
49+ + ops:: ShrAssign < i32 >
4850 + ops:: ShrAssign < u32 >
4951 + ops:: Add < Output = Self >
5052 + ops:: Sub < Output = Self >
You can’t perform that action at this time.
0 commit comments