Skip to content

Commit d990732

Browse files
committed
Comment updates
1 parent e3990c6 commit d990732

File tree

1 file changed

+37
-17
lines changed

1 file changed

+37
-17
lines changed

stdlib/public/core/FloatingPointToString.swift

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
/// https://doi.org/10.1145/2837614.2837654
3737
/// In particular, the Errol paper explored the impact of higher-precision
3838
/// fixed-width arithmetic on Grisu2 and showed a way to rapidly test
39-
/// the correctness of such algorithms.
39+
/// the correctness of Grisu-style algorithms.
4040
///
4141
/// A few further improvements were inspired by the Ryu algorithm
4242
/// from Ulf Anders; "Ryū: fast float-to-string conversion", 2018.
@@ -53,10 +53,12 @@
5353
/// values on 32-bit processors, and higher-precision values on all
5454
/// processors, it is considerably faster.
5555
///
56-
/// * Always Accurate. Converting the decimal form back to binary
57-
/// will always yield exactly the same value. For the IEEE 754
58-
/// formats, the round-trip will produce exactly the same bit
59-
/// pattern in memory.
56+
/// * Always Accurate. Except for NaNs, converting the decimal form
57+
/// back to binary will always yield an equal value. For the IEEE
58+
/// 754 formats, the round trip will produce exactly the same bit
59+
/// pattern in memory. This assumes, of course, that the conversion
60+
/// from text to binary uses a correctly-rounded algorithm such as
61+
/// Clinger 1990 or Eisel-Lemire 2021.
6062
///
6163
/// * Always Short. This always selects an accurate result with the
6264
/// minimum number of significant digits.
@@ -73,12 +75,27 @@
7375
/// * When present, a '.' is never the first or last character
7476
/// * There is a consecutive range of integer values that can be
7577
/// represented in any particular type (-2^54...2^54 for double).
76-
/// Never use exponential form for integral numbers in this range.
78+
/// We do not use exponential form for integral numbers in this
79+
/// range.
7780
/// * Generally follow existing practice: Don't use use exponential
7881
/// form for fractional values bigger than 10^-4; always write at
7982
/// least 2 digits for an exponent.
8083
/// * Apart from the above, we do prefer shorter output.
8184

85+
/// Note: If you want to compare performance of this implementation
86+
/// versus some others, keep in mind that this implementation does
87+
/// deliberately sacrifice some performance. Any attempt to compare
88+
/// the performance of this implementation to others should
89+
/// try to compensate for the following:
90+
/// * The output ergonomics described above do take some time.
91+
/// It would be faster to always emit the form "123456e-78"
92+
// (See `finishFormatting()`)
93+
/// * The implementations in published papers generally include
94+
/// large tables with every power of 10 computed out. We've
95+
/// factored these tables down to conserve code size, which
96+
/// requires some additional work to reconstruct the needed power
97+
/// of 10. (See the `intervalContainingPowerOf10_*` functions)
98+
8299
///
83100
/// This Swift implementation was ported from an earlier C version;
84101
/// the output is exactly the same in all cases.
@@ -90,7 +107,7 @@
90107
/// implementation to ensure that no unsafety actually occurs. For
91108
/// Float32, that testing was exhaustive -- we verified all 4
92109
/// billion possible Float32 values.
93-
/// * The Swift code uses an idiom of building up to 8 ASCII characters
110+
/// * The Swift code uses an idiom of building up to 8 digit characters
94111
/// in a UInt64 and then writing the whole block to memory.
95112
/// * The Swift version is slightly faster than the C version;
96113
/// mostly thanks to various minor algorithmic tweaks that were
@@ -348,6 +365,7 @@ fileprivate func _Float16ToASCII(
348365
// Exhaustive testing shows that the only input value
349366
// affected by this is 0.015625 == 2^-6, which
350367
// incorrectly prints as "0.01562" without this fix.
368+
// With this, it prints correctly as "0.01563"
351369
if t < lDigit || (t == lDigit && l > 0) {
352370
t += 1
353371
}
@@ -965,10 +983,12 @@ fileprivate func _Float64ToASCII(
965983
firstDigit &+= 1
966984

967985
// >90% of random binary64 values need at least 15 digits.
968-
// We already have seven, try grabbing the next 8 digits all at once.
986+
// We have seven so there's probably at least 8 more, which
987+
// we can grab all at once.
969988
let TenToTheEighth = 100000000 as UInt128; // 10^(15-bulkFirstDigits)
970989
let d0 = delta * TenToTheEighth
971990
var t0 = t * TenToTheEighth
991+
// The integer part of t0 is the next 8 digits
972992
let next8Digits = UInt32(truncatingIfNeeded: t0._high >> 32)
973993
t0 &= fractionMask
974994
if d0 < t0 {
@@ -1204,8 +1224,9 @@ fileprivate func _Float80ToASCII(
12041224
// ================================================================
12051225

12061226
#if false
1207-
// Note: We don't need _float128ToStringImpl, since that's only for backwards compatibility,
1208-
// and the legacy ABI never supported Float128.
1227+
// Note: We don't need _float128ToStringImpl, since that's only for
1228+
// backwards compatibility, and the legacy ABI never supported
1229+
// Float128.
12091230

12101231
internal func Float128ToASCII(
12111232
value d: Float128,
@@ -1331,13 +1352,12 @@ fileprivate func _backend_256bit(
13311352
as: UInt8.self)
13321353
nextDigit &+= 1
13331354

1334-
// It would be nice to generate 8 digits at a time
1335-
// and take advantage of intToEightDigits, but
1336-
// our integer portion has only 14 bits. We can't make
1337-
// that bigger without either sacrificing too much
1338-
// precision for correct Float128 or folding the first
1339-
// digits into the scaling (as we do with Double) which
1340-
// would require a back-out phase here.
1355+
// It would be nice to generate 8 digits at a time and take
1356+
// advantage of intToEightDigits, but our integer portion has only
1357+
// 14 bits. We can't make that bigger without either sacrificing
1358+
// too much precision for correct Float128 or folding the first
1359+
// digits into the scaling (as we do with Double) which would
1360+
// require a back-out phase here (as we do with Double).
13411361

13421362
// If there is at least one more digit possible...
13431363
if delta < t {

0 commit comments

Comments
 (0)