Define an exponentiation operator

This commit is contained in:
Xiaodi Wu 2017-08-27 00:19:57 -05:00
parent cc8f586714
commit a4a9ac7368
5 changed files with 86 additions and 19 deletions

View File

@ -684,8 +684,13 @@ extension Complex : Math {
} }
@_transparent // @_inlineable @_transparent // @_inlineable
public static func pow(_ base: Complex, _ exponent: Complex) -> Complex { public static func ** (lhs: Complex, rhs: Complex) -> Complex {
return Complex.exp(exponent * Complex.log(base)) return Complex.exp(rhs * Complex.log(lhs))
}
@_transparent // @_inlineable
public static func **= (lhs: inout Complex, rhs: Complex) {
lhs = lhs ** rhs
} }
@_transparent // @_inlineable @_transparent // @_inlineable
@ -812,7 +817,7 @@ extension Complex : Math {
if imaginary.isInfinite { if imaginary.isInfinite {
return Complex(real: .pi / 2, imaginary: -imaginary) return Complex(real: .pi / 2, imaginary: -imaginary)
} }
let a = Complex.pow(self, 2) - 1 let a = self ** 2 - 1
let b = Complex.log(self + Complex.sqrt(a)) let b = Complex.log(self + Complex.sqrt(a))
return Complex( return Complex(
real: abs(b.imaginary), real: abs(b.imaginary),
@ -928,7 +933,7 @@ extension Complex : Math {
imaginary: T(signOf: imaginary, magnitudeOf: .pi / 2) imaginary: T(signOf: imaginary, magnitudeOf: .pi / 2)
) )
} }
let a = Complex.pow(self, 2) + 1 let a = self ** 2 + 1
let b = Complex.log(self + Complex.sqrt(a)) let b = Complex.log(self + Complex.sqrt(a))
return Complex( return Complex(
real: T(signOf: real, magnitudeOf: b.real), real: T(signOf: real, magnitudeOf: b.real),
@ -984,7 +989,7 @@ extension Complex : Math {
real: .infinity, imaginary: T(signOf: imaginary, magnitudeOf: .pi / 2) real: .infinity, imaginary: T(signOf: imaginary, magnitudeOf: .pi / 2)
) )
} }
let a = Complex.pow(self, 2) - 1 let a = self ** 2 - 1
let b = Complex.log(self + Complex.sqrt(a)) let b = Complex.log(self + Complex.sqrt(a))
return Complex( return Complex(
real: T(signOf: 0, magnitudeOf: b.real), real: T(signOf: 0, magnitudeOf: b.real),

View File

@ -0,0 +1,19 @@
//
// ExponentiationOperators.swift
// NumericAnnex
//
// Created by Xiaodi Wu on 8/26/17.
//
precedencegroup ExponentiationPrecedence {
associativity: right
higherThan: MultiplicationPrecedence
}
// "Exponentiative"
infix operator ** : ExponentiationPrecedence
// Compound
infix operator **= : AssignmentPrecedence

View File

@ -10,11 +10,11 @@ extension BinaryInteger {
// MARK: Exponentiation // MARK: Exponentiation
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// Returns the result of raising `base` to the power of `exponent`, rounded /// Returns the result of raising `lhs` to the power of `rhs`, rounded to a
/// to a representable value. /// representable value.
@_transparent // @_inlineable @_transparent // @_inlineable
public static func pow(_ base: Self, _ exponent: Self) -> Self { public static func ** (lhs: Self, rhs: Self) -> Self {
var x = base, n = exponent var x = lhs, n = rhs
if Self.isSigned && n < 0 { if Self.isSigned && n < 0 {
x = 1 / x x = 1 / x
n = 0 - n n = 0 - n
@ -34,6 +34,20 @@ extension BinaryInteger {
return x * y return x * y
} }
/// Raises `lhs` to the power of `rhs` and stores the result in `lhs`, rounded
/// to a representable value.
@_transparent // @_inlineable
public static func **= (lhs: inout Self, rhs: Self) {
lhs = lhs ** rhs
}
/// Returns the result of raising `base` to the power of `exponent`, rounded
/// to a representable value.
@available(*, deprecated, message: "Use ** instead")
public static func pow(_ base: Self, _ exponent: Self) -> Self {
return base ** exponent
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// MARK: Square Root // MARK: Square Root
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -41,13 +41,21 @@ public protocol Math : SignedNumeric {
/// - rhs: The value by which to divide `lhs`. /// - rhs: The value by which to divide `lhs`.
static func /= (lhs: inout Self, rhs: Self) static func /= (lhs: inout Self, rhs: Self)
/// Returns the result of raising `base` to the power of `exponent`, rounded /// Returns the result of raising the first value to the power of the second,
/// to a representable value. /// rounded to a representable value.
/// ///
/// - Parameters: /// - Parameters:
/// - base: The base to be raised to the power of `exponent`. /// - lhs: The value to be raised to the power of `rhs`.
/// - exponent: The exponent by which to raise `base`. /// - rhs: The value by which to raise `lhs`.
static func pow(_ base: Self, _ exponent: Self) -> Self static func ** (lhs: Self, rhs: Self) -> Self
/// Raises the left-hand side to the power of the right-hand side and stores
/// the result in the left-hand side, rounded to a representable value.
///
/// - Parameters:
/// - lhs: The value to be raised to the power of `rhs`.
/// - rhs: The value by which to raise `lhs`.
static func **= (lhs: inout Self, rhs: Self)
/// Returns the natural exponential of the value, rounded to a representable /// Returns the natural exponential of the value, rounded to a representable
/// value. /// value.
@ -239,6 +247,17 @@ extension Math {
} }
extension Math { extension Math {
/// Returns the result of raising `base` to the power of `exponent`, rounded
/// to a representable value.
///
/// - Parameters:
/// - base: The base to be raised to the power of `exponent`.
/// - exponent: The exponent by which to raise `base`.
@available(*, deprecated, message: "Use ** instead")
public static func pow(_ base: Self, _ exponent: Self) -> Self {
return base ** exponent
}
/// Returns the natural exponential of `x`, rounded to a representable value. /// Returns the natural exponential of `x`, rounded to a representable value.
/// ///
/// The natural exponential of a value `x` is _e_ (2.7182818...) raised to the /// The natural exponential of a value `x` is _e_ (2.7182818...) raised to the

View File

@ -199,8 +199,13 @@ extension Float : Real {
} }
@_transparent @_transparent
public static func pow(_ base: Float, _ exponent: Float) -> Float { public static func ** (lhs: Float, rhs: Float) -> Float {
return powf(base, exponent) return powf(lhs, rhs)
}
@_transparent
public static func **= (lhs: inout Float, rhs: Float) {
lhs = lhs ** rhs
} }
@_transparent @_transparent
@ -359,14 +364,19 @@ extension Double : Real {
} }
@_transparent @_transparent
public static func pow(_ base: Double, _ exponent: Double) -> Double { public static func ** (lhs: Double, rhs: Double) -> Double {
#if os(Linux) #if os(Linux)
return Glibc.pow(base, exponent) return Glibc.pow(lhs, rhs)
#else #else
return Darwin.pow(base, exponent) return Darwin.pow(lhs, rhs)
#endif #endif
} }
@_transparent
public static func **= (lhs: inout Double, rhs: Double) {
lhs = lhs ** rhs
}
@_transparent @_transparent
public func naturalExponential() -> Double { public func naturalExponential() -> Double {
#if os(Linux) #if os(Linux)