// 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) %{ float_to_int_conversion_template = gyb.parse_template("float_to_int_conversion", """ % for int_ty in all_integer_types(word_bits): % 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) % for testValue in [0, FloatMin, FloatMax, FloatMin - 1, FloatMax + 1, OtherMin, OtherMax]: % if testValue < OtherMin or testValue > OtherMax: % # Can't construct `other` value, do nothing and continue. % elif testValue >= FloatMin and testValue <= FloatMax: FixedPointConversionTruncations.test("${OtherInt}to${Self}Conversion/${testValue}") { expectEqual(${Self}(${testValue} as ${OtherInt}), ${testValue}) } FixedPointConversionFailures.test("${OtherInt}to${Self}FailableConversion/${testValue}") { expectEqual(${Self}(exactly: ${testValue} as ${OtherInt}), ${testValue}) } % else: FixedPointConversionTruncations.test("${OtherInt}to${Self}Truncation/${testValue}") { let value: ${OtherInt} = ${testValue} let result = ${Self}(value) expectNotEqual(${OtherInt}(result), value) } FixedPointConversionFailures.test("${OtherInt}to${Self}Failure/${testValue}") { let value: ${OtherInt} = ${testValue} let result = ${Self}(exactly: value) expectEqual(result, ${OtherMin} as ${Self}) expectEqual(${OtherInt}(result!), value) } % end % end # testValue in testValues % end # for in all_integer_types (Other) """) }% #if arch(i386) || arch(arm) ${gyb.execute_template( float_to_int_conversion_template, word_bits=32, **locals() )} #elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) ${gyb.execute_template( float_to_int_conversion_template, word_bits=64, **locals() )} #else _UnimplementedError() #endif % if Self == 'Float80': #endif % end % end # for in all_floating_point_types (Self) runAllTests()