It was originally used for nan static function payload argument, but as that function has been removed from the FloatingPoint protocol, the associatedtype could also be moved down.
– Steve > On Apr 22, 2016, at 11:16 AM, Xiaodi Wu <[email protected]> wrote: > > One more stray thought: > Is there a reason RawSignificand is declared in FloatingPoint but used > only in BinaryFloatingPoint? > > > On Fri, Apr 22, 2016 at 10:02 AM, Xiaodi Wu <[email protected]> wrote: >> 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
