<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 21, 2016, at 9:13 PM, Jordan Rose <<a href="mailto:jordan_rose@apple.com" class="">jordan_rose@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">[Proposal: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0067-floating-point-protocols.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0067-floating-point-protocols.md</a>]</div><div class=""><br class=""></div><div class="">This is super impressive. I do have several bits I’m uncomfortable with, however. I’ll try to separate that into “semantic” and “naming” sections.</div><div class=""><br class=""></div><div class=""><b class="">Semantic</b></div><div class=""><b class=""><br class=""></b></div><div class=""><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal; color: rgb(51, 51, 51);" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">static</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> radix: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span> { <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">get</span> }</pre><div class=""><br class=""></div></div><div class="">Does it ever make sense to have a model type that allows different instances to have different radices?</div></div></div></blockquote><div><br class=""></div><div>No.</div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Is there an algorithm that makes use of a model’s radix, or is this just in here for “completeness”?</div></div></blockquote><div><br class=""></div><div>If you know ulp, radix, and exponent range, you can infer basically all the other numerical details of the type. One good example would be the constant that Dave mentioned, “maxResultOfAdding1”. You can compute this if you know radix and ulp. The radix is also the bound on how large the relative spacing between consecutive numbers can get, which is sometimes important for computing accurate bounds. These are all somewhat niche, but the problem is that there’s no good way to get this value if you don’t have it, and it imposes “zero” implementation burden.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal; color: rgb(51, 51, 51);" class=""> <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// A signaling NaN (not-a-number).</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">@warn_unused_result</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">static</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> signalingNaN: <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">Self</span> { <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">get</span> }
</pre></div><div class=""><br class=""></div><div class="">I’m not sure it really makes sense for a Bignum / APFloat type to support such a value. But really I think this is just underspecified. What does it mean, in terms of this protocol and its uses, for a NaN to be signaling? Is it just a specific “color" of NaN, with no semantic requirements other than being distinguishable?</div></div></div></blockquote><div><br class=""></div><div>There are a variety of means that a softfloat type could use to implement signaling NaNs. Here are two of the simpler ones:</div><div><br class=""></div><div>(a) if running on HW with hard-float support, use native-precision hard-float instructions to set flags as needed.</div><div>(b) provide operation variants that take an inout flags / parameter:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>mutating func add(rhs: Self, inout flags: Flags)</div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">(Also, is ‘signalingNan.isNan’ true? I assume so but since ’nan’ is implied to be a non-signaling NaN I’m not sure anymore.)</div></div></blockquote><div><br class=""></div><div>Yup, that should be clarified.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal; color: rgb(51, 51, 51);" class=""> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> signBit: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Bool</span> { <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">get</span> }
</pre></div><div class=""><br class=""></div><div class="">Unlike Chris, I’m strongly against this property as it stands. You should not be able to write “if someValue.signBit”; a bit is not a boolean value. (Citation: "<a href="https://swift.org/documentation/api-design-guidelines/#strive-for-fluent-usage" class="">Uses of Boolean methods and properties should read as assertions about the receiver</a>.”)</div><div class=""><br class=""></div><div class="">I’d be okay with Greg’s idea of changing the type to an enum. I’d also be okay with renaming this to a predicate, whatever the name ends up being. (“isSignBitSet”, “isSignNegative”, etc.)</div></div></div></blockquote><div><br class=""></div><div>Making it a predicate is weird, because then the three properties making up the number become `isSignBitSet`, `exponent`, and `significand`; one of these things is not like the other ones. If `signBit: Bool` were ruled out, I would rather go with Greg’s enum proposal.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal; color: rgb(51, 51, 51);" class=""> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> exponent: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span> { <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">get</span> }
</pre></div><div class=""><br class=""></div><div class="">Nitpick: it’s probably worth noting in the doc comment that this is the <i class="">unbiased</i> exponent value.</div><div class=""><br class=""></div><div class="">Also, does it matter that this is insufficient for bignums, which may have an exponent of greater than `sizeof(Int.self)` bits? (This is also a concern for a number of members of BinaryFloatingPoint, like ‘significantBitCount’.)</div></div></div></blockquote><div><br class=""></div><div>An exponent of Int.max encodes a number >= 2**Int.max. This is a staggeringly huge quantity, even when Int is 32 bits (it’s approximately 1e646456992). There are a few extremely niche applications that require numbers with greater magnitude, but they are *extremely* rare. To a good approximation, `Int` is more than enough bits, and a reasonable tradeoff.</div><div><br class=""></div><div>Ditto `significandBitCount`. I haven’t seen usage of floating-point types with more than a few thousand significand bits; billions of bits is enough. It is plausible that one could build a type that runs into this limit on a 32-bit system, but it wouldn’t be very useful; on a 64-bit system, you can’t allocate the storage for even one such value.</div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><b class="">Naming</b></div><div class=""><br class=""></div><div class=""><i class="">On “NaN” vs. “Nan”:</i> I’m not convinced that ignoring the case is the right way to go here. IMHO the clearest lowercase form is “nan” and the clearest capitalized form is “NaN”.</div><div class=""><br class=""></div><div class="">The <a href="https://swift.org/documentation/api-design-guidelines/#general-conventions" class="">current draft API guidelines</a> don’t cover this case, but if I were to add something for this, I’d say “when a word is normally written with mixed case, the lowercase form should be fully-lowercased if the first letter is naturally uppercase, and the capitalized form should have the first letter uppercased only.” That rule produces “iPhone/IPhone”, “next/NeXT”, and “nan/NaN”. (The “if the first letter is naturally uppercase” could be thrown out as well.)</div></div></blockquote><div><br class=""></div><div>Yup, this seems like a sensible rule to me.</div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><i class="">On 'isLessThanOrEqual(to:)’:</i> I agree with Xiaodi that the argument label is problematic here. I think the problem is that we have <i class="">two</i> prepositions that apply to the argument, and “pick the second one” leaves the base name feeling unbalanced. (Remember that we allow referring to a method by its basename alone when using it as a function value.)</div><div class=""><br class=""></div><div class=""><i class="">On 'isTotallyOrdered(with:)’:</i> I lost track of who said it, but I agree that this sounds like it’s “!isUnordered(with: other)”. The only name that’s coming to mind is ‘isTotallyOrderedBefore(_:)’, which isn’t great.</div><div class=""><br class=""></div><div class=""><i class="">On ‘binade’:</i> At first I thought this was a confusing term and there had to be a better one, but now I think it’s an “if you don’t know what this is, you don’t need to use it” case. :-)</div></div></blockquote><div><br class=""></div><div>Yup.</div><div><br class=""></div><div>– Steve</div></div><br class=""></body></html>