Skip to content

Commit d07baee

Browse files
committed
[stdlib] More verbose debugDescription for NaNs
The format of debugDescription for NaN is: [ '-' ] ( 'snan' | 'nan' ) [ '(0x' hexadecimal-digits ')' ]
1 parent d1e78f5 commit d07baee

File tree

2 files changed

+69
-5
lines changed

2 files changed

+69
-5
lines changed

stdlib/public/core/Runtime.swift.gyb

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -350,11 +350,26 @@ func _float${bits}ToStringImpl(
350350

351351
func _float${bits}ToString(_ value: Float${bits}, debug: Bool) -> String {
352352

353-
if value.isInfinite {
354-
return value.sign == .minus ? "-inf" : "inf"
355-
}
356-
if value.isNaN {
357-
return "nan"
353+
if !value.isFinite {
354+
let significand = value.significandBitPattern
355+
if significand == 0 {
356+
// Infinity
357+
return value.sign == .minus ? "-inf" : "inf"
358+
}
359+
else {
360+
// NaN
361+
if !debug {
362+
return "nan"
363+
}
364+
let isSignaling = (significand & Float${bits}._quietNaNMask) == 0
365+
let payload = significand & ((Float${bits}._quietNaNMask >> 1) - 1)
366+
// FIXME(performance): Inefficient String manipulation. We could move
367+
// this to C function.
368+
return
369+
(value.sign == .minus ? "-" : "")
370+
+ (isSignaling ? "snan" : "nan")
371+
+ (payload == 0 ? "" : ("(0x" + String(payload, radix: 16) + ")"))
372+
}
358373
}
359374

360375
_sanityCheck(sizeof(_Buffer32.self) == 32)

test/1_stdlib/PrintFloat.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ PrintTests.test("Printable") {
5656
expectPrinted("-inf", -Float.infinity)
5757
expectPrinted("nan", Float.nan)
5858
expectPrinted("nan", -Float.nan)
59+
expectPrinted("nan", Float.signalingNaN)
60+
expectPrinted("nan", -Float.signalingNaN)
5961
expectPrinted("0.0", asFloat32(0.0))
6062
expectPrinted("1.0", asFloat32(1.0))
6163
expectPrinted("-1.0", asFloat32(-1.0))
@@ -66,12 +68,28 @@ PrintTests.test("Printable") {
6668
expectPrinted("-inf", -Double.infinity)
6769
expectPrinted("nan", Double.nan)
6870
expectPrinted("nan", -Double.nan)
71+
expectPrinted("nan", Double.signalingNaN)
72+
expectPrinted("nan", -Double.signalingNaN)
6973
expectPrinted("0.0", asFloat64(0.0))
7074
expectPrinted("1.0", asFloat64(1.0))
7175
expectPrinted("-1.0", asFloat64(-1.0))
7276
expectPrinted("100.125", asFloat64(100.125))
7377
expectPrinted("-100.125", asFloat64(-100.125))
7478

79+
#if arch(i386) || arch(x86_64)
80+
expectPrinted("inf", Float80.infinity)
81+
expectPrinted("-inf", -Float80.infinity)
82+
expectPrinted("nan", Float80.nan)
83+
expectPrinted("nan", -Float80.nan)
84+
expectPrinted("nan", Float80.signalingNaN)
85+
expectPrinted("nan", -Float80.signalingNaN)
86+
expectPrinted("0.0", asFloat80(0.0))
87+
expectPrinted("1.0", asFloat80(1.0))
88+
expectPrinted("-1.0", asFloat80(-1.0))
89+
expectPrinted("100.125", asFloat80(100.125))
90+
expectPrinted("-100.125", asFloat80(-100.125))
91+
#endif
92+
7593
expectPrinted("1.00001", asFloat32(1.00001))
7694
expectPrinted("1.25e+17", asFloat32(125000000000000000.0))
7795
expectPrinted("1.25e+16", asFloat32(12500000000000000.0))
@@ -191,17 +209,48 @@ PrintTests.test("Printable") {
191209
expectDebugPrinted("1.24999998e+17", asFloat32(125000000000000000.0))
192210
expectDebugPrinted("1.25", asFloat32(1.25))
193211
expectDebugPrinted("1.24999997e-05", asFloat32(0.0000125))
212+
expectDebugPrinted("inf", Float.infinity)
213+
expectDebugPrinted("-inf", -Float.infinity)
214+
expectDebugPrinted("nan", Float.nan)
215+
expectDebugPrinted("-nan", -Float.nan)
216+
expectDebugPrinted("nan(0xffff)", Float(nan: 65535, signaling: false))
217+
expectDebugPrinted("-nan(0xffff)", -Float(nan: 65535, signaling: false))
218+
#if !arch(i386)
219+
expectDebugPrinted("snan", Float.signalingNaN)
220+
expectDebugPrinted("snan(0xffff)", Float(nan: 65535, signaling: true))
221+
expectDebugPrinted("-snan(0xffff)", -Float(nan: 65535, signaling: true))
222+
#endif
194223

195224
expectDebugPrinted("1.1000000000000001", asFloat64(1.1))
196225
expectDebugPrinted("1.25e+17", asFloat64(125000000000000000.0))
197226
expectDebugPrinted("1.25", asFloat64(1.25))
198227
expectDebugPrinted("1.2500000000000001e-05", asFloat64(0.0000125))
228+
expectDebugPrinted("inf", Double.infinity)
229+
expectDebugPrinted("-inf", -Double.infinity)
230+
expectDebugPrinted("nan", Double.nan)
231+
expectDebugPrinted("-nan", -Double.nan)
232+
expectDebugPrinted("nan(0xffff)", Double(nan: 65535, signaling: false))
233+
expectDebugPrinted("-nan(0xffff)", -Double(nan: 65535, signaling: false))
234+
#if !arch(i386)
235+
expectDebugPrinted("snan", Double.signalingNaN)
236+
expectDebugPrinted("snan(0xffff)", Double(nan: 65535, signaling: true))
237+
expectDebugPrinted("-snan(0xffff)", -Double(nan: 65535, signaling: true))
238+
#endif
199239

200240
#if arch(i386) || arch(x86_64)
201241
expectDebugPrinted("1.10000000000000000002", asFloat80(1.1))
202242
expectDebugPrinted("125000000000000000.0", asFloat80(125000000000000000.0))
203243
expectDebugPrinted("1.25", asFloat80(1.25))
204244
expectDebugPrinted("1.25000000000000000001e-05", asFloat80(0.0000125))
245+
expectDebugPrinted("inf", Float80.infinity)
246+
expectDebugPrinted("-inf", -Float80.infinity)
247+
expectDebugPrinted("nan", Float80.nan)
248+
expectDebugPrinted("-nan", -Float80.nan)
249+
expectDebugPrinted("nan(0xffff)", Float80(nan: 65535, signaling: false))
250+
expectDebugPrinted("-nan(0xffff)", -Float80(nan: 65535, signaling: false))
251+
expectDebugPrinted("snan", Float80.signalingNaN)
252+
expectDebugPrinted("snan(0xffff)", Float80(nan: 65535, signaling: true))
253+
expectDebugPrinted("-snan(0xffff)", -Float80(nan: 65535, signaling: true))
205254
#endif
206255
}
207256

0 commit comments

Comments
 (0)