Я не бачу оператора піднесення до ступеня, визначеного в базових арифметичних операторах у посиланні на мову 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
**
, щоб ви могли використовувати його на ints і не конфліктувати з XOR.
-2.0**2.0 = -(2.0**2.0) = -4.0
. Однак тут -2.0**2.0 = (-2.0)**2.0 = 4.0
, що може бути не за призначенням і може спричинити досить неприємну і важку для відстеження помилку.
<<
та >>
. Різні пріоритети призведуть до різної інтерпретації коду, тому стандартизація пріоритету для звичайних операторів є важливою. Я не знаю, що є найкращим стандартом, але надання << 2
і ** 2
той самий пріоритет має певний сенс. nshipster.com/swift-operators
Якщо ви випадково піднімаєте 2 до деякої потужності, ви можете скористатися побітовим оператором лівого зсуву:
let x = 2 << 0 // 2
let y = 2 << 1 // 4
let z = 2 << 7 // 256
Зверніть увагу, що значення "потужності" на 1 менше, ніж ви можете подумати.
Зауважте, що це швидше, ніж pow(2.0, 8.0)
дозволяє вам уникнути необхідності використовувати подвійні.
let x = 0b00000001 << exponent // 2**exponent let x = 1 << 0 // 1 let x = 1 << 2 // 4 let x = 1 << 8 // 256
Для тих, хто шукає версію **
оператора інфіксу 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
отриматиpow
2**3**2
- це 512, а не 64. Я не знаю жодної мови програмування з ліво-асоціативним оператором піднесення. Вони всі право-асоціативні. Якщо ви впроваджуєте це в Swift, ви, безумовно, повинні зробити це правильно-асоціативно, щоб відповідати іншим популярним мовам, а також математичним умовам .
Якщо ви спеціально зацікавлені в операторі степенування для 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
}
Як і більшість сімейних мов C, такої немає.
Альтернативна відповідь - використання NSExpression
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