OCamlに整数累乗の関数がありますか? **は浮動小数点のみです。ほとんど正確であるように見えますが、精密エラーの可能性はありませんか?** 3. = 8. 8.時々falseを返しますか?整数累乗のためのライブラリ関数はありますか?私は自分自身を書くことができましたが、効率の問題がそこに入っています。また、そのような機能がまだなければ私は驚くでしょう。OCamlで整数累乗
答えて
についてあなたの質問の浮動小数点部分:OCamlは、基礎となるシステムのpow()
関数を呼び出します。浮動小数点累乗は実装するのは難しい関数ですが、8.0
は数学的に正しい結果の1つのULP内の唯一のものであるため、2. ** 3. = 8.
をtrue
とすることは忠実である必要があります(つまり、Unit in the Last Placeに正確です)。
すべての数学ライブラリは忠実である必要がありますので、この特定の例について心配する必要はありません。しかし、not all of them actually are、あなたは心配する権利です。あなたはOCamlは(実際にはIEEE 754倍精度数を浮動した引数または累乗の結果が正確に表現できないことを、63ビット整数またはより広いを使用している場合は心配する
より良い理由は、だろう9_007_199_254_740_993
または2 +1を表すことはできません)。この場合、浮動小数点指数演算は整数の指数演算に代わるものであり、特定の実装の弱点ではありませんが、その整数を正確に表すように設計されていないためです。このテーマに読んで
(*)もう一つの楽しみの参照は、ウィリアム・カハンで「A Logarithm Too Clever by Half」です。
標準ライブラリにはありません。しかし、自分で簡単に書くことができます(速くなるようにexponentiation by squaringを使用)、またはこれを提供する拡張ライブラリを再利用します。 Batteriesには、Int.powです。以下は
提案実装です:
let rec pow a = function
| 0 -> 1
| 1 -> a
| n ->
let b = pow a (n/2) in
b * b * (if n mod 2 = 0 then 1 else a)
あなたは非常に大きな数字を操作しているので、オーバーフローの危険性がある場合、あなたはおそらく、すべての種類を提供している、などZarithとして大きな整数ライブラリを使用する必要があります累乗関数の
は、(あなたが(a^n) mod p
を計算する、「べき乗剰余」を必要とすることができ、これは、上記機能pow
、例えば、中間計算にMODを適用することにより、オーバーフローを回避する方法で行うことができる。)
グレート答えは別の実装です。残念ながら、私は1つの最良の答えを選ぶことしかできませんでした:/。また、これは常に整数累乗を実装する最速の方法であるとは私は確信していません。実際には、これらの線に沿ってプロジェクトオイラーの質問(私はまだ解決していません)があると思います。私は本当に整数のべき乗が標準ライブラリに追加されるべきだと思います。これ以上効率的ではないとしても(私は確信していませんが)、それは必要とする変換の一般的なものであり、浮動小数点からの変換と矛盾は厄介です。もちろん、ライブラリを読み込むのは難しいことではありませんが、標準ではない理由はありません。 – user2258552
一般的な場合に整数実装を実装する方法の良いアイデアがある場合は、実装を提案することを自由にしてください。 – gasche
@ user2258552整数累乗が非常に一般的であるという前提には同意できません。実際には、ほとんどの場合、小さな固定指数で作業するか、gascheが示唆するように任意の精度演算を必要とします。 TL; DR:固定精度intで整数累乗が必要であると信じて、任意の精度の算術ライブラリが必要であることを理解してください。 –
ここで(@gascheが提供するもののような)乗で累乗を使用しますが、この1つは末尾再帰
let is_even n =
n mod 2 = 0
(* https://en.wikipedia.org/wiki/Exponentiation_by_squaring *)
let pow base exponent =
if exponent < 0 then invalid_arg "exponent can not be negative" else
let rec aux accumulator base = function
| 0 -> accumulator
| 1 -> base * accumulator
| e when is_even e -> aux accumulator (base * base) (e/2)
| e -> aux (base * accumulator) (base * base) ((e - 1)/2) in
aux 1 base exponent
- 1. [InterviewBit] 2つの整数の累乗
- 2. JavaScriptでの最速の累乗累乗
- 3. z3実数累乗
- 4. 累乗剰余演算関数の整数オーバーフロー
- 5. GMP整数を2の累乗(2n)の和に変換する
- 6. べき乗累乗再帰
- 7. VBA - モジュラ累乗
- 8. Python:0から16の累乗で2の累乗
- 9. 累乗の奇数と偶数をチェック
- 10. 長整数型はC++で8の累乗では機能しません
- 11. 2の累乗数を確認する
- 12. numpyに、0の累乗から0の累乗で累乗したベクトルの各行の行列を返す関数がありますか?
- 13. ocamlのレベルの整数
- 14. 高速行列累乗
- 15. SMLオーバーフロー:累乗手続き
- 16. RSAの累乗指数で負の指数
- 17. ページテーブルエントリサイズ - なぜ2の累乗ですか?
- 18. 2の累乗でループをインクリメントする
- 19. Javaの非整数指数の累乗に負の基数を計算する方法はありますか?
- 20. 4の累乗に対して倍数を数えます。
- 21. Mathematicaのべき乗累乗と指定された係数の発見
- 22. javaで非整数値の階乗
- 23. C二乗法による累乗の実装
- 24. C++大量の10の累乗
- 25. iOSの2つのテクスチャの非累乗
- 26. 累乗法則フィッティングscipy、numpy not working
- 27. Javacardの左から右のバイナリモジュール累乗指数
- 28. グラフの累乗則の指数を計算する方法
- 29. 指数のバイナリ表現によるモジュラ累乗
- 30. 累乗のステップサイズが10で、桁数が0になる範囲関数
引数が同じであれば、浮動小数点累乗は整数累乗と同じくらい速いのですか?また、浮動小数点累乗は、-2^30≦a^b <2^30の整数a、bについては真実でなければならない、または私の特定の例の2 3や8? – user2258552
@ user2258552速度に関して:浮動小数点指数は、おそらく書き込まれた整数型のものよりも遅いでしょう。 "should"の意味について:忠実な初等関数は、その定義域を渡って1つのULPに対して正確です。すべてのlibmsは忠実でなければなりません。なぜなら、計算コストと正確さとの間で合理的な妥協点があるからです。精度は0.5です。テーブルメーカーのジレンマのために、すべてのlibmsを期待するのは少し難しいですが、1 ULPまでの精度は妥当なコストで達成できます。 (しかし、pow()もまた最も難しい初等関数の1つです) –
スピードに関して:これを踏まえて、標準ライブラリに整数累乗関数を含まないことは実際にはほとんど意味がありません... – user2258552