Two stray thoughts: I agree with previous comments that `ulpOfOne` may not really be necessary.
Of the following-- ``` init(signBit: Bool, exponent: Int, significand: Self) init(magnitudeOf other: Self, signOf: Self) ``` --would it be more elegant to have the latter be `init(signOf: Self, magnitudeOf other: Self)`? On Fri, Apr 22, 2016 at 9:54 AM, Xiaodi Wu <[email protected]> wrote: > On Fri, Apr 22, 2016 at 9:13 AM, Stephen Canon via swift-evolution > <[email protected]> wrote: >> >> On Apr 21, 2016, at 9:13 PM, Jordan Rose <[email protected]> wrote: >> >> [Proposal: >> https://github.com/apple/swift-evolution/blob/master/proposals/0067-floating-point-protocols.md] >> >> 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. >> >> Semantic >> >> static var radix: Int { get } >> >> >> Does it ever make sense to have a model type that allows different instances >> to have different radices? >> >> >> No. >> >> Is there an algorithm that makes use of a model’s radix, or is this just in >> here for “completeness”? >> >> >> 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. >> >> /// A signaling NaN (not-a-number). >> @warn_unused_result >> static func signalingNaN: Self { get } >> >> >> 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? >> >> >> There are a variety of means that a softfloat type could use to implement >> signaling NaNs. Here are two of the simpler ones: >> >> (a) if running on HW with hard-float support, use native-precision >> hard-float instructions to set flags as needed. >> (b) provide operation variants that take an inout flags / parameter: >> >> mutating func add(rhs: Self, inout flags: Flags) >> >> (Also, is ‘signalingNan.isNan’ true? I assume so but since ’nan’ is implied >> to be a non-signaling NaN I’m not sure anymore.) >> >> >> Yup, that should be clarified. >> >> var signBit: Bool { get } >> >> >> 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: "Uses of Boolean methods and properties should read as assertions >> about the receiver.”) >> >> 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.) >> >> >> 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. >> >> var exponent: Int { get } >> >> >> Nitpick: it’s probably worth noting in the doc comment that this is the >> unbiased exponent value. >> >> 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’.) >> >> >> 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. > > Naive question: is it necessary to make a trade-off here? Why not an > associated type Exponent that's Int for Float, Double, and Float80, > allowing for something else for bignums? > >> 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. >> >> Naming >> >> On “NaN” vs. “Nan”: 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”. >> >> The current draft API guidelines 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.) >> >> >> Yup, this seems like a sensible rule to me. >> >> On 'isLessThanOrEqual(to:)’: I agree with Xiaodi that the argument label is >> problematic here. I think the problem is that we have two 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.) >> >> On 'isTotallyOrdered(with:)’: 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. >> >> On ‘binade’: 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. :-) >> >> >> Yup. >> >> – Steve >> >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution >> _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
