aws_smithy_types::BigDecimal stores the original input string and derives PartialEq, Eq, and Hash. As a result, different spellings of the same number compare as different values.
Reproduction
use aws_smithy_types::BigDecimal;
use std::str::FromStr;
#[test]
fn numerically_equal_big_decimals_compare_equal() {
let scientific = BigDecimal::from_str("1e2").unwrap();
let plain = BigDecimal::from_str("100").unwrap();
assert_eq!(scientific, plain);
}
This currently fails because equality compares the stored strings "1e2" and "100" rather than their numeric values.
Other examples include:
- 1.0 and 1.00
- +5 and 5
- -0.0 and 0
- .5 and 0.5
This was brought up while adding BigDecimal support for CBOR in #4820. CBOR decimal fractions contain an exponent and mantissa, not the original source string. A round trip can change the spelling. CBOR cannot recover every original spelling because values such as +5 and 5 have the same exponent and mantissa.
The underlying issue is not specific to CBOR. Other protocols can also encounter it when a service returns an equivalent number using different formatting.
Expected behavior
Numerically equal BigDecimal values should compare and hash equally, regardless of how they were written.
The implementation should also define whether as_ref() continues to return the original spelling or returns a canonical representation. Preserving the original spelling would be preferred for backwards compatibility with existing serialization behavior.
aws_smithy_types::BigDecimalstores the original input string and derivesPartialEq,Eq, andHash. As a result, different spellings of the same number compare as different values.Reproduction
This currently fails because equality compares the stored strings "1e2" and "100" rather than their numeric values.
Other examples include:
This was brought up while adding BigDecimal support for CBOR in #4820. CBOR decimal fractions contain an exponent and mantissa, not the original source string. A round trip can change the spelling. CBOR cannot recover every original spelling because values such as +5 and 5 have the same exponent and mantissa.
The underlying issue is not specific to CBOR. Other protocols can also encounter it when a service returns an equivalent number using different formatting.
Expected behavior
Numerically equal BigDecimal values should compare and hash equally, regardless of how they were written.
The implementation should also define whether as_ref() continues to return the original spelling or returns a canonical representation. Preserving the original spelling would be preferred for backwards compatibility with existing serialization behavior.