Mengapa Spotlight memberikan nilai yang salah untuk `cos (pi / 2)`?

8

Seperti yang mungkin Anda ketahui, Spotlight dapat melakukan matematika sederhana. Misalnya, mengetik cos(pi)akan menghasilkan -1, seperti yang Anda harapkan. Saya baru saja mengetik cos(pi/2), yang seharusnya 0 tetapi memberi saya -5e-12.

Ya itu mungkin karena kesalahan pembulatan, tetapi ayolah cos(pi/2):! Menurut pendapat saya, itu jelas terlihat seperti bug. Bagaimana menurut anda?

poitroae
sumber
1
cos (x) adalah fungsi transendental. Kecuali mereka nilai hardcode untuk pi, pi / 2, dll, Anda harus mengharapkan beberapa kesalahan.
Navin
@Navin sebenarnya saya mengharapkan mereka untuk meng-hard-code nilai-nilai ini karena mereka sangat penting.
poitroae
1
piitu sendiri akan menjadi hard-coded (saat Anda mendapatkan -1 untuk cos(pi)) tetapi segera setelah Anda memanipulasinya Anda mendapatkan angka floating point, yang memiliki presisi terbatas. OSX bukan hard-code pi/2, pi/4dll, itu benar-benar melakukan operasi.
harryg
2
@harryg Meskipun ada kesalahan pembulatan yang dapat diselesaikan dengan beralih ke desimal, ini bukan salah satunya. Desimal berguna jika Anda ingin merepresentasikan dengan 0.1tepat. tepatnya, tetapi ini tidak berguna untuk bilangan irasional seperti pi yang tidak dapat direpresentasikan secara tepat dalam biner atau desimal.
CodesInChaos
1
Untuk referensi, dalam Ruby:irb(main):009:0> Math.cos(Math::PI/2) => 6.123233995736766e-17
harryg

Jawaban:

13

Ini karena kurangnya presisi pi dan karena keseluruhan semua kurangnya presisi dalam sistem bawaan.

pi = 3.1415926536

pi/2 = 1.5707963268 

cos(1.5707963268) = -5.103412e-12

FYI =  5.103412e-12 = 0.000000000005103412 ~ 0 


Tentang presisi sistem secara keseluruhan:

3.141592653589793238462643383 = 3.1415926536 

Dalam Python kita mendapatkan yang berikut:

>>> float("3.141592653589793238462643383")
3.141592653589793

Seperti yang bisa kita lihat ada masalah dengan presisi karena bahkan tidak cocok dengan representasi float.

Matthieu Riegler
sumber
Ini karena kurangnya presisi, tetapi kesalahan sebesar ini tidak dapat ditebak pada angka floating point.
Dennis Jaheruddin
2
Mungkin lebih kurang presisi dengan nilai pi.
Matthieu Riegler
5

Mereka tidak menyimpan π dengan presisi floating-point yang tidak biasa. Mereka menggunakan nilai yang salah untuk π dengan presisi ganda. Untuk perkiraan 3,1415926536 dalam biner, setidaknya 38 bit diperlukan:

3.14159265359922… > 11.001001000011111101101010100010001001

Perhatikan bahwa 2 ^ -36 adalah tentang 1.5e-11, yang bertepatan dengan trailing 99. floating-point presisi ganda memiliki signifikansi 52-bit. Untuk mengevaluasi cos(pi/2)sebagai -5e-12, satu-satunya pilihan lain yang mungkin adalah tipe 48-bit, yang akan sangat aneh.

Dekat 0 dan π, di mana turunannya hampir nol, cos (θ) tidak dapat dihitung dengan sangat akurat:

cos(3.1415926536) ≈ -0.999999999999999999999947911

Itu berbeda dari -1 sekitar 5,2e-23, yang lebih kecil dari ε untuk double, jadi cos(3.1415926536)dihitung dengan tepat -1 ... yang tidak benar.

Dekat ± π / 2, turunan [ -sin (θ) ] hampir ± 1, sehingga kesalahan pada input menjadi output.

cos(1.57079632679961) ≈ -4.71338076867830836e-12
cos(1.57079632679962) ≈ -4.72338076867830836e-12
cos(1.57079632680000) ≈ -5.10338076867830836e-12

Saya kebetulan memiliki kalkulator TI yang menampilkan satu digit lebih sedikit dan menghitung cos(π/2)sebagai -5.2e-12. Namun, ini sangat berbeda secara elektronik dan dirancang untuk memberikan nilai tepat cos(90°).

Saya akan menebak bahwa di Spotlight, cos(pi/2)sedang dihitung dengan mengambil nilai untuk π, mengkonversi ke string desimal , menyimpannya sebagai nilai biner (tepat, rasional) 11.0010010000111111011010101000100010010010101010101111 (atau 10000), membaginya dengan 2, dan kemudian pada dasarnya mengurangkan dari nilai sebenarnya dari π / 2. Anda harus mencari tahu apakah cos(pi/2 + cos(pi/2))lebih dekat ke nol (mungkin -2.2e-35).

Perkalian dengan kekuatan dua seharusnya hanya mempengaruhi eksponen, bukan signifikan. Dimungkinkan untuk menentukan bagaimana pembulatan diterapkan dengan membagi dua atau menggandakan.

pengguna130144
sumber
Tidak ada yang salah dengan Markdown - MathJax hanya diaktifkan di situs yang berhubungan dengan Matematika, bukan di SE-wide.
grg
1
cos (pi / 2 + cos (pi / 2)) ditampilkan sebagai 0 persis.
Nick Matteo
4

