Maafkan kenaifan yang akan jelas dalam cara saya mengajukan pertanyaan ini dan juga fakta bahwa saya menanyakannya.
Matematikawan biasanya menggunakan karena itu adalah teori yang paling sederhana / paling baik (karena kalkulus). Tetapi komputer tampaknya melakukan semuanya dalam biner, jadi apakah lebih cepat pada mesin untuk menghitung daripada ?2**x
Math::exp(x)
Jawaban:
Karena ini adalah CS dan bukan Stackoverflow, saya akan berasumsi bahwa Anda mengajukan pertanyaan tentang analisis numerik, dan (untuk menjaga hal-hal sederhana) khususnya IEEE-754 floating point. Dalam hal itu, jawaban untuk pertanyaan Anda sebagian tergantung pada apa yang Anda maksud dengan "lebih mudah", dan sebagian pada detail sistem.
Tidak ada CPU modern yang saya tahu memiliki instruksi yang dibangun di mana melakukan persis apa yang Anda harapkan baik untuk operasi (yang selanjutnya akan kita sebut , nama yang biasa dalam C) atau 2 x ( ). Keduanya diimplementasikan menggunakan fungsi perpustakaan.ex 2x
exp
exp2
Seperti halnya semua metode numerik untuk operasi transendental, ada beberapa kasus khusus yang perlu dipertimbangkan:
Namun, ada hal lain yang membuat masalah sedikit lebih rumit: domain yang berguna cukup kecil. Untuk binary32,x<−104 x>88.7
exp(x)
underflow jika atau lebih, dan overflow jika x > 88,7 atau lebih. Tidak seperti biasanya untuk operasi transendental, kita juga dapat mengabaikan kasus subnormal, karena tidak dapat dibedakan dari apakah subnormal. Semua hal di atas juga berlaku untuk , kecuali bahwa domainnya sedikit berbeda.exp(x)
1.0
x
exp2
exp2
f2xm1
Sunting: Sudah ditunjukkan dalam komentar bahwa saya harus menjelaskan beberapa terminologi baru yang digunakan dalam IEEE 754-2008. Beberapa bahasanya telah berubah sejak 1985 dan 1987, dan kebanyakan orang jauh lebih akrab dengan jargon lama.
Istilah "binary32" dan "binary64" adalah nama baru untuk angka floating-point biner 32-bit dan 64-bit, yang standar lama masing-masing disebut "tunggal" dan "ganda".
Istilah "nomor subnormal" menggantikan istilah "nomor dinormal" atau "nomor dinormalisasi" sebelumnya .
sumber
2**x
<<
1 << x
sumber
x
bukan bilangan bulat (katakanlah,20.75
), Anda akan mengatur mantissa ke2
dan eksponen ke nilai bulatx
sebagai estimasi paling akurat (representasi tepat tidak mungkin). Yang juga jauh lebih cepat daripada `pow '.Jika
2**x
fungsi pada bilangan bulat, maka saya setuju dengan jawaban Stephen, pergeseran lebih murah. Tapi saya biasanya melihat itu sebagai2^x
dan**
untuk menunjukkan exponentiation floating point. Untuk kasus ini, saya mengharapkan kinerja yang sama antara**
dan^
karena keduanyaexp
danpow
(operasi yang mendasari**
) keduanya operasi perkiraan transendental.sumber
**
dianggap sinonim untuk versi floating-point (dan, konyol saya, saya lupa keduanya akan berbeda).Karena 2 ^ x = e ^ (x * ln 2) dan e ^ x = 2 ^ (x * log2 (e)), Anda tidak akan mengharapkan banyak perbedaan.
Untuk x mendekati nol, orang biasanya akan menggunakan polinomial e ^ x = 1 + x + x ^ 2/2 + x ^ 3/6 ..., dioptimalkan dengan baik untuk memotong sesegera mungkin sambil menjaga kesalahan pembulatan kecil . Jelas 2 ^ x adalah, kecil sedikit lebih lambat untuk menghitung. "x close to 0" biasanya berupa nilai x di mana sqrt (1/2) <= e ^ x <= sqrt (2). Membatasi rentang x memastikan bahwa derajat polinom tidak perlu dipilih terlalu tinggi.
Untuk x yang lebih besar, seseorang biasanya menghitung 2 ^ x dengan membiarkan x = x '+ x' ', di mana x' adalah bilangan bulat dan -0,5 <= x '' <= 0,5. 2 ^ x 'kemudian akan dihitung dengan membangun angka floating point dengan pola bit yang tepat, dan 2 ^ x' 'dengan menggunakan metode e ^ x untuk x kecil. Di sini, 2 ^ x sedikit lebih cepat. Selain itu, jika x lebih besar (katakanlah x = 100,3), hanya mengalikan x dengan log2 (e) akan menimbulkan kesalahan pembulatan yang tidak dapat diterima (karena ada lebih sedikit bit fraksional), sehingga lebih banyak perhatian harus diambil.
Dan mudah-mudahan fungsi perpustakaan yang baik akan berhati-hati bahwa setiap kali x <= y, e ^ x <= e ^ y dan 2 ^ x <= 2 ^ y, tidak peduli apa kesalahan pembulatannya. Mencapai hal semacam itu bisa rumit.
sumber
Anda harus memahami bahwa matematika di komputer dilakukan dengan cara yang berbeda oleh perangkat lunak yang berbeda, semoga muncul dengan jawaban yang konsisten. Melihat sebagian besar perangkat lunak, saya pikir komputer berperilaku seperti komputer - baik dan akan menghitung jawabannya jauh bahkan untuk seperti 0 ^ 0. Masalahnya adalah bahwa kasus khusus melibatkan "pengakuan" yang tidak terjadi secara gratis di komputer digital. Ini berarti bahwa hanya dalam kasus-kasus di mana memiliki jawaban akan mempercepat "yang paling" akan optimasi terjadi. Tetapi dalam kasus-kasus itu akan terjadi dengan sangat baik. Perhatikan juga bahwa beberapa pengakuan berbeda mungkin harus dilakukan untuk mendapatkan jawaban yang benar. Ini disebut tingkat optimisasi kecepatan dan ini telah terjadi hingga tingkat profesional maksimum berdasarkan sebagian besar perangkat lunak yang disebut GNU "C". Ini karena di sini perbedaan menit dalam menjalankan waktu dari perangkat lunak ke perangkat lunak dan mesin ke mesin digunakan di sana sebagai angka penerimaan kualitas. Pada penerjemah lain biasanya hanya jika "bendera nol" terjadi sebagai efek samping dari perhitungan sebelumnya akan mempercepat pengenalan dilakukan. seperti 0 * x => C0.
sumber