mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This follows the API guidelines and is consistent with the printed form. 'quietNaN' does not change, though.
240 lines
6.0 KiB
Swift
240 lines
6.0 KiB
Swift
// RUN: rm -rf %t &&mkdir %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-run %t/float.out | FileCheck %s
|
|
|
|
// 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-run %t/double.out | FileCheck %s
|
|
// REQUIRES: executable_test
|
|
|
|
//===---
|
|
// 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.isSignaling)
|
|
}
|
|
|
|
func testNormal() {
|
|
let positiveNormal: TestFloat = 42.0
|
|
checkNormal(positiveNormal)
|
|
_precondition(!positiveNormal.isSignMinus)
|
|
_precondition(positiveNormal.floatingPointClass == .positiveNormal)
|
|
|
|
let negativeNormal: TestFloat = -42.0
|
|
checkNormal(negativeNormal)
|
|
_precondition(negativeNormal.isSignMinus)
|
|
_precondition(negativeNormal.floatingPointClass == .negativeNormal)
|
|
|
|
_precondition(positiveNormal == positiveNormal)
|
|
_precondition(negativeNormal == negativeNormal)
|
|
_precondition(positiveNormal != negativeNormal)
|
|
_precondition(negativeNormal != positiveNormal)
|
|
_precondition(positiveNormal == -negativeNormal)
|
|
_precondition(negativeNormal == -positiveNormal)
|
|
|
|
print("testNormal done")
|
|
}
|
|
testNormal()
|
|
// CHECK: testNormal done
|
|
|
|
//===---
|
|
// 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.isSignaling)
|
|
}
|
|
|
|
func testZero() {
|
|
let plusZero = noinlinePlusZero()
|
|
checkZero(plusZero)
|
|
_precondition(!plusZero.isSignMinus)
|
|
_precondition(plusZero.floatingPointClass == .positiveZero)
|
|
|
|
let minusZero = noinlineMinusZero()
|
|
checkZero(minusZero)
|
|
_precondition(minusZero.isSignMinus)
|
|
_precondition(minusZero.floatingPointClass == .negativeZero)
|
|
|
|
_precondition(plusZero == 0.0)
|
|
_precondition(plusZero == plusZero)
|
|
_precondition(plusZero == minusZero)
|
|
_precondition(minusZero == -0.0)
|
|
_precondition(minusZero == plusZero)
|
|
_precondition(minusZero == minusZero)
|
|
|
|
print("testZero done")
|
|
}
|
|
testZero()
|
|
// CHECK: testZero done
|
|
|
|
//===---
|
|
// 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.isSignaling)
|
|
}
|
|
|
|
func asUInt64(a: UInt64) -> UInt64 {
|
|
return a
|
|
}
|
|
|
|
func asUInt64(a: UInt32) -> UInt64 {
|
|
return UInt64(a)
|
|
}
|
|
|
|
func testSubnormal() {
|
|
var iterations: Int
|
|
switch asUInt64(TestFloat._BitsType.max) {
|
|
case UInt64.max:
|
|
iterations = 1023
|
|
case asUInt64(UInt32.max):
|
|
iterations = 127
|
|
default:
|
|
_preconditionFailure("unhandled float kind")
|
|
}
|
|
var positiveSubnormal: TestFloat = 1.0
|
|
for var i = 0; i < iterations; i += 1 {
|
|
positiveSubnormal /= 2.0 as TestFloat
|
|
}
|
|
checkSubnormal(positiveSubnormal)
|
|
_precondition(!positiveSubnormal.isSignMinus)
|
|
_precondition(positiveSubnormal.floatingPointClass == .positiveSubnormal)
|
|
_precondition(positiveSubnormal != 0.0)
|
|
|
|
var negativeSubnormal: TestFloat = -1.0
|
|
for var i = 0; i < iterations; i += 1{
|
|
negativeSubnormal /= 2.0 as TestFloat
|
|
}
|
|
checkSubnormal(negativeSubnormal)
|
|
_precondition(negativeSubnormal.isSignMinus)
|
|
_precondition(negativeSubnormal.floatingPointClass == .negativeSubnormal)
|
|
_precondition(negativeSubnormal != -0.0)
|
|
|
|
print("testSubnormal done")
|
|
}
|
|
|
|
#if arch(arm)
|
|
print("testSubnormal done")
|
|
#else
|
|
testSubnormal()
|
|
#endif
|
|
// CHECK: testSubnormal done
|
|
|
|
//===---
|
|
// 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.isSignaling)
|
|
}
|
|
|
|
func testInf() {
|
|
var stdlibPlusInf = TestFloat.infinity
|
|
checkInf(stdlibPlusInf)
|
|
_precondition(!stdlibPlusInf.isSignMinus)
|
|
_precondition(stdlibPlusInf.floatingPointClass == .positiveInfinity)
|
|
|
|
var stdlibMinusInf = -TestFloat.infinity
|
|
checkInf(stdlibMinusInf)
|
|
_precondition(stdlibMinusInf.isSignMinus)
|
|
_precondition(stdlibMinusInf.floatingPointClass == .negativeInfinity)
|
|
|
|
var computedPlusInf = 1.0 / noinlinePlusZero()
|
|
checkInf(computedPlusInf)
|
|
_precondition(!computedPlusInf.isSignMinus)
|
|
_precondition(computedPlusInf.floatingPointClass == .positiveInfinity)
|
|
|
|
var computedMinusInf = -1.0 / noinlinePlusZero()
|
|
checkInf(computedMinusInf)
|
|
_precondition(computedMinusInf.isSignMinus)
|
|
_precondition(computedMinusInf.floatingPointClass == .negativeInfinity)
|
|
|
|
_precondition(stdlibPlusInf == computedPlusInf)
|
|
_precondition(stdlibMinusInf == computedMinusInf)
|
|
|
|
_precondition(stdlibPlusInf != computedMinusInf)
|
|
_precondition(stdlibMinusInf != computedPlusInf)
|
|
|
|
print("testInf done")
|
|
}
|
|
testInf()
|
|
// CHECK: testInf done
|
|
|
|
//===---
|
|
// NaNs
|
|
//===---
|
|
|
|
func checkNaN(nan: TestFloat) {
|
|
_precondition(!nan.isSignMinus)
|
|
_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.isSignaling)
|
|
_precondition(qnan.floatingPointClass == .quietNaN)
|
|
}
|
|
|
|
func testNaN() {
|
|
var stdlibDefaultNaN = TestFloat.nan
|
|
checkQNaN(stdlibDefaultNaN)
|
|
|
|
var stdlibQNaN = TestFloat.quietNaN
|
|
checkQNaN(stdlibQNaN)
|
|
|
|
print("testNaN done")
|
|
}
|
|
testNaN()
|
|
// CHECK: testNaN done
|
|
|
|
print("all done.")
|
|
// CHECK: all done.
|
|
|