blob: 3aad6512963afe2bef4c7d6341f23684b5913342 [file] [log] [blame]
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()