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 <j...@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 <sca...@apple.com 
> <mailto:sca...@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@swift.org <mailto:swift-dev@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@swift.org <mailto:swift-dev@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 <j...@bitcycle.com 
>>>> <mailto:j...@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 <sca...@apple.com 
>>>> <mailto:sca...@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 <j...@bitcycle.com 
>>>>> <mailto:j...@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 <j...@bitcycle.com 
>>>>> <mailto:j...@bitcycle.com>> wrote:
>>>>> 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 <sca...@apple.com 
>>>>> <mailto:sca...@apple.com>> wrote:
>>>>> > On Aug 26, 2016, at 6:06 PM, Jens Persson via swift-dev 
>>>>> > <swift-dev@swift.org <mailto:swift-dev@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@swift.org <mailto:swift-dev@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-dev 
>>> <https://lists.swift.org/mailman/listinfo/swift-dev>
>> 
>> _______________________________________________
>> swift-dev mailing list
>> swift-dev@swift.org <mailto:swift-dev@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-dev 
>> <https://lists.swift.org/mailman/listinfo/swift-dev>
> 
> 

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to