Saya mencari pendekatan yang efisien untuk menghitung b (katakan a = 2
dan b = 50
). Untuk memulai, saya memutuskan untuk melihat implementasi Math.Pow()
fungsi. Tetapi dalam .NET Reflector , yang saya temukan adalah ini:
[MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical]
public static extern double Pow(double x, double y);
Apa saja sumber daya yang dapat saya lihat sebagai apa yang terjadi di dalam ketika saya memanggil Math.Pow()
fungsi?
InternalCall
denganextern
pengubah (karena mereka tampaknya saling bertentangan), silakan lihat pertanyaan (dan jawaban yang dihasilkan) yang saya posting tentang hal yang sama.2^x
operasi jikax
bilangan bulat hasilnya adalah operasi shift. Jadi mungkin Anda bisa membuat hasilnya menggunakan mantissa2
dan eksponenx
.Jawaban:
Itu berarti bahwa metode ini benar-benar diimplementasikan dalam CLR, ditulis dalam C ++. Kompilator just-in-time berkonsultasi dengan tabel dengan metode yang diimplementasikan secara internal dan mengkompilasi panggilan ke fungsi C ++ secara langsung.
Melihat kode membutuhkan kode sumber untuk CLR. Anda bisa mendapatkannya dari distribusi SSCLI20 . Itu ditulis di sekitar kerangka waktu. NET 2.0, saya telah menemukan implementasi tingkat rendah, ingin
Math.Pow()
tetap sebagian besar akurat untuk versi CLR nanti.Tabel pencarian terletak di clr / src / vm / ecall.cpp. Bagian yang relevan dengan
Math.Pow()
terlihat seperti ini:Mencari "COMDouble" akan membawa Anda ke clr / src / classlibnative / float / comfloat.cpp. Saya akan menghindarkan Anda kodenya, lihat saja sendiri. Ini pada dasarnya memeriksa kasus sudut, lalu memanggil versi CRT untuk
pow()
.Satu-satunya detail implementasi lain yang menarik adalah makro FCIntrinsic dalam tabel. Itu petunjuk bahwa jitter dapat mengimplementasikan fungsi sebagai intrinsik. Dengan kata lain, gantilah panggilan fungsi dengan instruksi kode mesin titik mengambang. Yang tidak demikian halnya
Pow()
, tidak ada instruksi FPU untuk itu. Namun yang pasti untuk operasi sederhana lainnya. Yang perlu dicatat adalah bahwa ini dapat membuat matematika floating point dalam C # secara substansial lebih cepat daripada kode yang sama dalam C ++, periksa jawaban ini untuk alasan mengapa.Omong-omong, kode sumber untuk CRT juga tersedia jika Anda memiliki versi lengkap dari direktori Visual Studio vc / crt / src. Namun, Anda akan menabrak tembok
pow()
, Microsoft membeli kode itu dari Intel. Melakukan pekerjaan yang lebih baik daripada para insinyur Intel tidak mungkin. Meskipun identitas buku sekolah menengah saya dua kali lebih cepat ketika saya mencobanya:Tapi bukan pengganti yang benar karena mengakumulasi kesalahan dari 3 operasi floating point dan tidak berurusan dengan masalah domain aneh yang dimiliki Pow (). Seperti 0 ^ 0 dan -Infinity dinaikkan ke daya apa pun.
sumber
pow
sangat sulit untuk diimplementasikan secara akurat, menjadi fungsi transendental (lihat Dilema Table-Maker's ). Jauh lebih mudah dengan kekuatan integral.Jawaban Hans Passant bagus, tetapi saya ingin menambahkan bahwa jika
b
bilangan bulat, makaa^b
dapat dihitung dengan sangat efisien dengan dekomposisi biner. Berikut ini adalah versi modifikasi dari Henry Warren's Hacker's Delight :Dia mencatat bahwa operasi ini optimal (apakah jumlah minimum operasi aritmatika atau logis) untuk semua b <15. Juga tidak ada solusi yang diketahui untuk masalah umum menemukan urutan faktor optimal untuk menghitung
a^b
b selain dari luas Cari. Ini masalah NP-Hard. Jadi pada dasarnya itu berarti bahwa dekomposisi biner sebaik yang didapatnya.sumber
a
merupakan angka floating point.a
menjadi bilangan bulat, tetapi kode itu. Sebagai akibatnya, saya bertanya-tanya tentang keakuratan hasil perhitungan teks "sangat efisien".Jika tersedia versi C dari
pow
indikasi apa pun, itu tidak terlihat seperti apa yang Anda harapkan. Tidak akan banyak membantu bagi Anda untuk menemukan versi .NET, karena masalah yang Anda selesaikan (yaitu yang dengan bilangan bulat) adalah urutan besarnya yang lebih sederhana, dan dapat diselesaikan dalam beberapa baris kode C # dengan eksponensial oleh algoritma kuadrat .sumber