Skip to content

Commit a655122

Browse files
committed
When parsing floating-point from String, underflow to 0, overflow to infinity
Previously, overflow and underflow both caused this to return `nil`, which causes several problems: * It does not distinguish between a large but valid input and a malformed input. `Float("3.402824e+38")` is perfectly well-formed but returns nil * It differs from how the compiler handles literals. As a result, `Float(3.402824e+38)` is very different from `Float("3.402824e+38")` * It's inconsistent with Foundation Scanner() * It's inconsistent with other programming languages This is exactly the same as #25313 Fixes rdar://problem/36990878
1 parent 38c8bbd commit a655122

File tree

3 files changed

+9
-22
lines changed

3 files changed

+9
-22
lines changed

stdlib/public/SwiftShims/RuntimeShims.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,19 @@ SWIFT_RUNTIME_STDLIB_API
3131
void *_swift_objCMirrorSummary(const void * nsObject);
3232

3333
/// Call strtold_l with the C locale, swapping argument and return
34-
/// types so we can operate on Float80. Return NULL on overflow.
34+
/// types so we can operate on Float80.
3535
SWIFT_RUNTIME_STDLIB_API
3636
const char *_swift_stdlib_strtold_clocale(const char *nptr, void *outResult);
3737
/// Call strtod_l with the C locale, swapping argument and return
38-
/// types so we can operate consistently on Float80. Return NULL on
39-
/// overflow.
38+
/// types so we can operate consistently on Float80.
4039
SWIFT_RUNTIME_STDLIB_API
4140
const char *_swift_stdlib_strtod_clocale(const char *nptr, double *outResult);
4241
/// Call strtof_l with the C locale, swapping argument and return
43-
/// types so we can operate consistently on Float80. Return NULL on
44-
/// overflow.
42+
/// types so we can operate consistently on Float80.
4543
SWIFT_RUNTIME_STDLIB_API
4644
const char *_swift_stdlib_strtof_clocale(const char *nptr, float *outResult);
4745
/// Call strtof_l with the C locale, swapping argument and return
48-
/// types so we can operate consistently on Float80. Return NULL on
49-
/// overflow.
46+
/// types so we can operate consistently on Float80.
5047
SWIFT_RUNTIME_STDLIB_API
5148
const char *_swift_stdlib_strtof16_clocale(const char *nptr, __fp16 *outResult);
5249

stdlib/public/stubs/Stubs.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -452,10 +452,6 @@ static const char *_swift_stdlib_strtoX_clocale_impl(
452452
_swift_set_errno(0);
453453
const auto result = posixImpl(nptr, &EndPtr, getCLocale());
454454
*outResult = result;
455-
if (result == huge || result == -huge || result == 0.0 || result == -0.0) {
456-
if (errno == ERANGE)
457-
EndPtr = nullptr;
458-
}
459455
return EndPtr;
460456
}
461457

test/stdlib/NumericParsing.swift.gyb

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -181,17 +181,11 @@ tests.test("${Self}/Basics") {
181181
expectNil(${Self}("0 ")) // Trailing whitespace
182182
expectNil(${Self}("\u{1D7FF}")) // MATHEMATICAL MONOSPACE DIGIT NINE
183183

184-
// Overflow and underflow. Interleave with other checks to make
185-
// sure we're not abusing errno
186-
expectEqual(0.0, ${Self}("0"))
187-
expectNil(${Self}("2e99999999999999"))
188-
expectEqual(0.0, ${Self}("0"))
189-
expectNil(${Self}("2e-99999999999999"))
190-
expectEqual(0.0, ${Self}("0"))
191-
expectNil(${Self}("-2e99999999999999"))
192-
expectEqual(0.0, ${Self}("0"))
193-
expectNil(${Self}("-2e-99999999999999"))
194-
expectEqual(0.0, ${Self}("0"))
184+
// Overflow to infinity, underflow to zero.
185+
expectEqual(.infinity, ${Self}("2e99999999999999"))
186+
expectEqual(0.0, ${Self}("2e-99999999999999"))
187+
expectEqual(-.infinity, ${Self}("-2e99999999999999"))
188+
expectEqual(0.0, ${Self}("-2e-99999999999999"))
195189
}
196190

197191
% if Self == 'Float80':

0 commit comments

Comments
 (0)