Swift의 지수 연산자
Swift 언어 참조에서 기본 산술 연산자에 정의된 지수 연산자가 없습니다.
언어에는 정말 사전 정의된 정수 또는 부동의 지수 연산자가 없습니까?
연산자는 없지만 다음과 같은 pow 기능을 사용할 수 있습니다.
return pow(num, power)
원하는 경우 운영자가 다음과 같이 pow 함수를 호출하도록 할 수도 있습니다.
infix operator ** { associativity left precedence 170 }
func ** (num: Double, power: Double) -> Double{
return pow(num, power)
}
2.0**2.0 //4.0
우연히 2를 어떤 전력으로 올리는 경우 비트 단위의 왼쪽 시프트 연산자를 사용할 수 있습니다.
let x = 2 << 0 // 2
let y = 2 << 1 // 4
let z = 2 << 7 // 256
'power' 값은 생각보다 1이 적습니다.
이 속도는 다음보다 빠릅니다.pow(2.0, 8.0)
더블을 사용하지 않아도 됩니다.
Swift 3 버전의 제품을 찾고 있는 모든 사람들을 위한 것입니다.**
infix 연산자:
precedencegroup ExponentiationPrecedence {
associativity: right
higherThan: MultiplicationPrecedence
}
infix operator ** : ExponentiationPrecedence
func ** (_ base: Double, _ exp: Double) -> Double {
return pow(base, exp)
}
func ** (_ base: Float, _ exp: Float) -> Float {
return pow(base, exp)
}
2.0 ** 3.0 ** 2.0 // 512
(2.0 ** 3.0) ** 2.0 // 64
스위프트 4.2
import Foundation
var n = 2.0 // decimal
var result = 5 * pow(n, 2)
print(result)
// 20.0
저는 그렇게 했습니다.
operator infix ** { associativity left precedence 200 }
func ** (base: Double, power: Double) -> Double {
return exp(log(base) * power)
}
하나도 없지만 당신은 가지고 있습니다.pow
기능.
대부분의 C 계열 언어들처럼, 하나도 없습니다.
특히 다음에 대한 지수 연산자에 관심이 있는 경우Int
유형, 메모리에 부동 소수점 숫자가 표시되는 방식 때문에 기존 답변이 큰 숫자에 대해 특별히 잘 작동하지 않을 것이라고 생각합니다.로 변환할 때Float
또는Double
부터Int
그런 다음 (필요한)pow
,powf
그리고.powl
의 기능.Darwin
모듈)의 정밀도가 떨어질 수 있습니다.에 대한 정확한 버전은 다음과 같습니다.Int
:
let pow = { Array(repeating: $0, count: $1).reduce(1, *) }
이 버전은 특별히 메모리 효율적이지 않으며 소스 코드 크기에 최적화되어 있습니다.
중간 배열을 만들지 않는 다른 버전:
func pow(_ x: Int, _ y: Int) -> Int {
var result = 1
for i in 0..<y {
result *= x
}
return result
}
다른 대답은 NSE 표현식을 사용하는 것입니다.
let mathExpression = NSExpression(format:"2.5**2.5")
let answer = mathExpression.expressionValue(with: nil, context: nil) as? Double
또는
let mathExpression = NSExpression(format:"2**3")
let answer = mathExpression.expressionValue(with: nil, context: nil) as? Int
이 답변은 정수의 정수 거듭제곱을 계산하기 위한 테스트되고 최적화된* 함수를 제공하는 동시에 사용자 정의의 여러 버전을 제공합니다.**
지수 연산자입니다.
적어도 이 페이지에서 읽은 것으로 봐서는 최적화되었다고 생각합니다.
Swift는 절대값이 1 미만인 결과에 대해 무엇을 해야 할지 선택해야 하기 때문에 의도적으로 이것을 제공하지 않는 것 같습니다.0으로 반올림하시겠습니까, 아니면 암시적으로 소수형으로 캐스팅하시겠습니까?컴파일러는 알 수 없으며 기본값을 선택하면 사람들이 방금 어떤 수학적 선택을 했는지 깨닫지 못하고 사용하게 될 수 있습니다.
Swift 5.3의 경우:
import Foundation
precedencegroup ExponeniationPrecedence {
associativity: right // This makes Towers of Powers work correctly
higherThan: MultiplicationPrecedence
}
infix operator ** : ExponeniationPrecedence
public func **(_ base: Int, _ exponent: Int) -> Int {
return pow(base, exponent)
}
public func **(_ base: Double, _ exponent: Double) -> Double {
return pow(base, exponent)
}
public func **(_ base: Decimal, _ exponent: Int) -> Decimal {
return pow(base, exponent)
}
public func **(_ base: Float, _ exponent: Float) -> Float {
return powf(base, exponent)
}
/// Calculate exponentiation of integer base and integer exponent, returning integer result.
///
/// Exponentiation that would result in absolute values of less than 1 (i.e. exponent is negative and base is not 1 or -1) are rounded 0.
public func pow(_ base: Int, _ exponent: Int) -> Int {
// Optimize cases for certain exponents
switch exponent {
case 0:
return 1
case 1:
return base
case _ where exponent < 0 && base != -1 && base != 1:
// Negative exponents of integers always round to zero, except if the base is 1 or -1
return 0
default:
break
}
// Optimize cases for certain bases
switch base {
case -1:
if exponent % 2 == 0 {
return -1 * base
} else {
return base
}
case 0, 1:
return base
case -2, 2:
// Use the bitwise left shift operator to efficiently calculate powers of 2 and -2
let result = 1 << exponent
if base == -2 && exponent % 2 == 1 {
return -1 * result
}
return result
default:
var result = 1
for i in 1 ... exponent {
result *= base
}
return result
}
}
/// Calculate powers of integer base and integer exponent using Foundation's pow function by casting both the base and the exponent as Doubles, calling pow, but without casting the result.
/// Useful if rounding results between -1 and 1 to zero is not acceptable.
public func pow(_ base: Int, _ exponent: Int) -> Double {
return pow(Double(base), Double(exponent))
}
/// Calculate powers of integer base and integer exponent using Foundation's pow function by casting both the base and the exponent as Doubles, calling pow, and then casting the result as an Int
/// If results are -1<x<1, round to 0.
public func castPow(_ base: Int, _ exponent: Int) -> Int {
return Int(pow(base, exponent))
}
의 테스트 사례pow(Int, Int)
함수:
// Test Exponent = 0
assert(0**0 == 1)
assert(1**0 == 1)
assert(2**0 == 1)
// Test Exponent = 1
assert(-1**1 == -1)
assert(0**1 == 0)
assert(1**1 == 1)
assert(2**1 == 2)
// Test Exponent = -1
assert(-1 ** -1 == -1)
assert(0 ** -1 == 0)
assert(1 ** -1 == 1)
assert(2 ** -1 == 0)
// Test Exponent = 2
assert(-1 ** 2 == 1)
assert(0 ** 2 == 0)
assert(1 ** 2 == 1)
assert(2 ** 2 == 4)
assert(3 ** 2 == 9)
// Test Base = 0
assert(0**0 == 1)
assert(0**1 == 0)
assert(0**2 == 0)
// Test Base = 1
assert(1 ** -1 == 1)
assert(1**0 == 1)
assert(1**1 == 1)
assert(1**2 == 1)
// Test Base = -1
assert(-1 ** -1 == -1)
assert(-1**0 == 1)
assert(-1**1 == -1)
assert(-1**2 == 1)
assert(-1**2 == 1)
assert(-1**3 == -1)
// Test Base = 2
assert(2 ** -1 == 0)
assert(2**0 == 1)
assert(2**1 == 2)
assert(2**2 == 4)
assert(2**3 == 8)
// Test Base = -2
assert(-2 ** -1 == 0)
assert(-2**0 == 1)
assert(-2**1 == -2)
assert(-2**2 == 4)
assert(-2**3 == -8)
// Test Base = 3
assert(3 ** -1 == 0)
assert(3**0 == 1)
assert(3**1 == 3)
assert(3**2 == 9)
assert(3**3 == 27)
// Test Towers of Powers
assert(2**2**2 == 16)
assert(3**2**2 == 81)
assert(2**2**3 == 256)
assert(2**3**2 == 512)
언급URL : https://stackoverflow.com/questions/24065801/exponentiation-operator-in-swift
'programing' 카테고리의 다른 글
데몬의 오류 응답: 심을 생성하지 못했습니다. OCI 런타임을 생성하지 못했습니다. container_linux.go:380...Ubuntu WSL 2에서 도커를 사용하는 동안 (0) | 2023.07.31 |
---|---|
Spring 속성 자리 표시자를 확인할 수 없습니다. (0) | 2023.07.31 |
봄에 폴더/디렉토리를 어떻게 모니터링합니까? (0) | 2023.07.31 |
나중에 사용할 주피터(IPython) 노트북 세션을 피클 또는 저장하는 방법 (0) | 2023.07.26 |
스프링 기본 스코프가 싱글톤입니까? (0) | 2023.07.26 |