From da5bb7aa502d0d35848e47eca65ba3068d7d7ec7 Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Tue, 31 May 2016 17:59:51 -0500 Subject: [PATCH 1/2] [stdlib] Add tests for FloatingPoint's nextUp and nextDown --- .../StdlibUnittest/StdlibUnittest.swift.gyb | 8 ++--- test/1_stdlib/FloatingPoint.swift.gyb | 36 +++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb b/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb index 39f1be5dc0671..4f681dde9b254 100644 --- a/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb +++ b/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb @@ -238,25 +238,25 @@ public func expectOptionalEqual${Generic}( %end -public func expectLT(_ lhs: Int, _ rhs: Int, ${TRACE}) { +public func expectLT(_ lhs: T, _ rhs: T, ${TRACE}) { if !(lhs < rhs) { expectationFailure("\(lhs) < \(rhs)", trace: ${trace}) } } -public func expectLE(_ lhs: Int, _ rhs: Int, ${TRACE}) { +public func expectLE(_ lhs: T, _ rhs: T, ${TRACE}) { if !(lhs <= rhs) { expectationFailure("\(lhs) <= \(rhs)", trace: ${trace}) } } -public func expectGT(_ lhs: Int, _ rhs: Int, ${TRACE}) { +public func expectGT(_ lhs: T, _ rhs: T, ${TRACE}) { if !(lhs > rhs) { expectationFailure("\(lhs) > \(rhs)", trace: ${trace}) } } -public func expectGE(_ lhs: Int, _ rhs: Int, ${TRACE}) { +public func expectGE(_ lhs: T, _ rhs: T, ${TRACE}) { if !(lhs >= rhs) { expectationFailure("\(lhs) >= \(rhs)", trace: ${trace}) } diff --git a/test/1_stdlib/FloatingPoint.swift.gyb b/test/1_stdlib/FloatingPoint.swift.gyb index 05ddeeb765674..52954174efcb9 100644 --- a/test/1_stdlib/FloatingPoint.swift.gyb +++ b/test/1_stdlib/FloatingPoint.swift.gyb @@ -171,6 +171,42 @@ FloatingPoint.test("Double/HashValueZero") { expectEqual(zero.hashValue, negativeZero.hashValue) } +let floatNextUpDownTests: [(Float, Float)] = [ + (.nan, .nan), + (.greatestFiniteMagnitude, .infinity), + (-.infinity, -.greatestFiniteMagnitude), + (0x1.fffffep-1, 1.0), (1.0, 0x1.000002p+0), + (-0x1p-149, -0.0), (0.0, 0x1p-149), + (0x1.effffep-1, 0.96875), (0.96875, 0x1.f00002p-1), +] + +FloatingPoint.test("Float.nextUp, .nextDown") + .forEach(in: floatNextUpDownTests) { + (prev, succ) in + expectEqual(succ.bitPattern, prev.nextUp.bitPattern) + expectEqual(prev.bitPattern, succ.nextDown.bitPattern) + expectEqual((-succ).bitPattern, (-prev).nextDown.bitPattern) + expectEqual((-prev).bitPattern, (-succ).nextUp.bitPattern) +} + +let doubleNextUpDownTests: [(Double, Double)] = [ + (.nan, .nan), + (.greatestFiniteMagnitude, .infinity), + (-.infinity, -.greatestFiniteMagnitude), + (0x1.fffffffffffffp-1, 1.0), (1.0, 0x1.0000000000001p+0), + (-0x1p-1074, -0.0), (0.0, 0x1p-1074), + (0x1.effffffffffffp-1, 0.96875), (0.96875, 0x1.f000000000001p-1), +] + +FloatingPoint.test("Double.nextUp, .nextDown") + .forEach(in: doubleNextUpDownTests) { + (prev, succ) in + expectEqual(succ.bitPattern, prev.nextUp.bitPattern) + expectEqual(prev.bitPattern, succ.nextDown.bitPattern) + expectEqual((-succ).bitPattern, (-prev).nextDown.bitPattern) + expectEqual((-prev).bitPattern, (-succ).nextUp.bitPattern) +} + #if arch(i386) || arch(x86_64) FloatingPoint.test("Float80/IntegerLiteralConvertible") { From 8b2d20191685b086158444d16ac82e9baf2a31fa Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Tue, 31 May 2016 18:00:07 -0500 Subject: [PATCH 2/2] [stdlib] Fix for nextUp and nextDown --- stdlib/public/core/FloatingPointTypes.swift.gyb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stdlib/public/core/FloatingPointTypes.swift.gyb b/stdlib/public/core/FloatingPointTypes.swift.gyb index 694e47bbc536d..aafd1bbf259b5 100644 --- a/stdlib/public/core/FloatingPointTypes.swift.gyb +++ b/stdlib/public/core/FloatingPointTypes.swift.gyb @@ -480,6 +480,9 @@ extension ${Self}: BinaryFloatingPoint { exponentBitPattern: exponentBitPattern - 1, significandBitPattern: ${Self}._significandMask) } + return ${Self}(sign: .minus, + exponentBitPattern: exponentBitPattern, + significandBitPattern: significandBitPattern - 1) } if isInfinite { return self } if significandBitPattern == ${Self}._significandMask {