@@ -16,22 +16,41 @@ pub trait Float: Sized + Copy {
1616 /// Returns the bitwidth of the significand
1717 fn significand_bits ( ) -> u32 ;
1818
19+ /// Returns the bitwidth of the exponent
20+ fn exponent_bits ( ) -> u32 {
21+ Self :: bits ( ) - Self :: significand_bits ( ) - 1
22+ }
23+
24+ /// Returns a mask for the sign bit
25+ fn sign_mask ( ) -> Self :: Int ;
26+
27+ /// Returns a mask for the significand
28+ fn significand_mask ( ) -> Self :: Int ;
29+
30+ /// Returns a mask for the exponent
31+ fn exponent_mask ( ) -> Self :: Int ;
32+
1933 /// Returns `self` transmuted to `Self::Int`
2034 fn repr ( self ) -> Self :: Int ;
2135
2236 #[ cfg( test) ]
2337 /// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
24- /// represented in multiple different ways. This methods returns `true` if two NaNs are
38+ /// represented in multiple different ways. This method returns `true` if two NaNs are
2539 /// compared.
2640 fn eq_repr ( self , rhs : Self ) -> bool ;
2741
2842 /// Returns a `Self::Int` transmuted back to `Self`
2943 fn from_repr ( a : Self :: Int ) -> Self ;
3044
45+ /// Constructs a `Self` from its parts. Inputs are treated as bits and shifted into position.
46+ fn from_parts ( sign : bool , exponent : Self :: Int , significand : Self :: Int ) -> Self ;
47+
3148 /// Returns (normalized exponent, normalized significand)
3249 fn normalize ( significand : Self :: Int ) -> ( i32 , Self :: Int ) ;
3350}
3451
52+ // FIXME: Some of this can be removed if RFC Issue #1424 is resolved
53+ // https://github.com/rust-lang/rfcs/issues/1424
3554impl Float for f32 {
3655 type Int = u32 ;
3756 fn bits ( ) -> u32 {
@@ -40,6 +59,15 @@ impl Float for f32 {
4059 fn significand_bits ( ) -> u32 {
4160 23
4261 }
62+ fn sign_mask ( ) -> Self :: Int {
63+ 1 << ( Self :: bits ( ) - 1 )
64+ }
65+ fn significand_mask ( ) -> Self :: Int {
66+ ( 1 << Self :: significand_bits ( ) ) - 1
67+ }
68+ fn exponent_mask ( ) -> Self :: Int {
69+ !( Self :: sign_mask ( ) | Self :: significand_mask ( ) )
70+ }
4371 fn repr ( self ) -> Self :: Int {
4472 unsafe { mem:: transmute ( self ) }
4573 }
@@ -54,6 +82,11 @@ impl Float for f32 {
5482 fn from_repr ( a : Self :: Int ) -> Self {
5583 unsafe { mem:: transmute ( a) }
5684 }
85+ fn from_parts ( sign : bool , exponent : Self :: Int , significand : Self :: Int ) -> Self {
86+ Self :: from_repr ( ( ( sign as Self :: Int ) << ( Self :: bits ( ) - 1 ) ) |
87+ ( ( exponent << Self :: significand_bits ( ) ) & Self :: exponent_mask ( ) ) |
88+ ( significand & Self :: significand_mask ( ) ) )
89+ }
5790 fn normalize ( significand : Self :: Int ) -> ( i32 , Self :: Int ) {
5891 let shift = significand. leading_zeros ( )
5992 . wrapping_sub ( ( 1u32 << Self :: significand_bits ( ) ) . leading_zeros ( ) ) ;
@@ -68,6 +101,15 @@ impl Float for f64 {
68101 fn significand_bits ( ) -> u32 {
69102 52
70103 }
104+ fn sign_mask ( ) -> Self :: Int {
105+ 1 << ( Self :: bits ( ) - 1 )
106+ }
107+ fn significand_mask ( ) -> Self :: Int {
108+ ( 1 << Self :: significand_bits ( ) ) - 1
109+ }
110+ fn exponent_mask ( ) -> Self :: Int {
111+ !( Self :: sign_mask ( ) | Self :: significand_mask ( ) )
112+ }
71113 fn repr ( self ) -> Self :: Int {
72114 unsafe { mem:: transmute ( self ) }
73115 }
@@ -82,6 +124,11 @@ impl Float for f64 {
82124 fn from_repr ( a : Self :: Int ) -> Self {
83125 unsafe { mem:: transmute ( a) }
84126 }
127+ fn from_parts ( sign : bool , exponent : Self :: Int , significand : Self :: Int ) -> Self {
128+ Self :: from_repr ( ( ( sign as Self :: Int ) << ( Self :: bits ( ) - 1 ) ) |
129+ ( ( exponent << Self :: significand_bits ( ) ) & Self :: exponent_mask ( ) ) |
130+ ( significand & Self :: significand_mask ( ) ) )
131+ }
85132 fn normalize ( significand : Self :: Int ) -> ( i32 , Self :: Int ) {
86133 let shift = significand. leading_zeros ( )
87134 . wrapping_sub ( ( 1u64 << Self :: significand_bits ( ) ) . leading_zeros ( ) ) ;
0 commit comments