diff --git a/Sources/RawStructuredFieldValues/PseudoDecimal.swift b/Sources/RawStructuredFieldValues/PseudoDecimal.swift index e5cf92c..d2c2ec4 100644 --- a/Sources/RawStructuredFieldValues/PseudoDecimal.swift +++ b/Sources/RawStructuredFieldValues/PseudoDecimal.swift @@ -226,6 +226,7 @@ extension String { // Swift Numerics would let us do this for all the floating point types. extension Double { public init(_ pseudoDecimal: PseudoDecimal) { - self = Double(pseudoDecimal.mantissa) * pow(10, Double(pseudoDecimal.exponent)) + // Divide by an exact power of ten: multiplying by an inexact negative power of ten rounds twice. + self = Double(pseudoDecimal.mantissa) / pow(10, -Double(pseudoDecimal.exponent)) } } diff --git a/Tests/StructuredFieldValuesTests/StructuredFieldDecoderTests.swift b/Tests/StructuredFieldValuesTests/StructuredFieldDecoderTests.swift index d56350a..5082d9c 100644 --- a/Tests/StructuredFieldValuesTests/StructuredFieldDecoderTests.swift +++ b/Tests/StructuredFieldValuesTests/StructuredFieldDecoderTests.swift @@ -182,6 +182,14 @@ final class StructuredFieldDecoderTests: XCTestCase { XCTAssertEqual(ItemField(Double(5.0)), try StructuredFieldValueDecoder().decode(from: Array(headerField.utf8))) } + func testDecodingDecimalAsDoubleIsCorrectlyRounded() throws { + XCTAssertEqual(ItemField(Double(0.3)), try StructuredFieldValueDecoder().decode(from: Array("0.3".utf8))) + XCTAssertEqual( + ItemField(Double(-19.993)), + try StructuredFieldValueDecoder().decode(from: Array("-19.993".utf8)) + ) + } + func testAskingForTheWrongType() throws { let headerField = "gzip" let intField = "5"