mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
234 lines
6.0 KiB
Swift
234 lines
6.0 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: cp %s %t/main.swift
|
|
|
|
// RUN: echo "typealias TestFloat = Float" > %t/float_type.swift
|
|
// RUN: %target-build-swift %t/main.swift %t/float_type.swift -o %t/float.out
|
|
// RUN: %target-codesign %t/float.out
|
|
// RUN: %target-run %t/float.out
|
|
|
|
// RUN: echo "typealias TestFloat = Double" > %t/double_type.swift
|
|
// RUN: %target-build-swift %t/main.swift %t/double_type.swift -o %t/double.out
|
|
// RUN: %target-codesign %t/double.out
|
|
// RUN: %target-run %t/double.out
|
|
// REQUIRES: executable_test
|
|
|
|
import StdlibUnittest
|
|
|
|
var FloatTests = TestSuite("Float")
|
|
|
|
//===---
|
|
// Helpers
|
|
//===---
|
|
|
|
func noinlinePlusZero() -> TestFloat {
|
|
return 0.0
|
|
}
|
|
|
|
func noinlineMinusZero() -> TestFloat {
|
|
return -0.0
|
|
}
|
|
|
|
//===---
|
|
// Normals
|
|
//===---
|
|
|
|
func checkNormal(_ normal: TestFloat) {
|
|
precondition(normal.isNormal)
|
|
precondition(normal.isFinite)
|
|
precondition(!normal.isZero)
|
|
precondition(!normal.isSubnormal)
|
|
precondition(!normal.isInfinite)
|
|
precondition(!normal.isNaN)
|
|
precondition(!normal.isSignalingNaN)
|
|
}
|
|
|
|
FloatTests.test("normal") {
|
|
let positiveNormal: TestFloat = 42.0
|
|
checkNormal(positiveNormal)
|
|
precondition(positiveNormal.sign == .plus)
|
|
precondition(positiveNormal.floatingPointClass == .positiveNormal)
|
|
|
|
let negativeNormal: TestFloat = -42.0
|
|
checkNormal(negativeNormal)
|
|
precondition(negativeNormal.sign == .minus)
|
|
precondition(negativeNormal.floatingPointClass == .negativeNormal)
|
|
|
|
precondition(positiveNormal == positiveNormal)
|
|
precondition(negativeNormal == negativeNormal)
|
|
precondition(positiveNormal != negativeNormal)
|
|
precondition(negativeNormal != positiveNormal)
|
|
precondition(positiveNormal == -negativeNormal)
|
|
precondition(negativeNormal == -positiveNormal)
|
|
}
|
|
|
|
//===---
|
|
// Zeroes
|
|
//===---
|
|
|
|
func checkZero(_ zero: TestFloat) {
|
|
precondition(!zero.isNormal)
|
|
precondition(zero.isFinite)
|
|
precondition(zero.isZero)
|
|
precondition(!zero.isSubnormal)
|
|
precondition(!zero.isInfinite)
|
|
precondition(!zero.isNaN)
|
|
precondition(!zero.isSignalingNaN)
|
|
}
|
|
|
|
FloatTests.test("zero") {
|
|
let plusZero = noinlinePlusZero()
|
|
checkZero(plusZero)
|
|
precondition(plusZero.sign == .plus)
|
|
precondition(plusZero.floatingPointClass == .positiveZero)
|
|
|
|
let minusZero = noinlineMinusZero()
|
|
checkZero(minusZero)
|
|
precondition(minusZero.sign == .minus)
|
|
precondition(minusZero.floatingPointClass == .negativeZero)
|
|
|
|
precondition(plusZero == 0.0)
|
|
precondition(plusZero == plusZero)
|
|
precondition(plusZero == minusZero)
|
|
precondition(minusZero == -0.0)
|
|
precondition(minusZero == plusZero)
|
|
precondition(minusZero == minusZero)
|
|
}
|
|
|
|
//===---
|
|
// Subnormals
|
|
//===---
|
|
|
|
func checkSubnormal(_ subnormal: TestFloat) {
|
|
precondition(!subnormal.isNormal)
|
|
precondition(subnormal.isFinite)
|
|
precondition(!subnormal.isZero)
|
|
precondition(subnormal.isSubnormal)
|
|
precondition(!subnormal.isInfinite)
|
|
precondition(!subnormal.isNaN)
|
|
precondition(!subnormal.isSignalingNaN)
|
|
}
|
|
|
|
func asUInt64(_ a: UInt64) -> UInt64 {
|
|
return a
|
|
}
|
|
|
|
func asUInt64(_ a: UInt32) -> UInt64 {
|
|
return UInt64(a)
|
|
}
|
|
|
|
#if !arch(arm)
|
|
FloatTests.test("subnormal") {
|
|
var iterations: Int
|
|
switch asUInt64(TestFloat.RawSignificand.max) {
|
|
case UInt64.max:
|
|
iterations = 1023
|
|
case asUInt64(UInt32.max):
|
|
iterations = 127
|
|
default:
|
|
preconditionFailure("unhandled float kind")
|
|
}
|
|
var positiveSubnormal: TestFloat = 1.0
|
|
for i in 0 ..< iterations {
|
|
positiveSubnormal /= 2.0 as TestFloat
|
|
}
|
|
checkSubnormal(positiveSubnormal)
|
|
precondition(positiveSubnormal.sign == .plus)
|
|
precondition(positiveSubnormal.floatingPointClass == .positiveSubnormal)
|
|
precondition(positiveSubnormal != 0.0)
|
|
|
|
var negativeSubnormal: TestFloat = -1.0
|
|
for i in 0 ..< iterations {
|
|
negativeSubnormal /= 2.0 as TestFloat
|
|
}
|
|
checkSubnormal(negativeSubnormal)
|
|
precondition(negativeSubnormal.sign == .minus)
|
|
precondition(negativeSubnormal.floatingPointClass == .negativeSubnormal)
|
|
precondition(negativeSubnormal != -0.0)
|
|
}
|
|
#endif
|
|
|
|
//===---
|
|
// Infinities
|
|
//===---
|
|
|
|
func checkInf(_ inf: TestFloat) {
|
|
precondition(!inf.isNormal)
|
|
precondition(!inf.isFinite)
|
|
precondition(!inf.isZero)
|
|
precondition(!inf.isSubnormal)
|
|
precondition(inf.isInfinite)
|
|
precondition(!inf.isNaN)
|
|
precondition(!inf.isSignalingNaN)
|
|
}
|
|
|
|
FloatTests.test("infinity") {
|
|
var stdlibPlusInf = TestFloat.infinity
|
|
checkInf(stdlibPlusInf)
|
|
precondition(stdlibPlusInf.sign == .plus)
|
|
precondition(stdlibPlusInf.floatingPointClass == .positiveInfinity)
|
|
|
|
var stdlibMinusInf = -TestFloat.infinity
|
|
checkInf(stdlibMinusInf)
|
|
precondition(stdlibMinusInf.sign == .minus)
|
|
precondition(stdlibMinusInf.floatingPointClass == .negativeInfinity)
|
|
|
|
var computedPlusInf = 1.0 / noinlinePlusZero()
|
|
checkInf(computedPlusInf)
|
|
precondition(computedPlusInf.sign == .plus)
|
|
precondition(computedPlusInf.floatingPointClass == .positiveInfinity)
|
|
|
|
var computedMinusInf = -1.0 / noinlinePlusZero()
|
|
checkInf(computedMinusInf)
|
|
precondition(computedMinusInf.sign == .minus)
|
|
precondition(computedMinusInf.floatingPointClass == .negativeInfinity)
|
|
|
|
precondition(stdlibPlusInf == computedPlusInf)
|
|
precondition(stdlibMinusInf == computedMinusInf)
|
|
|
|
precondition(stdlibPlusInf != computedMinusInf)
|
|
precondition(stdlibMinusInf != computedPlusInf)
|
|
}
|
|
|
|
//===---
|
|
// NaNs
|
|
//===---
|
|
|
|
func checkNaN(_ nan: TestFloat) {
|
|
precondition(nan.sign == .plus)
|
|
precondition(!nan.isNormal)
|
|
precondition(!nan.isFinite)
|
|
precondition(!nan.isZero)
|
|
precondition(!nan.isSubnormal)
|
|
precondition(!nan.isInfinite)
|
|
precondition(nan.isNaN)
|
|
}
|
|
|
|
func checkQNaN(_ qnan: TestFloat) {
|
|
checkNaN(qnan)
|
|
precondition(!qnan.isSignalingNaN)
|
|
precondition(qnan.floatingPointClass == .quietNaN)
|
|
}
|
|
|
|
func checkSNaN(_ snan: TestFloat) {
|
|
checkNaN(snan)
|
|
// sNaN cannot be fully supported on i386.
|
|
#if !arch(i386)
|
|
precondition(snan.isSignalingNaN)
|
|
precondition(snan.floatingPointClass == .signalingNaN)
|
|
#endif
|
|
}
|
|
|
|
FloatTests.test("nan") {
|
|
var stdlibDefaultNaN = TestFloat.nan
|
|
checkQNaN(stdlibDefaultNaN)
|
|
|
|
var stdlibQNaN = TestFloat.nan
|
|
checkQNaN(stdlibQNaN)
|
|
|
|
var stdlibSNaN = TestFloat.signalingNaN
|
|
checkSNaN(stdlibSNaN)
|
|
}
|
|
|
|
runAllTests()
|
|
|