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 <j...@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 <sca...@apple.com > <mailto:sca...@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 <j...@bitcycle.com >> <mailto: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