mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
210 lines
6.0 KiB
Swift
210 lines
6.0 KiB
Swift
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 == 'Float16':
|
|
#if !os(macOS) && !(os(iOS) && targetEnvironment(macCatalyst))
|
|
% end
|
|
% 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 == 'Float16':
|
|
#if !os(macOS) && !(os(iOS) && targetEnvironment(macCatalyst))
|
|
% end
|
|
% if OtherFloat == 'Float80':
|
|
#if !os(Windows) && (arch(i386) || arch(x86_64))
|
|
% end
|
|
|
|
% if OtherSignificandBits <= SelfSignificandBits:
|
|
|
|
% if OtherFloat == 'Float16':
|
|
if #available(iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
|
|
% end
|
|
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)
|
|
}
|
|
% if OtherFloat == 'Float16':
|
|
}
|
|
% end
|
|
|
|
% else:
|
|
|
|
% if Self == 'Float16':
|
|
if #available(iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
|
|
% end
|
|
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))
|
|
}
|
|
% if Self == 'Float16':
|
|
}
|
|
% end
|
|
|
|
% end
|
|
|
|
% if 'Float16' in [Self, OtherFloat]:
|
|
if #available(iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
|
|
% 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 'Float16' in [Self, OtherFloat]:
|
|
}
|
|
% end
|
|
|
|
% if OtherFloat == 'Float16':
|
|
#endif
|
|
% end
|
|
% if OtherFloat == 'Float80':
|
|
#endif
|
|
% end
|
|
|
|
% end # for in all_floating_point_types (Other)
|
|
|
|
#if _pointerBitWidth(_32)
|
|
% int_types = all_integer_types(32)
|
|
#elseif _pointerBitWidth(_64)
|
|
% int_types = all_integer_types(64)
|
|
#else
|
|
_UnimplementedError()
|
|
#endif
|
|
|
|
% for int_ty in int_types:
|
|
% OtherInt = int_ty.stdlib_name
|
|
|
|
extension ${OtherInt} {
|
|
% if Self == 'Float16':
|
|
@available(iOS 14.0, watchOS 7.0, tvOS 14.0, *)
|
|
@available(macOS, unavailable)
|
|
% end
|
|
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),
|
|
]
|
|
}
|
|
}
|
|
}
|
|
|
|
% if Self == 'Float16':
|
|
if #available(iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
|
|
% end
|
|
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)
|
|
}
|
|
}
|
|
% if Self == 'Float16':
|
|
}
|
|
% end
|
|
|
|
% end # for in int_types
|
|
|
|
% if Self == 'Float16':
|
|
#endif
|
|
% end
|
|
% if Self == 'Float80':
|
|
#endif
|
|
% end
|
|
|
|
% end # for in all_floating_point_types (Self)
|
|
|
|
runAllTests()
|