[swift-evolution] protocol-oriented integers (take 2)

Max Moiseev moiseev at apple.com
Mon Jan 30 13:31:05 CST 2017


> On Jan 29, 2017, at 4:41 AM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> 
>  
> >   static func doubleWidthMultiply(_ lhs: Self, _ rhs: Self) -> (high: Self, low: Magnitude)
> >   static func doubleWidthDivide(_ lhs: (high: Self, low: Magnitude), _ rhs: Self) -> (quotient: Self, remainder: Self)
> 
> Could these take/return a single `DoubleWidth<Self>` value instead of two separate `Self` and `Magnitude` values? Or would that present circularity problems?
> 
> Having mulled the idea of implementing an IEEE Decimal type, I'd be sad to see these return DoubleWidth<Self>. Double-width multiply as it is here is useful when you want to get the result and immediately discard either the high or the low bits, for instance. If you'd want a result of type `DoubleWidth<Foo>` instead, you could always just write `DoubleWidth<Foo>(a) * DoubleWidth<Foo>(b)`.

doubleWidthDivide should not return a DoubleWidth<T> for two reasons:
1. The components of it’s return type are not high and low, but are quotient and remainder instead.
2. In DoubleWidth<T> high is T and low is T.Magnitude, which is not the case for quotient and remainder.

Having said that, there is a solution for doubleWidthMultiply, that I think is worth trying:

enum DoubleWidth<T> {
  case .parts(high: T, low: T.Magnitude)

  var high: T { switch self { case .parts(let high, _): return high } }
  var low: T.Magnitude { switch self { case .parts(_, let low): return low } }
}

This way it will be possible to both do pattern-matching on the result of doubleWidthMultiply, and use it as a whole, accessing r.high and r.low when needed.

Max
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170130/be19c0d1/attachment.html>


More information about the swift-evolution mailing list