[swift-users] A protocol-oriented numerics library

Karl Wagner razielim at gmail.com
Sat Jun 10 09:12:18 CDT 2017


> On 10. Jun 2017, at 03:18, Xiaodi Wu via swift-users <swift-users at swift.org> wrote:
> 
> Hi all,
> 
> A few weeks ago, Joe Groff challenged users on Twitter to create a Rational<T> type making use of the new integer protocols implemented for Swift 4. As it happens, I'd already started a project to try out these new number protocols. Now that I think the most embarrassing bugs have been squashed in that project, I thought I'd share it here in case anyone else might find it useful.
> 
> NumericAnnex <https://github.com/xwu/NumericAnnex <https://github.com/xwu/NumericAnnex>> is meant to supplement the standard library's numerics facilities in Swift 4. At the moment, it provides:
> 
> * Extensions to BinaryInteger for GCD, LCM, and exponentiation
> 
> * Protocols Math (refines SignedNumeric), Real (refines Math and FloatingPoint), and PRNG  (refines Sequence and IteratorProtocol)
> 
> * Types Complex<T>, Rational<T>, and Random
> 
> Documentation is available at <https://xwu.github.io/NumericAnnex/ <https://xwu.github.io/NumericAnnex/>>.
> 
> I'd love to hear feedback. I'll follow up shortly on Swift Evolution with some thoughts on future improvements to integer protocols based on this experience.
> 
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

It looks good. 

When it comes to trig functions, personally I’ve found it helpful to introduce an “Angle<T>” type to my own projects, rather than documenting “this angle expects radians” and having users do the conversion.

public enum Angle<T: FloatingPoint> {
    case degrees(T)
    case radians(T)

    public var degrees: T {
        switch self {
        case .degrees(let degs): return degs
        case .radians(let rads): return (rads / .pi) * 180
        }
    }
    
    public var radians: T {
        switch self {
        case .degrees(let degs): return (degs / 180) * .pi
        case .radians(let rads): return rads
        }
    }
}

Allows usage such as:

func rotate(by angle: Angle<CGFloat>) { 

   let rads = angle.radians
   ...
}

rotate(by: .degrees(90))
rotate(by: .radians(.pi/2))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170610/b9a160d1/attachment.html>


More information about the swift-users mailing list