| import StdlibUnittest |
| |
| %{ |
| import gyb |
| from SwiftFloatingPointTypes import all_floating_point_types, getFtoIBounds |
| from SwiftIntTypes import all_integer_types |
| }% |
| |
| var FixedPointConversionTruncations = TestSuite("FixedPointToFloatingPointConversionTruncations") |
| var FixedPointConversionFailures = TestSuite("FixedPointToFloatingPointConversionFailures") |
| |
| var FloatingPointConversionTruncations = TestSuite("FloatingPointToFloatingPointConversionTruncations") |
| var FloatingPointConversionFailures = TestSuite("FloatingPointToFloatingPointConversionFailures") |
| |
| % for self_type in all_floating_point_types(): |
| % SelfSignificandBits = self_type.bits |
| % Self = self_type.stdlib_name |
| |
| % if Self == 'Float80': |
| #if !os(Windows) && (arch(i386) || arch(x86_64)) |
| % end |
| |
| % for other_type in all_floating_point_types(): |
| % OtherSignificandBits = other_type.bits |
| % OtherFloat = other_type.stdlib_name |
| |
| % if OtherFloat == 'Float80': |
| #if !os(Windows) && (arch(i386) || arch(x86_64)) |
| % end |
| |
| % if OtherSignificandBits <= SelfSignificandBits: |
| |
| FloatingPointConversionTruncations.test("${OtherFloat}To${Self}Conversion") |
| .forEach(in: [ |
| ${OtherFloat}.greatestFiniteMagnitude, |
| -${OtherFloat}.greatestFiniteMagnitude, |
| (1.0 as ${OtherFloat}).nextUp, |
| (1.0 as ${OtherFloat}).nextDown, |
| (-1.0 as ${OtherFloat}).nextUp, |
| (-1.0 as ${OtherFloat}).nextDown, |
| ]) { |
| input in |
| // FIXME: we should have a stronger postcondition here. |
| let result = ${Self}(input) |
| let resultConvertedBack = ${OtherFloat}(result) |
| expectEqual(input, resultConvertedBack) |
| } |
| |
| % else: |
| |
| FloatingPointConversionTruncations.test("${OtherFloat}To${Self}Conversion") |
| .forEach(in: [ |
| ( ${OtherFloat}.greatestFiniteMagnitude, ${Self}.infinity), |
| (-${OtherFloat}.greatestFiniteMagnitude, -${Self}.infinity), |
| ( (1.0 as ${OtherFloat}).nextUp, 1.0 as ${Self}), |
| ( (1.0 as ${OtherFloat}).nextDown, 1.0 as ${Self}), |
| ((-1.0 as ${OtherFloat}).nextUp, -1.0 as ${Self}), |
| ((-1.0 as ${OtherFloat}).nextDown, -1.0 as ${Self}), |
| ]) { |
| (input, expectedResult) in |
| expectEqual(expectedResult, ${Self}(input)) |
| } |
| |
| % end |
| |
| FloatingPointConversionTruncations.test("${OtherFloat}To${Self}Conversion/special") { |
| expectEqual( 1.0 as ${Self}, ${Self}(exactly: 1.0 as ${OtherFloat})) |
| expectEqual(-1.0 as ${Self}, ${Self}(exactly: -1.0 as ${OtherFloat})) |
| expectEqual( ${Self}.infinity, ${Self}( ${OtherFloat}.infinity)) |
| expectEqual(-${Self}.infinity, ${Self}(-${OtherFloat}.infinity)) |
| expectTrue(${Self}(${OtherFloat}.nan).isNaN) |
| } |
| |
| FloatingPointConversionFailures.test("${OtherFloat}To${Self}FailableConversion") |
| .forEach(in: [ |
| ${OtherFloat}.greatestFiniteMagnitude, |
| -${OtherFloat}.greatestFiniteMagnitude, |
| (1.0 as ${OtherFloat}).nextUp, |
| (1.0 as ${OtherFloat}).nextDown, |
| (-1.0 as ${OtherFloat}).nextUp, |
| (-1.0 as ${OtherFloat}).nextDown, |
| ]) { |
| input in |
| let result = ${Self}(exactly: input) |
| % if OtherSignificandBits <= SelfSignificandBits: |
| if let result = expectNotNil(result) { |
| // FIXME: we should have a stronger postcondition here. |
| expectEqual(input, ${OtherFloat}(result)) |
| } |
| % else: |
| expectNil(result) |
| % end |
| } |
| |
| FloatingPointConversionFailures.test("${OtherFloat}To${Self}Conversion/AlwaysSuccess") { |
| expectEqual( 1.0 as ${Self}, ${Self}(exactly: 1.0 as ${OtherFloat})) |
| expectEqual(-1.0 as ${Self}, ${Self}(exactly: -1.0 as ${OtherFloat})) |
| expectEqual( ${Self}.infinity, ${Self}(exactly: ${OtherFloat}.infinity)) |
| expectEqual(-${Self}.infinity, ${Self}(exactly: -${OtherFloat}.infinity)) |
| expectNil(${Self}(exactly: ${OtherFloat}.nan)) |
| } |
| |
| % if OtherFloat == 'Float80': |
| #endif |
| % end |
| |
| % end # for in all_floating_point_types (Other) |
| |
| #if arch(i386) || arch(arm) |
| % int_types = all_integer_types(32) |
| #elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) |
| % int_types = all_integer_types(64) |
| #else |
| _UnimplementedError() |
| #endif |
| |
| % for int_ty in int_types: |
| % OtherInt = int_ty.stdlib_name |
| |
| extension ${OtherInt} { |
| static var _test${Self}Conversion: [(${OtherInt}, ${OtherInt}, ${OtherInt}?)] { |
| if bitWidth > ${Self}.significandBitCount + 1 { |
| let bitOffset = ${Self}.significandBitCount + 1 |
| let limit: ${OtherInt} = ~(~0 << bitOffset) |
| let over: ${OtherInt} = 1 + limit << 1 |
| return [ |
| (0, 0, 0), |
| (limit, limit, limit), |
| (over, over + 1, nil), |
| % if int_ty.is_signed: |
| (-limit, -limit, -limit), |
| (-over, -(over + 1), nil), |
| % end |
| ] |
| } else { |
| return [ |
| (0, 0, 0), |
| (.min, .min, .min), |
| (.max, .max, .max), |
| ] |
| } |
| } |
| } |
| |
| FixedPointConversionTruncations.test("${OtherInt}to${Self}") |
| .forEach(in: ${OtherInt}._test${Self}Conversion) { |
| value, roundedExpectation, exactExpectation in |
| |
| let roundedResult = ${Self}(value) |
| expectEqual(roundedResult, ${Self}(roundedExpectation)) |
| |
| let exactResult = ${Self}(exactly: value) |
| if let expectation = exactExpectation { |
| expectEqual(exactResult!, ${Self}(expectation)) |
| } else { |
| expectNil(exactResult) |
| } |
| } |
| |
| % end # for in int_types |
| |
| % if Self == 'Float80': |
| #endif |
| % end |
| |
| % end # for in all_floating_point_types (Self) |
| |
| runAllTests() |