diff --git a/stdlib/public/core/FloatingPoint.swift.gyb b/stdlib/public/core/FloatingPoint.swift.gyb index 98940b570c5bf..62c7f40a89cbb 100644 --- a/stdlib/public/core/FloatingPoint.swift.gyb +++ b/stdlib/public/core/FloatingPoint.swift.gyb @@ -198,7 +198,14 @@ public struct ${Self} { extension ${Self} : CustomStringConvertible { /// A textual representation of `self`. public var description: String { - return _float${bits}ToString(self) + return _float${bits}ToString(self, debug: false) + } +} + +extension ${Self} : CustomDebugStringConvertible { + /// A textual representation of `self`. + public var debugDescription: String { + return _float${bits}ToString(self, debug: true) } } diff --git a/stdlib/public/core/Runtime.swift.gyb b/stdlib/public/core/Runtime.swift.gyb index 8674560244cfa..ebfb629db3a4b 100644 --- a/stdlib/public/core/Runtime.swift.gyb +++ b/stdlib/public/core/Runtime.swift.gyb @@ -355,11 +355,12 @@ struct _Buffer72 { @_silgen_name("swift_float${bits}ToString") func _float${bits}ToStringImpl( buffer: UnsafeMutablePointer, - _ bufferLength: UInt, _ value: Float${bits} + _ bufferLength: UInt, _ value: Float${bits}, + _ debug: Bool ) -> UInt @warn_unused_result -func _float${bits}ToString(value: Float${bits}) -> String { +func _float${bits}ToString(value: Float${bits}, debug: Bool) -> String { _sanityCheck(sizeof(_Buffer32.self) == 32) _sanityCheck(sizeof(_Buffer72.self) == 72) @@ -367,7 +368,7 @@ func _float${bits}ToString(value: Float${bits}) -> String { return withUnsafeMutablePointer(&buffer) { (bufferPtr) in let bufferUTF8Ptr = UnsafeMutablePointer(bufferPtr) - let actualLength = _float${bits}ToStringImpl(bufferUTF8Ptr, 32, value) + let actualLength = _float${bits}ToStringImpl(bufferUTF8Ptr, 32, value, debug) return String._fromWellFormedCodeUnitSequence( UTF8.self, input: UnsafeBufferPointer( diff --git a/stdlib/public/stubs/Stubs.cpp b/stdlib/public/stubs/Stubs.cpp index 7f23e42dd7f8f..cfb7975b8423d 100644 --- a/stdlib/public/stubs/Stubs.cpp +++ b/stdlib/public/stubs/Stubs.cpp @@ -141,12 +141,16 @@ static int swift_snprintf_l(char *Str, size_t StrSize, locale_t Locale, template static uint64_t swift_floatingPointToString(char *Buffer, size_t BufferLength, - T Value, const char *Format) { + T Value, const char *Format, + bool Debug) { if (BufferLength < 32) swift::crash("swift_floatingPointToString: insufficient buffer size"); - const int Precision = std::numeric_limits::digits10; - + int Precision = std::numeric_limits::digits10; + if (Debug) { + Precision = std::numeric_limits::max_digits10; + } + // Pass a null locale to use the C locale. int i = swift_snprintf_l(Buffer, BufferLength, /*locale=*/nullptr, Format, Precision, Value); @@ -170,21 +174,21 @@ static uint64_t swift_floatingPointToString(char *Buffer, size_t BufferLength, } extern "C" uint64_t swift_float32ToString(char *Buffer, size_t BufferLength, - float Value) { + float Value, bool Debug) { return swift_floatingPointToString(Buffer, BufferLength, Value, - "%0.*g"); + "%0.*g", Debug); } extern "C" uint64_t swift_float64ToString(char *Buffer, size_t BufferLength, - double Value) { + double Value, bool Debug) { return swift_floatingPointToString(Buffer, BufferLength, Value, - "%0.*g"); + "%0.*g", Debug); } extern "C" uint64_t swift_float80ToString(char *Buffer, size_t BufferLength, - long double Value) { + long double Value, bool Debug) { return swift_floatingPointToString(Buffer, BufferLength, Value, - "%0.*Lg"); + "%0.*Lg", Debug); } /// \param[out] LinePtr Replaced with the pointer to the malloc()-allocated diff --git a/test/1_stdlib/Interval.swift b/test/1_stdlib/Interval.swift index c2b4e9447466d..49186be3e878a 100644 --- a/test/1_stdlib/Interval.swift +++ b/test/1_stdlib/Interval.swift @@ -169,11 +169,11 @@ IntervalTestSuite.test("CustomStringConvertible/CustomDebugStringConvertible") { expectEqual("0.0...0.1", String(X(0.0)...X(0.1))) expectEqual( - "HalfOpenInterval(X(0.0)..( ) { var actual = "" debugPrint(object, terminator: "", toStream: &actual) - if expected1 != actual && (expected2 != nil && expected2! != actual) { + if expected1 != actual && (expected2 == nil || expected2! != actual) { print( "check failed at \(file), line \(line)", "expected: \"\(expected1)\" or \"\(expected2)\"", @@ -409,6 +409,23 @@ func test_FloatingPointPrinting() { printedIs(asFloat80(0.0000000000000000125), "1.25e-17") #endif + debugPrintedIs(asFloat32(1.1), "1.10000002") + debugPrintedIs(asFloat32(125000000000000000.0), "1.24999998e+17") + debugPrintedIs(asFloat32(1.25), "1.25") + debugPrintedIs(asFloat32(0.0000125), "1.24999997e-05") + + debugPrintedIs(asFloat64(1.1), "1.1000000000000001") + debugPrintedIs(asFloat64(125000000000000000.0), "1.25e+17") + debugPrintedIs(asFloat64(1.25), "1.25") + debugPrintedIs(asFloat64(0.0000125), "1.2500000000000001e-05") + +#if arch(i386) || arch(x86_64) + debugPrintedIs(asFloat80(1.1), "1.10000000000000000002") + debugPrintedIs(asFloat80(125000000000000000.0), "125000000000000000.0") + debugPrintedIs(asFloat80(1.25), "1.25") + debugPrintedIs(asFloat80(0.0000125), "1.25000000000000000001e-05") +#endif + print("test_FloatingPointPrinting done") } test_FloatingPointPrinting() diff --git a/test/Interpreter/SDK/objc_cast.swift b/test/Interpreter/SDK/objc_cast.swift index f65415883d0df..23a902e92e4ea 100644 --- a/test/Interpreter/SDK/objc_cast.swift +++ b/test/Interpreter/SDK/objc_cast.swift @@ -426,16 +426,18 @@ if let strArr = objImplicitOpt as? [String] { } // Casting an array of numbers to different numbers. -// CHECK: Numbers-as-doubles cast produces [3.14159, 2.71828, 0.0] -obj = ([3.14159, 2.71828, 0] as [Double]) as AnyObject +// CHECK: Numbers-as-doubles cast produces [3.9375, 2.71828, 0.0] +obj = ([3.9375, 2.71828, 0] as [Double]) as AnyObject if let doubleArr = obj as? [Double] { + print(sizeof(Double.self)) print("Numbers-as-doubles cast produces \(doubleArr)") } else { print("Numbers-as-doubles failed") } -// CHECK: Numbers-as-floats cast produces [3.14159{{.*}}, 2.71828{{.*}}, 0.0] +// CHECK: Numbers-as-floats cast produces [3.9375, 2.71828{{.*}}, 0.0] if let floatArr = obj as? [Float] { + print(sizeof(Float.self)) print("Numbers-as-floats cast produces \(floatArr)") } else { print("Numbers-as-floats failed")