pow()の非浮動の代替はありますか?


9

私はArduinoのWebサイトでLANGUAGE REFERENCEを調べましたが、Float以外の相当するものを見つけることができません。pow() 何か大きなものが欠けているはずですが、私にとっては困っています。pow()数学の見出しの下のFUNCTIONS列で(予想どおり)見つかりましたが、[base]と[exponent]の両方のパラメーターが両方とも(float)であると表示されています。そして、Mathという見出しの下には、6つのエントリしかありません。それらは整数バージョンではないようです。私がやりたいのは、0から10までの指数を使用して2の累乗を生成することだけです。2^ 0 = 1、2 ^ 1 = 2、2 ^ 2 = 4、2 ^ 3 = 8、2 ^ 4 = 16、 2 ^ 5 = 32、2 ^ 6 = 64、2 ^ 7 = 128、2 ^ 8 = 256、2 ^ 9 = 512、2 ^ 10は1024

フロートを使用するのはこれができる唯一の方法ですか?私は現実と対立しているように感じ始め、実際に自分の薬を数えましたが、私はあるべき場所にいます。あなたの時間を無駄にしてしまったこの悪質な見落としを事前にお詫び申し上げますが、私は9ページすべてのタグを調べ、考えられる限りの検索を行ってきました。私はそれほど多くの時間を費やしていないことを認めますが、これはたった5分のことになると確信していました。


2
整数pow()の一般的なケースについては、stackoverflow.com / questions / 101439 /…を参照してください。2の累乗の場合は、シフトを使用します。
Peter Cordes

回答:


8

一般的なケースでは、@ dat_haの答えは正しいですが、非常に特殊なケースが必要なことに注意してください。2のべき乗です。コンピュータは2進算術を使用するため、2の累乗を含む演算では、いくつかのショートカットが利用できることがよくあります。

数値を2のべき乗で乗算するには、左シフト演算(<<)を使用します。これは、数値のバイナリ表現のビット(つまり、ビット)を文字通り左にシフトします。基数2では、ビットを1桁左にシフトすることは、2を乗算することと同じです。これは、基数10で桁を1桁左にシフトすることは、10を乗算することと同じです。C++の左シフト演算子の完全な説明、スタックオーバーフローでこの回答を参照してください。

左シフトは情報を失う可能性があることに注意することが重要です。最後からシフトされたビットは失われます。2から10までの累乗が必要なため、Arduino Unoで最大値2^15-1持つ符号付き整数を使用する場合は安全です。

これらの警告を踏まえて、これらの制約内で2の累乗を計算する関数を次に示します。左シフト演算は非常に低レベルの演算であり、乗算は実際には実行されないため、これは非常に高速なコードです。

int pow2(int p){
    return 1 << p;
}

エラー:を使用する場合、最大2 ^ 32-1になることがありunsigned longます。
Dat Ha

@DatHaありがとう、編集中に "signed"という単語を失ったようです。修繕。
Jason Clark、

1
任意精度の整数演算の実装を使用する場合、2 ^ 32-1を超える可能性があります
Dat Han Bag

具体的には、pow()の結果に対する整数変換の結果が2の累乗に対して機能しない理由を知りたいのですが、pow(2,3)は8.00を返しますが、int(8.00)は8を返します、int(pow(2,3))は7を返します!
KDM 2018年

1

それはで動作しintdoublelongfloatunsigned longそしてunsigned intまた働くべきです。フロートのみを使用する必要はありません。

お役に立てば幸いです。


上記の答えが機能する理由は、実数のセット(浮動小数点を含む)に整数のセットが含まれているためです
Dat Han Bag

@DatHanBag:さらに重要なことに、すべての32ビット整数はで正確に表現できdoubleます。実際には、IEEE浮動小数点は2進数の仮数/指数表現に基づいているため、2のべき乗はすべて2 ^ 53(doubleすべての任意の整数を表すことができない点、最後の1単位)を正確に表すことができます。仮数は1.0より大きい)。
Peter Cordes

@PeterCordesはい、私はそれを知っていました。多分私は答えについての私のコメントでarduinoの浮動小数点数と整数セットを参照するとき、「有界セット」と言ったはずです
Dat Han Bag

4
これはpow()整数に使用するという一般的な質問に対するやや有効な回答ですが、AFAICT arduinoにはハードウェア浮動小数点さえないため、恐ろしい回答です。log2(n)時間で実行され、結果を累積するために加算するこのような整数pow()実装は、おそらくおそらくより良いパフォーマンスを発揮し、2の累乗に対してビットシフトが機能することは、この質問に対するひどい答えになるだけです。
Peter Cordes

1
@PeterCordesは「ひどい答えです」。-質の低い単純な答えのようなものであることに同意しました。pow()は確かにlog2(n)で計算可能です-学校で学んだ簡単な方法(数値をそれ自体で乗算することはそれほど効率的ではありません)。たとえば、非常に大きな整数のフーリエ変換を使用すると、より適切に実行できます。しかし、多分、OPはそれを受け入れ、好きになるでしょう。
Dat Han Bag
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.