Ok, I've learned a lot, thanks! /Jens On Sat, Aug 27, 2016 at 2:26 AM, Stephen Canon <sca...@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 <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> 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> 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> 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> 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> 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> 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> 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> 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> 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> wrote: >>> > On Aug 26, 2016, at 6:06 PM, Jens Persson via swift-dev < >>> 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 >>> https://lists.swift.org/mailman/listinfo/swift-dev >>> >>> >>> _______________________________________________ >>> swift-dev mailing list >>> swift-dev@swift.org >>> https://lists.swift.org/mailman/listinfo/swift-dev >>> >>> >>> >> >> > >
_______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev