Swift言語でいくつかの整数の力を得るには?


54

、私は最近、迅速に学んでいるが、私は、私は

var a:Int = 3 
var b:Int = 3 
println(pow(a,b)) // 27 

のようなものを取得したいが、POW機能のみの二重数を扱うことができます答え

を見つけることができない基本的な問題を抱えています整数では動作しませんし、Double(a)やa.double()のようなものでintをキャストすることもできません...

なぜ整数を供給しないのですか?あいまいさのない整数を返します。 なぜ整数をdoubleにキャストできないのですか?それはちょうど3から3.0(または3.00000 ...何でも)

私は2つの整数を持っていて、私は電源操作をしたい場合、どのようにスムーズにそれを行うことができますか?

ありがとうございます!

  0

これらの型宣言がTYPOため 13 6月. 142014-06-13 02:19:04

  0

SORRY間違っている、私は 16 6月. 142014-06-16 07:22:42

50

ご希望の場合は、infixoperatorとすることができます。

// Put this at file level anywhere in your project 
infix operator ^^ { associativity left precedence 160 } 
func ^^ (radix: Int, power: Int) -> Int { 
    return Int(pow(Double(radix), Double(power))) 
} 

// ... 
// Then you can do this... 
let i = 2 ^^ 3 
// ... or 
println("2³ = \(2 ^^ 3)") // Prints 2³ = 8 

それでもXOR operatorを使用することができますので、私は2つのキャレットを使用。スウィフト3ではスウィフト3

ため

アップデートは "マジックナンバー" precedenceprecedencegroupsによって置き換えられます。

precedencegroup PowerPrecedence { higherThan: MultiplicationPrecedence } 
infix operator ^^ : PowerPrecedence 
func ^^ (radix: Int, power: Int) -> Int { 
    return Int(pow(Double(radix), Double(power))) 
} 

// ... 
// Then you can do this... 
let i2 = 2 ^^ 3 
// ... or 
print("2³ = \(2 ^^ 3)") // Prints 2³ = 8 
  0

