// RUN: %empty-directory(%t) // RUN: %gyb %s -o %t/FloatingPointConversion.swift // RUN: %line-directive %t/FloatingPointConversion.swift -- %target-build-swift %t/FloatingPointConversion.swift -Xfrontend -disable-access-control -o %t/a.out_Debug -Onone // RUN: %line-directive %t/FloatingPointConversion.swift -- %target-build-swift %t/FloatingPointConversion.swift -Xfrontend -disable-access-control -o %t/a.out_Release -O // // RUN: %line-directive %t/FloatingPointConversion.swift -- %target-run %t/a.out_Debug // RUN: %line-directive %t/FloatingPointConversion.swift -- %target-run %t/a.out_Release // REQUIRES: executable_test 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()