Ini adalah bug yang dapat direproduksi pada 10.9.2 - dan kesalahan pembulatan titik mengambang seperti itu cukup tipikal.

Nilai pi yang ditangani tanpa cukup presisi jika saya harus menebak.

  • cos (999999 * pi) tidak memiliki kesalahan
  • cos ((999999 +1) * pi) memang memiliki kesalahan - kemungkinan pembulatan

Saya akan menuju ke https://developer.apple.com/bug-reporting/ jika Anda ingin melihat aparatur perbaikan bug Apple beraksi.

bmike
sumber
5
Benarkah itu bug? Apa yang harus menjadi presisi pada operasi semacam itu?
Édouard
Saya bukan pengembang terdaftar, tetapi saya akan sangat berterima kasih jika Anda bisa mengirimkannya untuk kami!
poitroae
4
@ Édouard Anda mungkin menganggapnya sebagai bug jika pengguna telah dituntun untuk mengharapkan beberapa kemampuan untuk matematika simbolik. Sistem aljabar komputer (CAS) tentu saja akan tahu bahwa cos (π / 2) = 0 persis! Di sisi lain, hampir tidak masuk akal untuk mengharapkan Spotlight mengandung CAS. Dan di bidang aritmatika floating point, hasil seperti laporan OP diharapkan. Setiap laporan bug mungkin lebih baik diberi label permintaan fitur, mungkin.
Harald Hanche-Olsen
1
@ Edouard bmike sebenarnya benar bahwa ini adalah bug dan bukan hanya kesalahan pembulatan. Presisi yang diharapkan dari operasi tersebut, mengingat aritmatika presisi ganda standar, adalah sekitar 10 ^ -16, bukan 10 ^ -12. Anda dapat mencobanya sendiri dengan menulis program dalam bahasa favorit Anda yang memanfaatkan dukungan floating point CPU, melakukan perhitungan, dan memeriksa pola bit hasilnya. Seperti dikatakan bmike, kemungkinan alasannya adalah bahwa nilai π yang digunakan Spotlight tidak didefinisikan dengan presisi yang memadai.
Szabolcs
2
Sesuatu yang aneh sedang terjadi di sini. cos(2*acos(0)*0.5)mengembalikan sejumlah pesanan 10^-10. Jadi bukan karena konstanta π tidak cukup tepat. Saya tidak bisa menjelaskan hasil ini: terlalu presisi untuk presisi ganda dan terlalu presisi untuk presisi tunggal.
Szabolcs
4

Dari jawaban dan komentar lain yang berikut menjadi jelas:

Fakta bahwa Anda mendapatkan hasil bukan nol BUKAN bug, bahkan dengan implementasi perangkat lunak yang sempurna Anda akan mengalami batasan perhitungan floating point. Namun, kesalahan dalam urutan 10 ^ -12 sangat besar.

Ini BUKAN untuk menyalahkan ketidaktepatan angka floating point. Hasil yang Anda dapatkan hanya ini:

cos(1.5707963268)

Itu dapat divalidasi menggunakan paket perangkat lunak alternatif apa pun. Jika Anda mengevaluasi cos(pi/2)dalam salah satu paket tersebut, Anda pasti akan mendapatkan hasil yang jauh lebih dekat dengan nol dari 10 ^ -12.

Untuk menyimpulkan saya melihat dua batasan yang mungkin, salah satunya harus berlaku:

  1. Pi tidak disimpan dengan presisi yang cukup, atau setidaknya pi / 2 menghasilkan presisi yang tidak cukup
  2. Karena hanya membutuhkan presisi yang tidak memadai sebagai input

Mungkin seseorang dengan akses ke perangkat lunak dapat memvalidasi mana yang berlaku.

Pembaruan Seperti yang disebutkan dalam komentar masalah tampaknya adalah keakuratan konstanta pi.

Dennis Jaheruddin
sumber
Ini aneh. 1.5707963268 adalah hasil yang diberikan Spotlight saat Anda menghitung pi / 2. Setelah beberapa percobaan sederhana, sepertinya Spotlight menampilkan 10 angka signifikan untuk angka di bawah 1 dan 11 untuk angka di atas 1. Tetapi untuk alasan implementasi aneh apa langkah pembulatan diterapkan dalam perhitungan alih-alih setelah?
Édouard
1
Saya juga ingin menunjukkan bahwa jika Anda memberi Spotlight perkiraan yang lebih tepat pi / 2 (dengan menyalin lebih dari 10 digit dari Wolfram Alpha, misalnya), ketepatannya meningkat.
Édouard
Terima kasih telah mengonfirmasi dugaan saya bahwa presisi pi adalah penyebab kesalahan antara 0 dan sekitar 10 ^ -12 dalam pertanyaan OP.
bmike
Seberapa sering Anda melihat ini: "10 ^ -12 benar-benar besar"
GEdgar
2

Menimbang bahwa -5e-12ini adalah jumlah yang sangat kecil, ini adalah kesalahan pembulatan.

Saya pikir ini adalah konsekuensi dari sorotan yang menunjukkan lebih banyak desimal daripada yang digunakan dalam definisi pikonstanta atau deret tak hingga yang digunakan untuk menghitung fungsi trigonometri.

Alexander - Pasang kembali Monica
sumber