@@ -44,6 +44,9 @@ pub enum Decimal32ConversionError {
44
44
CoefficientScalingFailedError ,
45
45
#[ error( "The base value for setting the sign for converting the Decimal32 into bytes must be zero." ) ]
46
46
SignSettingValueIsNotZero ,
47
+ #[ error( "The base value for setting the exponent was not 0x80000000 or 0x00000000." ) ]
48
+ IllegalBaseValueForExponentSetting ,
49
+
47
50
}
48
51
49
52
type ConversionError = Decimal32ConversionError ;
@@ -77,11 +80,24 @@ fn set_sign_bit(mut result: u32, sign: Sign) -> Result<u32, ConversionError> {
77
80
}
78
81
}
79
82
83
+ /// the wikipedia article at https://en.wikipedia.org/wiki/Decimal32_floating-point_format
84
+ /// describes decoding a decimal32. in this case we are encoding and thus have to think the other way around
85
+ /// if the significant's MSB is 0 then left shift significand by 1 (leading zero becomes implicit)
86
+ /// and exponent mus start with bits 00, 01 or 10.
87
+ /// if significand's 3 MSB are 100, left shift it by 3 to make the 100 implicit
88
+ /// and insert 11 after the sign bit and right shift exponent field by 2 to preserve
89
+ /// the two added bits.
80
90
fn set_exponent_bits ( mut result : u32 , exp : i64 ) -> Result < u32 , ConversionError > {
91
+ if result != 0x8000_0000 && result != 0x0000_0000 {
92
+ return Err ( Decimal32ConversionError :: IllegalBaseValueForExponentSetting ) ;
93
+ }
81
94
match exp {
82
95
_ if exp < EXPONENT_MIN => Err ( Decimal32ConversionError :: ExponentUnderflow ) ,
83
96
_ if exp > EXPONENT_MAX => Err ( Decimal32ConversionError :: ExponentOverflow ) ,
84
97
x => {
98
+ let mut unsigned_exponent: u32 = ( exp + EXPONENT_BIAS ) . try_into ( ) . unwrap ( ) ;
99
+ unsigned_exponent <<= 20 ;
100
+ result = result | unsigned_exponent;
85
101
Ok ( result)
86
102
}
87
103
}
@@ -128,22 +144,21 @@ mod test {
128
144
129
145
#[ test]
130
146
fn set_exponent_bits_works ( ) {
131
- assert_eq ! ( set_exponent_bits( 0x80000000 , 1 ) . unwrap( ) , 0x86600000 ) ;
132
- assert_eq ! ( set_exponent_bits( 0x80000000 , 2 ) . unwrap( ) , 0x86700000 ) ;
133
- assert_eq ! ( set_exponent_bits( 0x80000000 , 8 ) . unwrap( ) , 0x86D00000 ) ;
134
- assert_eq ! ( set_exponent_bits( 0x80000000 , 16 ) . unwrap( ) , 0x87500000 ) ;
135
- assert_eq ! ( set_exponent_bits( 0x80000000 , 32 ) . unwrap( ) , 0x88500000 ) ;
136
- assert_eq ! ( set_exponent_bits( 0x80000000 , 64 ) . unwrap( ) , 0x8A500000 ) ;
137
- assert_eq ! ( set_exponent_bits( 0x80000000 , 96 ) . unwrap( ) , 0x8C500000 ) ;
138
- assert_eq ! ( set_exponent_bits( 0x80000000 , 0 ) . unwrap( ) , 0x86500000 ) ;
139
- assert_eq ! ( set_exponent_bits( 0x80000000 , -1 ) . unwrap( ) , 0x86400000 ) ;
140
- // TODO continue here
141
- assert_eq ! ( set_exponent_bits( 0x80000000 , -2 ) . unwrap( ) , 0x86600000 ) ;
142
- assert_eq ! ( set_exponent_bits( 0x80000000 , -8 ) . unwrap( ) , 0x86600000 ) ;
143
- assert_eq ! ( set_exponent_bits( 0x80000000 , -16 ) . unwrap( ) , 0x86600000 ) ;
144
- assert_eq ! ( set_exponent_bits( 0x80000000 , -32 ) . unwrap( ) , 0x86600000 ) ;
145
- assert_eq ! ( set_exponent_bits( 0x80000000 , -64 ) . unwrap( ) , 0x86600000 ) ;
146
- assert_eq ! ( set_exponent_bits( 0x80000000 , -95 ) . unwrap( ) , 0x86600000 ) ;
147
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , 96 ) . unwrap( ) ) , format!( "{:#b}" , 0x8C50_0000u32 ) ) ;
148
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , 64 ) . unwrap( ) ) , format!( "{:#b}" , 0x8A50_0000u32 ) ) ;
149
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , 32 ) . unwrap( ) ) , format!( "{:#b}" , 0x8850_0000u32 ) ) ;
150
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , 16 ) . unwrap( ) ) , format!( "{:#b}" , 0x8750_0000u32 ) ) ;
151
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , 8 ) . unwrap( ) ) , format!( "{:#b}" , 0x86D0_0000u32 ) ) ;
152
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , 2 ) . unwrap( ) ) , format!( "{:#b}" , 0x8670_0000u32 ) ) ;
153
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , 1 ) . unwrap( ) ) , format!( "{:#b}" , 0x8660_0000u32 ) ) ;
154
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , 0 ) . unwrap( ) ) , format!( "{:#b}" , 0x8650_0000u32 ) ) ;
155
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , -1 ) . unwrap( ) ) , format!( "{:#b}" , 0x8640_0000u32 ) ) ;
156
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , -2 ) . unwrap( ) ) , format!( "{:#b}" , 0x8630_0000u32 ) ) ;
157
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , -8 ) . unwrap( ) ) , format!( "{:#b}" , 0x85C0_0000u32 ) ) ;
158
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , -16 ) . unwrap( ) ) , format!( "{:#b}" , 0x8550_0000u32 ) ) ;
159
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , -32 ) . unwrap( ) ) , format!( "{:#b}" , 0x8450_0000u32 ) ) ;
160
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , -64 ) . unwrap( ) ) , format!( "{:#b}" , 0x8250_0000u32 ) ) ;
161
+ assert_eq ! ( format!( "{:#b}" , set_exponent_bits( 0x8000_0000 , -95 ) . unwrap( ) ) , format!( "{:#b}" , 0x8060_0000u32 ) ) ;
147
162
}
148
163
149
164
}
0 commit comments