にすることによって、前提条件を取り除くことができます。浮動小数点数についてこれを行うには、次のようにします。あなたはこれを行います:埋め込み演算子^^ {} func ^^(基数、浮動小数点数:浮動小数点数) - >浮動小数点{ 返り値Float(pow(Double(基数)、Double(基数)) } 17 4月. 152015-04-17 01:04:51

  0

func ^^ (return double(pow(Double(基数)、Double(基数)) } 17 4月. 152015-04-17 01:20:17

+3

これは、優先順位がオフであったため、これが期待どおりに動作しないことがわかりました。累乗演算子の場合は、優先順位を160に設定します(https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/doc/uid/TP40014097-CH32-ID383を参照)。そしてhttps://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html)ようなので: '中置オペレータ^^ {優先順位160} FUNC ^^' ...など 26 5月. 152015-05-26 02:34:40

  0

に私はこのソリューションが本当に好きですが、Swift 3ではうまくいきません。どのようにそれを動作させるためにどのようなアイデア? 19 9月. 162016-09-19 18:51:39

  0

Swift 3にソートされました... 20 9月. 162016-09-20 08:04:56

  0

この( 'pow')をブール値に使う方法はありますか? 'Double(Bool)'はエラーをスローし、Boolean変数をDouble型にキャストする方法については何も見つかりません。 21 9月. 162016-09-21 23:04:28

  0

なぜあなたはブーリアンの力を必要としますか?真の真偽xの真または平方根を意味しますか? 22 9月. 162016-09-22 07:14:30

  0

swiftの以前のバージョンでは、ブール値を0または1の入力としてパワー関数に使用しました。-1をベースにして、答えとして1または-1を得ることができました。これはトリックが微積分の無限級数で多く使われています。私の背景はプログラミングよりも数学的なものなので、[1,0]から[-1,1]にマッピングする方がいいのか分かりませんか?これは、私のアプリが迅速に3に更新して以来残っている26の残りのエラーのうちの9つです。 23 9月. 162016-09-23 00:52:21

+1

'func p(_ b:Bool) - > Double {return b?-1:1}'? 23 9月. 162016-09-23 05:50:55

  0

ありがとう!私はちょうど疑問符の前にスペースが必要だったので、私は昨晩問題を解決するために使い始めた多くの余分なif文を保存しました! 23 9月. 162016-09-23 20:08:40

  0

コードの品質に関する注記:実際にはこれを '^^ 'と定義することはお勧めしません。なぜなら、コードレビューで'^'vs' ^^ 'を視覚的に見つけ出すことは非常に難しく、2人の演算子は' Int'を受け入れて返します極めて異なる結果をもたらす。あなたは厄介なバグを求めています。 11 12月. 162016-12-11 21:32:06

  0

2 ^^ 3 ^^ 4のような連鎖累乗をサポートするには、連合性を追加する必要があります:right to precedencegroup。これはhttps://stackoverflow.com/a/39117806/1949877に表示されています 15 6月. 172017-06-15 02:43:23


34

変数宣言に構文エラーがありますが、それは期待どおりに動作します。あなたがしなければならないことは、Doubleにキャストし、その値をpowに渡すことだけです。あなたは2つのint型で作業している、とあなたが戻って、操作の他の側でのIntをしたい場合、あなたは本当に「のIntのみ」の実装とドンをしたい場合はその後、ちょうど

import Darwin 

let a: Int = 3 
let b: Int = 3 

let x: Int = Int(pow(Double(a),Double(b))) 

3

をintにバックケースDoubleに/から強制したい場合、それを実装する必要があります。ここには簡単な実装があります。より速いアルゴリズムがありますが、これはうまくいくでしょう:

func pow (base:Int, power:UInt) -> Int { 
    var answer : Int = 1 
    for _ in 0..power { answer *= base } 
    return answer 
} 

> pow (2, 4) 
$R3: Int = 16 
> pow (2, 8) 
$R4: Int = 256 
> pow (3,3) 
$R5: Int = 27 

本当の実装では、おそらく何らかのエラーチェックが必要でしょう。

  0

この完全に有効な答えです。 IntsからDoublesへの変換で精度が失われ、Int Powの実行可能な解決策ではない場合があります。 Swift 3 REPLで 'Double(Int.max - 1)<Double(Int.max)'を実行しようとすると驚くかもしれません。 18 8月. 162016-08-18 14:00:14

+2

これを短縮するには、これを 'reduce'呼び出しで実装できます。 18 8月. 162016-08-18 14:00:46

+1

おそらく、電源をUInt 06 2月. 172017-02-06 14:47:36


-3
func calc (base:Int, number:Int) -> Int { 
    var answer : Int = base 
    for _ in 2...number {answer *= base } 
    return answer 
    } 
    calc (2,2) 
+1

答えにコードをダンプするのではなく、コードが解決策を提供する理由を説明することをお勧めします。 24 7月. 142014-07-24 15:28:18

+1

そして、それは正しい力の機能から遠いです。指数または負の値として0はどうでしょうか? 13 11月. 142014-11-13 14:00:46


-1

私は

func^(left:NSNumber, right: NSNumber) -> NSNumber { 
    return pow(left.doubleValue,right.doubleValue) 
} 
var a:NSNumber = 3 
var b:NSNumber = 3 
println(a^b) // 27 
  0

これは、標準のxor演算子を置き換えます。これを使うと、あなたが単一のカラットをオーバーライドしていることを知らない人にとっては、あなたのコードが非常に予期しない動作をするようになります。 25 3月. 152015-03-25 20:08:44


4

少しこれよりよいが好き詳細

infix operator ^^ { associativity left precedence 160 } 
    func ^^ (radix: Int, power: Int) -> Int { 
     return Int(pow(CGFloat(radix), CGFloat(power))) 
    } 

swift - Binary Expressions


1

それとも:

var a:Int = 3 
var b:Int = 3 
println(pow(Double(a),Double(b))) 

4

あなたは(^^ソリューションは、あなたのコードを読んで誰かにおそらく明らかであるが)演算子のオーバーロードに向けたdisinclinedしている場合は、迅速な実装を行うことができます。

let pwrInt:(Int,Int)->Int = { a,b in return Int(pow(Double(a),Double(b))) } 
pwrInt(3,4) // 81 

2

fuのオーバーロードされたセットnctions(およびいくつかの他の言語を使用して代わりに「^^」の「**」を使用して - 明確な私には):フロートを使用している場合

// http://stackoverflow.com/questions/24196689/how-to-get-the-power-of-some-integer-in-swift-language 
// Put this at file level anywhere in your project 
infix operator ** { associativity left precedence 160 } 
func ** (radix: Double, power: Double) -> Double { return pow(radix, power) } 
func ** (radix: Int, power: Int ) -> Double { return pow(Double(radix), Double(power)) } 
func ** (radix: Float, power: Float) -> Double { return pow(Double(radix), Double(power)) } 

、あなたが精度を失う可能性があります。数値リテラルと整数と非整数が混在している場合は、デフォルトでDoubleになります。私は個人的には、文法や可読性の理由からpow(a、b)のような関数の代わりに数学的表現を使うことが好きですが、それは私だけです。

pow()がエラーをスローする原因となる演算子も、これらの関数でエラーを発生させるため、エラーチェックの負担は、とにかくpower関数を使用したコードに依ります。 KISS、IMHO。

ネイティブpow()関数を使用すると、たとえば平方根(2 ** 0.5)または逆(2 ** -3 = 1/8)を取ることができます。逆数または部分指数を使用する可能性があるため、私はすべてのコードを書いて、pow()関数のデフォルトのDouble型を返すようにしました。必要に応じて、IntやFloatなどに型キャストすることができます。おそらく精度が低下します。

2 ** -3 = 0.125 
2 ** 0.5 = 1.4142135623731 
2 ** 3 = 8 

0

オーバーロードを組み合わせようとすると、ジェネリックを使用しようとしましたが、動作させることができませんでした。私は最終的にジェネリックをオーバーロードまたは使用しようとする代わりにNSNumberを使用すると考えました。これは、次のように簡略化:

typealias Dbl = Double // Shorter form 
infix operator ** {associativity left precedence 160} 
func ** (lhs: NSNumber, rhs: NSNumber) -> Dbl {return pow(Dbl(lhs), Dbl(rhs))} 

次のコードは、上記と同じ機能であるが、パラメータが正常ダブルスに変換することができるかどうかを確認するエラーチェックを実装します。

func ** (lhs: NSNumber, rhs: NSNumber) -> Dbl { 
    // Added (probably unnecessary) check that the numbers converted to Doubles 
    if (Dbl(lhs) ?? Dbl.NaN) != Dbl.NaN && (Dbl(rhs) ?? Dbl.NaN) != Dbl.NaN { 
     return pow(Dbl(lhs), Dbl(rhs)) 
    } else { 
     return Double.NaN 
    } 
} 

4

時には、IntDoubleにキャストすることは実行可能なソリューションではありません。いくつかの大きさでは、この変換で精度の低下があります。たとえば、次のコードは、直感的に予想されるものを返しません。 (スイフト3。0)

Double(Int.max - 1) < Double(Int.max) // false! 

あなたは高い大きさ精度を必要とし、約負の指数心配する必要がない場合 - 一般とにかく整数で解決することはできません - そしてtail-recursive exponentiation-by-squaring algorithmのこの実装はあなたです最善の策。 this SO answerによると、これは「非対称暗号法の巨大数に対する剰余演算を行うための標準的な方法」です。

func pow(_ base: Int, _ power: Int) -> Int { 
    func expBySq(_ y: Int, _ x: Int, _ n: Int) -> Int { 
     precondition(n >= 0) 
     if n == 0 { 
      return y 
     } else if n == 1 { 
      return y * x 
     } else if n % 2 == 0 { 
      return expBySq(y, x * x, n/2) 
     } else { // n is odd 
      return expBySq(y * x, x * x, (n - 1)/2) 
     } 
    } 

    return expBySq(1, base, power) 
} 
  0

そしてもちろん、これは演算子(もっと一般的な答えが示唆するように)やIntの拡張として定義することもできますし、これらの関数をあなたの心が望むところで呼び出すこともできます。 07 2月. 172017-02-07 16:26:42


2

mklbtz整数累乗を計算するための標準的なアルゴリズムである二乗によるべき乗について正しいが、アルゴリズムの末尾再帰実装が少し混乱と思われます。 C.で二乗し、べき乗の非再帰的な実装のためのhttp://www.programminglogic.com/fast-exponentiation-algorithms/を参照してください。私はここスウィフトにそれを翻訳しようとしました:

もちろん
func expo(_ base: Int, _ power: Int) -> Int { 
    var result = 1 

    while (power != 0){ 
     if (power%2 == 1){ 
      result *= base 
     } 
     power /= 2 
     base *= base 
    } 
    return result 
} 

が、これはアップ夢見することができ、それを呼び出すために、オーバーロード演算子を作成することによって、およびより一般的なものにするために書き直すことができたので、IntegerTypeプロトコルを実装したものであれば動作しました。それを一般的にするには、おそらく何かから始めるのです。

func expo<T:IntegerType>(_ base: T, _ power: T) -> T { 
    var result : T = 1 

しかし、それはおそらく逃げ出しています。 power(2, n)を計算するのに


-1

は、単に使用:

let result = 2 << (n-1) 

0

それは判明あなたもpow()を使用することができます。たとえば、次のように10を9にすることができます。 powとともに

pow(10, 9) 

は、powf()代わりdoublefloatを返します。私はこれをSwift 4とmacOS 10.13でのみテストしました。