Nie widzę operatora potęgowania zdefiniowanego w podstawowych operatorach arytmetycznych w odwołaniu do języka Swift.
Czy naprawdę nie ma w języku predefiniowanych liczb całkowitych lub zmiennoprzecinkowych?
Nie widzę operatora potęgowania zdefiniowanego w podstawowych operatorach arytmetycznych w odwołaniu do języka Swift.
Czy naprawdę nie ma w języku predefiniowanych liczb całkowitych lub zmiennoprzecinkowych?
Odpowiedzi:
Nie ma operatora, ale możesz użyć funkcji pow w następujący sposób:
return pow(num, power)
Jeśli chcesz, możesz również zmusić operatora do wywołania funkcji pow w następujący sposób:
infix operator ** { associativity left precedence 170 }
func ** (num: Double, power: Double) -> Double{
return pow(num, power)
}
2.0**2.0 //4.0
**
, więc możesz go używać na intach i nie powodować konfliktów z XOR.
-2.0**2.0 = -(2.0**2.0) = -4.0
. Jednak tutaj -2.0**2.0 = (-2.0)**2.0 = 4.0
, co może nie być przeznaczeniem i może spowodować dość nieprzyjemny i trudny do wyśledzenia błąd.
<<
i >>
. Różne priorytety prowadzą do różnych interpretacji kodu, dlatego ważna jest standaryzacja priorytetów dla wspólnych operatorów. Nie wiem, jaki jest najlepszy standard, ale dawanie << 2
i ** 2
ten sam priorytet ma sens. nshipster.com/swift-operators
Jeśli zdarzy ci się podnieść 2 do jakiejś potęgi, możesz użyć bitowego operatora przesunięcia w lewo:
let x = 2 << 0 // 2
let y = 2 << 1 // 4
let z = 2 << 7 // 256
Zauważ, że wartość „mocy” jest o 1 mniejsza niż myślisz.
Zauważ, że jest to szybsze niż pow(2.0, 8.0)
i pozwala uniknąć konieczności używania podwójnych.
let x = 0b00000001 << exponent // 2**exponent let x = 1 << 0 // 1 let x = 1 << 2 // 4 let x = 1 << 8 // 256
Dla każdego, kto szuka wersji **
operatora infix w języku Swift 3 :
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
import Darwin
dostaćpow
2**3**2
jest 512, a nie 64. Nie znam żadnego języka programowania z lewostronnym operatorem potęgowania. Wszystkie są prawicowe. Jeśli zaimplementujesz to w Swift, zdecydowanie powinieneś zrobić to prawidłowo asocjacyjnie, aby zachować zgodność z innymi popularnymi językami, a także konwencją matematyczną .
Jeśli jesteś szczególnie zainteresowany operatorem potęgowania dla Int
typu, nie sądzę, aby istniejące odpowiedzi działały szczególnie dobrze dla dużych liczb ze względu na sposób, w jaki liczby zmiennoprzecinkowe są reprezentowane w pamięci. Podczas konwersji do Float
lub Double
z, Int
a następnie z powrotem (co jest wymagane przez pow
,powf
i powl
funkcje w Darwin
module) może spowodować utratę precyzji . Oto dokładna wersja Int
:
let pow = { Array(repeating: $0, count: $1).reduce(1, *) }
Zwróć uwagę, że ta wersja nie jest szczególnie wydajna pod kątem pamięci i jest zoptymalizowana pod kątem rozmiaru kodu źródłowego.
Inna wersja, która nie utworzy tablicy pośredniej:
func pow(_ x: Int, _ y: Int) -> Int {
var result = 1
for i in 0..<y {
result *= x
}
return result
}
Podobnie jak większość języków z rodziny C, nie ma jednego.
Alternatywną odpowiedzią jest użycie NSExpression
let mathExpression = NSExpression(format:"2.5**2.5")
let answer = mathExpression.expressionValue(with: nil, context: nil) as? Double
lub
let mathExpression = NSExpression(format:"2**3")
let answer = mathExpression.expressionValue(with: nil, context: nil) as? Int