Skip to content

Commit f536781

Browse files
added comment to describe proper procedure for encoding
1 parent 30130bc commit f536781

File tree

1 file changed

+31
-16
lines changed

1 file changed

+31
-16
lines changed

amqp-type/src/fixed_width/decimal32.rs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ pub enum Decimal32ConversionError {
4444
CoefficientScalingFailedError,
4545
#[error("The base value for setting the sign for converting the Decimal32 into bytes must be zero.")]
4646
SignSettingValueIsNotZero,
47+
#[error("The base value for setting the exponent was not 0x80000000 or 0x00000000.")]
48+
IllegalBaseValueForExponentSetting,
49+
4750
}
4851

4952
type ConversionError = Decimal32ConversionError;
@@ -77,11 +80,24 @@ fn set_sign_bit(mut result: u32, sign: Sign) -> Result<u32, ConversionError> {
7780
}
7881
}
7982

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.
8090
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+
}
8194
match exp {
8295
_ if exp < EXPONENT_MIN => Err(Decimal32ConversionError::ExponentUnderflow),
8396
_ if exp > EXPONENT_MAX => Err(Decimal32ConversionError::ExponentOverflow),
8497
x => {
98+
let mut unsigned_exponent: u32 = (exp + EXPONENT_BIAS).try_into().unwrap();
99+
unsigned_exponent <<= 20;
100+
result = result | unsigned_exponent;
85101
Ok(result)
86102
}
87103
}
@@ -128,22 +144,21 @@ mod test {
128144

129145
#[test]
130146
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));
147162
}
148163

149164
}

0 commit comments

Comments
 (0)