// 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 % OtherMin = int_ty.min % OtherMax = int_ty.max % (FloatMin, FloatMax) = getFtoIBounds(self_type.bits, int_ty.bits, int_ty.is_signed) FixedPointConversionTruncations.test("${OtherInt}to${Self}") .forEach(in: [ (0, 0, 0), % if int_ty.bits > self_type.significand_bits + 1: % limit = ~(~0 << (self_type.significand_bits + 1)) % over = ~(~0 << (self_type.significand_bits + 2)) (${limit}, ${limit}, ${limit}), (${over}, ${over + 1}, nil), % if int_ty.is_signed: (-${limit}, -${limit}, -${limit}), (-${over}, -${over + 1}, nil), % end % else: (${OtherInt}.min, ${OtherInt}.min, ${OtherInt}.min), (${OtherInt}.max, ${OtherInt}.max, ${OtherInt}.max), % end ] as [(${OtherInt}, ${OtherInt}, ${OtherInt}?)]) { 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()