[swift-dev] Why are BinaryFloatingPoint's RawSignificand and RawExponent different type?

Jens Persson jens at bitcycle.com
Sat Aug 27 03:20:03 CDT 2016


Btw, I had a look quick at the development snapshot 08-25-a toolchain and
it seems like it has SE-0104 partly implemented.

(For example Double doesn't conform to SignedArithmetic while it does
conform to Arithmetic. And the Integer types doesn't conform to Arithmetic)

Is SE-0104 not part of Swift 3, and will thus not be included in Xcode 8 GM?

/Jens



On Sat, Aug 27, 2016 at 2:31 AM, Jens Persson <jens at bitcycle.com> wrote:

> Ok, I've learned a lot, thanks!
> /Jens
>
> On Sat, Aug 27, 2016 at 2:26 AM, Stephen Canon <scanon at apple.com> wrote:
>
>> For any given concrete type, it’s pretty straightforward to map [0, .max]
>> to [0,1) — note that this is a bit different from what you seem to have
>> been doing originally, mapping e.g. [0, 2**52) to [0, 1):
>>
>>     init(unitRange s: UInt64) {
>>         self = Self(s >> UInt64(63 - Self.significandBitCount)) * .
>> ulpOfOne/2
>>     }
>>
>> Making this generic over integer types is painful without the SE-0104
>> integer protocols, however.
>>
>> – Steve
>>
>>
>> On Aug 26, 2016, at 8:13 PM, Jens Persson <jens at bitcycle.com> wrote:
>>
>> Ah, right! Thanks again.
>> How would you make all integer type (UIntN, IntN) convertible/mappable
>> from their respective [.min, .max] range to Double/Float unit range [0, 1)?
>> /Jens
>>
>> On Sat, Aug 27, 2016 at 2:06 AM, Stephen Canon <scanon at apple.com> wrote:
>>
>>> Note that with the bug fixed, the result will still not be 1.nextDown,
>>> because the size of an ulp changes at 1; the values you produce will be
>>> space .ulpOfOne apart, but 1.nextDown is 1 - ulpOfOne/2.
>>>
>>> – Steve
>>>
>>> On Aug 26, 2016, at 8:00 PM, Jens Persson <jens at bitcycle.com> wrote:
>>>
>>> Thanks, but there seem to be something not working the same as in my
>>> original code, here is a quick test of your code:
>>>
>>> protocol BinaryFloatingPointWithBitPattern: BinaryFloatingPoint {
>>>     init(bitPattern: RawSignificand)
>>>     var bitPattern: RawSignificand { get }
>>> }
>>>
>>> extension Float: BinaryFloatingPointWithBitPattern { }
>>> extension Double: BinaryFloatingPointWithBitPattern { }
>>>
>>> extension BinaryFloatingPointWithBitPattern {
>>>     init(unitRangeFromRawSignificand s: RawSignificand) {
>>>         self = Self(bitPattern: Self(1).bitPattern | s) - 1
>>>     }
>>> }
>>>
>>> typealias T = Double
>>> // typealias T = Float
>>>
>>> let allSignificantBitsSet = T.RawSignificand((1 <<
>>> T.significandBitCount) - 1)
>>> print("bits set in signigicant:", String(allSignificantBitsSet, radix:
>>> 2).characters.count) // 52
>>> let a = T.init(bitPattern: 0)
>>> let b = T.init(bitPattern: allSignificantBitsSet)
>>> print(a) // 0.0, correct.
>>> print(b) // 2.2250738585072e-308. Wrong, this should be (1.0).nextDown.
>>>
>>>
>>> On Sat, Aug 27, 2016 at 1:57 AM, Stephen Canon <scanon at apple.com> wrote:
>>>
>>>> If BinaryFloatingPoint had init(_: RawSignificand), you could also just
>>>> write:
>>>>
>>>> extension BinaryFloatingPoint {
>>>>     init(unitRangeFromRawSignificand s: RawSignificand) {
>>>>         self = Self(s) * .ulpOfOne
>>>>     }
>>>> }
>>>>
>>>> (this is why I ask if RawSignificand is really the type you want; if
>>>> you use some concrete integer type this will work).  But once we have all
>>>> the new integer protocol conformances, we’ll have a generic init from any
>>>> integer type (this was already reviewed for FloatingPoint, but isn’t
>>>> implementable without the Integer support), which will also make this
>>>> possible.
>>>>
>>>> On Aug 26, 2016, at 7:47 PM, Stephen Canon via swift-dev <
>>>> swift-dev at swift.org> wrote:
>>>>
>>>> Assuming RawSignificand really is the type you want, I think this does
>>>> what you’re looking for?
>>>>
>>>> protocol BinaryFloatingPointWithBitPattern: BinaryFloatingPoint {
>>>>     init(bitPattern: RawSignificand)
>>>>     var bitPattern: RawSignificand { get }
>>>> }
>>>>
>>>> extension Float: BinaryFloatingPointWithBitPattern { }
>>>> extension Double: BinaryFloatingPointWithBitPattern { }
>>>>
>>>> extension BinaryFloatingPointWithBitPattern {
>>>>     init(unitRangeFromRawSignificand s: RawSignificand) {
>>>>         self = Self(bitPattern: Self(1).bitPattern | s) - 1
>>>>     }
>>>> }
>>>>
>>>> On Aug 26, 2016, at 7:38 PM, Stephen Canon via swift-dev <
>>>> swift-dev at swift.org> wrote:
>>>>
>>>> Where does your RawSignificand input come from?  Is that really the
>>>> type that you want?
>>>>
>>>> I don’t think you really need very much boilerplate at all here.
>>>>
>>>> On Aug 26, 2016, at 7:30 PM, Jens Persson <jens at bitcycle.com> wrote:
>>>>
>>>> I understand.
>>>> It's just very tempting to try and use the new static computed
>>>> properties for eg 23 and 52 etc.
>>>> I guess I'll just have to write a lot of boilerplate, or perhaps a
>>>> protocol that is just implemented by Double and Float (that will be very
>>>> similar to BinaryFloatingPoint in a lot of ways).
>>>> /Jens
>>>>
>>>> On Sat, Aug 27, 2016 at 1:25 AM, Stephen Canon <scanon at apple.com> wrote
>>>> :
>>>> This doesn’t really scale up very well, though.  BinaryFloatingPoint
>>>> needs to also be able to model e.g. Float2048 or similar; we generally
>>>> don't want to require that RawExponent to be the same type as
>>>> RawSignificand (which I think is what you’re really suggesting), because in
>>>> typical bignum usage significands are much larger than exponents.
>>>>
>>>> It sounds like maybe you actually want to be operating directly on
>>>> bitPatterns, rather than the abstract fields of the types.
>>>>
>>>> – Steve
>>>>
>>>> On Aug 26, 2016, at 7:21 PM, Jens Persson <jens at bitcycle.com> wrote:
>>>>
>>>> Oh, to more directly answer your question: I don't like having to
>>>> create a UInt (UInt64) value when all my bit manipulaton code happens in
>>>> UInt32 (for Float) for example.
>>>>
>>>> The most probable context for using these computed properties and types
>>>> of BinaryFloatingPoint is one in which specific fixed width types really
>>>> matters a lot (look at the name of the protocol and the properties and
>>>> assocated types we are talking about).
>>>>
>>>> /Jens
>>>>
>>>>
>>>> On Sat, Aug 27, 2016 at 1:15 AM, Jens Persson <jens at bitcycle.com> wr
>>>> ote:
>>>> Reason for asking is that I have this:
>>>>
>>>> extension Double {
>>>>     init(unitRangeFromRawSignificand s: RawSignificand) {
>>>>         let bitPattern = s | (1023 << 52)
>>>>         self = unsafeBitCast(bitPattern, to: Double.self) - 1.0
>>>>     }
>>>> }
>>>> extension Float {
>>>>     init(unitRangeFromRawSignificand s: RawSignificand) {
>>>>         let bitPattern = s | (127 << 23)
>>>>         self = unsafeBitCast(bitPattern, to: Float.self) - 1.0
>>>>     }
>>>> }
>>>>
>>>> But they would be better as:
>>>> extension BinaryFloatingPoint {
>>>>     init(unitRangeFromRawSignificand s: RawSignificand) {
>>>>         ... problems here, have to try casting things into
>>>> RawSignificand's type ...
>>>>     }
>>>> }
>>>>
>>>> Please have a go at that and perhaps you see what I mean or you will
>>>> come up with a nice solution that I have missed. (Speed is very important
>>>> btw.)
>>>>
>>>> /Jens
>>>>
>>>>
>>>> On Sat, Aug 27, 2016 at 1:02 AM, Stephen Canon <scanon at apple.com> wrote
>>>> :
>>>> > On Aug 26, 2016, at 6:06 PM, Jens Persson via swift-dev <
>>>> swift-dev at swift.org> wrote:
>>>> >
>>>> > I can understand why
>>>> > Double.RawSignificand is UInt64
>>>> > and
>>>> > Float.RawSignificand is UInt32
>>>> >
>>>> > But I can't understand why both
>>>> > Double.RawExponent
>>>> > and
>>>> > Float.RawExponent
>>>> > should be UInt.
>>>> >
>>>> > Why aren't they also just UInt64 and UInt32, resp.?
>>>>
>>>> Let me flip the question: why would they be UInt64 and UInt32?  Absent
>>>> a reason to prefer a specific fixed-with type, Swift integers should
>>>> generally default to being [U]Int (and ideally Int, but RawExponent
>>>> is Unsigned).
>>>>
>>>> – Steve
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> swift-dev mailing list
>>>> swift-dev at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-dev
>>>>
>>>>
>>>> _______________________________________________
>>>> swift-dev mailing list
>>>> swift-dev at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-dev
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160827/44893546/attachment.html>


More information about the swift-dev mailing list