[解決済み】.NET FrameworkでMath.Pow()はどのように実装されていますか?
質問
を計算するための効率的な方法を探していました。
b
(例えば
a = 2
と
b = 50
). 手始めに、私は
Math.Pow()
関数を使用します。しかし
.NETリフレクター
は、これしか見つかりませんでした。
[MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical]
public static extern double Pow(double x, double y);
を呼び出したときに、内部で何が起こっているかを見ることができるリソースには、どのようなものがあるのでしょうか?
Math.Pow()
関数を使用できますか?
どのように解決するのですか?
<ブロッククオート
MethodImplOptions.InternalCall
つまり、このメソッドは実際にはC++で書かれたCLRに実装されているのです。ジャストインタイム・コンパイラーは、内部に実装されたメソッドを含むテーブルを参照し、C++関数の呼び出しを直接コンパイルします。
コードを見るには、CLRのソースコードが必要です。それは
SSCLI20の配布
. .NET 2.0の頃に書かれたもので、低レベルの実装、例えば
Math.Pow()
は、その後のCLRのバージョンでもほぼ正確である。
ルックアップテーブルはclr/src/vm/ecall.cppにあります。に関連するセクションは
Math.Pow()
はこのようになります。
FCFuncStart(gMathFuncs)
FCIntrinsic("Sin", COMDouble::Sin, CORINFO_INTRINSIC_Sin)
FCIntrinsic("Cos", COMDouble::Cos, CORINFO_INTRINSIC_Cos)
FCIntrinsic("Sqrt", COMDouble::Sqrt, CORINFO_INTRINSIC_Sqrt)
FCIntrinsic("Round", COMDouble::Round, CORINFO_INTRINSIC_Round)
FCIntrinsicSig("Abs", &gsig_SM_Flt_RetFlt, COMDouble::AbsFlt, CORINFO_INTRINSIC_Abs)
FCIntrinsicSig("Abs", &gsig_SM_Dbl_RetDbl, COMDouble::AbsDbl, CORINFO_INTRINSIC_Abs)
FCFuncElement("Exp", COMDouble::Exp)
FCFuncElement("Pow", COMDouble::Pow)
// etc..
FCFuncEnd()
"COMDouble" で検索すると clr/src/classlibnative/float/comfloat.cpp がヒットします。コードは割愛するので、自分で見てみてください。これは基本的に、コーナーケースをチェックし、CRTバージョンの
pow()
.
他の実装の詳細で興味深いのは、テーブル内のFCIntrinsicマクロだけです。これは、ジッターが関数を組込み関数として実装する可能性があることを示すヒントです。つまり、関数呼び出しを浮動小数点マシンコード命令で置き換えるのです。の場合はそうではありません。
Pow()
そのためのFPU命令がないのです。しかし、他の単純な演算は確実にできます。注目すべきは、C#の浮動小数点演算がC++の同じコードよりも大幅に高速化されることです。
この回答
はその理由です。
ちなみに、CRTのソースコードも、Visual Studioのフルバージョン vc/crt/srcディレクトリがあれば、入手可能です。で壁にぶつかります。
pow()
でも、そのコードはマイクロソフトがインテルから買い取ったものなんですよ。しかし、マイクロソフトはインテルからそのコードを購入した。インテルのエンジニアより良い仕事をすることはあり得ない。 高校生の本のIDは、試したところ2倍速かったのですが。
public static double FasterPow(double x, double y) {
return Math.Exp(y * Math.Log(x));
}
しかし、3回の浮動小数点演算による誤差を蓄積し、Pow()が持つ変な領域の問題を扱わないので、真の代用品とは言えません。 0^0や-Infinityの任意の累乗のような。
関連
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み] enumを列挙するには
-
[解決済み] intをenumにキャストするにはどうすればよいですか?
-
[解決済み] 辞書を繰り返し使用するには?
-
[解決済み] C#で文字列のエンコーディングを手動で指定せずに、一貫性のあるバイト表現を得るには?
-
[解決済み] .NETでのdecimal, float, doubleの違い?
-
[解決済み] DateTime型の誕生日から年齢を計算するにはどうしたらいいですか?
-
[解決済み] Microsoft Officeをインストールせずに、C#でExcel(.XLSおよび.XLSX)ファイルを作成するにはどうすればよいですか?
-
[解決済み] .NETでC#オブジェクトをJSON文字列に変換するには?
-
[解決済み] .NETコンソールアプリケーションでアプリケーションのパスを取得するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み] エンティティタイプ <type> は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】ソケットのアドレス(プロトコル/ネットワークアドレス/ポート)は、通常1つしか使用できない?
-
[解決済み】C# ASP.NET使用時に「WebClientのリクエスト中に例外が発生しました。
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】Socket.Selectがエラー "An operation was attempted on something that is not a socket" を返す。
-
[解決済み】エラー「必要なフォーマルパラメータに対応する引数が与えられていない」を解決する?
-
[解決済み】パラメータ付きRedirectToAction
-
[解決済み] 関数を終了するには?
-
[解決済み】WebResource.axdとは何ですか?