Kita semua tahu 0/0
adalah Undefined
dan kembali kesalahan jika saya harus memasukkannya ke dalam kalkulator, dan jika saya harus membuat sebuah program (dalam C setidaknya) OS akan menghentikannya ketika saya mencoba untuk membagi dengan nol.
Tetapi yang saya bertanya-tanya adalah apakah komputer bahkan mencoba untuk membaginya dengan nol , atau apakah ia hanya memiliki "perlindungan bawaan", sehingga ketika "melihat" 0/0
ia mengembalikan kesalahan bahkan sebelum mencoba menghitungnya?
math
error-handling
arithmetic
Ankush
sumber
sumber
Jawaban:
CPU memiliki deteksi bawaan. Sebagian besar arsitektur set instruksi menentukan bahwa CPU akan menjebak ke handler pengecualian untuk integer divide dengan nol (saya tidak berpikir itu peduli jika dividennya nol).
Ada kemungkinan bahwa pemeriksaan untuk nol pembagi terjadi secara paralel dalam perangkat keras bersama dengan upaya untuk melakukan pembagian, namun, deteksi kondisi yang menyinggung secara efektif membatalkan pembagian dan perangkap sebagai gantinya, jadi kami tidak dapat benar-benar mengetahui apakah ada bagian yang dari itu mencoba divisi atau tidak.
(Perangkat keras sering bekerja seperti itu, melakukan banyak hal secara paralel dan kemudian memilih hasil yang sesuai setelah itu karena masing-masing operasi dapat segera memulai alih-alih membuat serial tentang pilihan operasi yang sesuai.)
Mekanisme trap to exception yang sama juga akan digunakan ketika deteksi overflow dihidupkan, yang Anda minta biasanya dengan menggunakan instruksi add / sub / mul yang berbeda (atau tanda pada instruksi tersebut).
Divisi floating point juga telah dibangun dalam deteksi untuk divide oleh nol, tetapi mengembalikan nilai yang berbeda ( IEEE 754 menentukan NaN ) alih-alih menjebak ke handler pengecualian.
Secara hipotesis, jika CPU menghilangkan deteksi apa pun untuk mencoba membaginya dengan nol, masalahnya dapat mencakup:
sumber
Itu tergantung pada bahasa, pada kompiler, pada apakah Anda menggunakan bilangan bulat atau angka floating point, dan sebagainya.
Untuk angka floating point, sebagian besar implementasi menggunakan standar IEEE 754 , di mana pembagian dengan 0 didefinisikan dengan baik. 0/0 memberikan hasil NaN yang jelas (bukan-angka), dan x / 0 untuk x ≠ 0 memberikan + Infinity atau -Infinity, tergantung pada tanda x.
Dalam bahasa seperti C, C ++ dll pembagian dengan nol memanggil perilaku tidak terdefinisi. Jadi menurut definisi bahasa, apa pun bisa terjadi. Terutama hal-hal yang tidak Anda inginkan terjadi. Seperti semuanya bekerja dengan sangat baik ketika Anda menulis kode dan menghancurkan data saat pelanggan Anda menggunakannya. Jadi dari sudut pandang bahasa, jangan lakukan ini . Beberapa bahasa menjamin bahwa aplikasi Anda akan macet; terserah mereka bagaimana ini diterapkan. Untuk bahasa-bahasa tersebut, pembagian dengan nol akan macet.
Banyak prosesor memiliki semacam instruksi "bagi" built-in, yang akan berperilaku berbeda tergantung pada prosesor. Pada prosesor Intel 32bit dan 64 bit, instruksi "bagi" akan membuat aplikasi Anda macet ketika Anda mencoba membagi dengan nol. Prosesor lain mungkin berperilaku berbeda.
Jika kompiler mendeteksi bahwa pembagian dengan nol akan terjadi ketika Anda mengeksekusi beberapa kode, dan kompiler itu baik untuk penggunanya, itu kemungkinan akan memberi Anda peringatan, dan menghasilkan instruksi "bagi" yang sudah ada di dalamnya sehingga perilakunya adalah sama.
sumber
EXCEPTION_INT_DIVIDE_BY_ZERO
nilaiEXCEPTION_RECORD
yang akan ditangani oleh Strlered Exception Handling Handler Handler yang diinstal (mudah-mudahan)Sepertinya Anda bertanya-tanya apa yang akan terjadi jika seseorang membuat CPU yang tidak secara eksplisit memeriksa nol sebelum membaginya. Apa yang akan terjadi tergantung sepenuhnya pada implementasi divisi. Tanpa merinci, satu jenis implementasi akan menghasilkan hasil yang memiliki semua bit ditetapkan, misalnya 65535 pada CPU 16-bit. Yang lain mungkin menutup telepon.
sumber
Karena
x/0
tidak masuk akal, titik, komputer harus selalu memeriksa pembagian dengan nol. Ada masalah di sini: Programmer ingin menghitung(a+b)/c
tanpa harus repot memeriksa apakah perhitungan itu masuk akal. Respons di bawah-the-kap untuk pembagian dengan nol oleh CPU + nomor jenis + sistem operasi + bahasa adalah baik melakukan sesuatu yang agak drastis (misalnya, crash program) atau melakukan sesuatu yang terlalu jinak (misalnya, menciptakan nilai yang membuat tidak ada akal seperti floating point IEEENaN
, angka yang "Bukan Angka").Dalam pengaturan biasa, seorang programmer diharapkan tahu apakah itu
(a+b)/c
masuk akal. Dalam konteks ini, tidak ada alasan untuk memeriksa pembagian dengan nol. Jika pembagian dengan nol tidak terjadi, dan jika bahasa mesin + bahasa implementasi + tipe data + respons sistem operasi untuk membuat program macet, tidak apa-apa. Jika responsnya adalah menciptakan nilai yang pada akhirnya mungkin mencemari setiap angka dalam program, tidak apa-apa juga.Baik "sesuatu yang drastis" atau "terlalu jinak" adalah hal yang tepat untuk dilakukan di dunia komputasi dengan keandalan tinggi. Respons default itu mungkin membunuh seorang pasien, menabrak pesawat, atau membuat bom meledak di tempat yang salah. Dalam lingkungan keandalan yang tinggi, seorang programmer yang menulis
(a+b)/c
akan dipilih mati selama tinjauan kode, atau di zaman modern, mungkin dipilih mati secara otomatis oleh alat yang memeriksa konstruksi verboten. Dalam lingkungan ini, programmer itu seharusnya telah menulis sesuatu di sepanjang barisdiv(add(a,b),c)
(dan mungkin beberapa memeriksa status kesalahan). Di bawah kap, fungsidiv
(dan jugaadd
) fungsi / makro melindungi terhadap pembagian dengan nol (atau meluap dalam kasusadd
). Apa yang dibutuhkan oleh perlindungan itu sangat spesifik untuk implementasi.sumber
Kami tahu sekarang
x/0
dan0/0
tidak memiliki jawaban yang jelas. Apa yang terjadi jika Anda tetap mencoba menghitung0/0
?Pada sistem modern, perhitungan dilewatkan ke MPU dalam CPU dan ditandai sebagai operasi ilegal, kembali
NaN
.Pada sistem yang jauh lebih tua, seperti komputer rumah '80 -an yang tidak memiliki divisi on-chip, perhitungan dilakukan oleh perangkat lunak apa pun yang sedang berjalan. Ada beberapa pilihan yang mungkin:
0
1
log(0)
dan perangkat lunak akan menggunakan rutinitas penanganan kesalahannya, atau crash0
dan e 0 = 1, memberikan hasil1
Dengan kata lain, itu akan tergantung pada implementasi apa yang akan terjadi dan akan mungkin untuk menulis perangkat lunak yang menghasilkan hasil yang benar dan dapat diprediksi untuk setiap nilai tetapi nilai-nilai yang tampaknya aneh untuk
0/0
itu tetap saja, masih konsisten secara internal.sumber
NaN
dalam bilangan bulat.very inefficient
untuk pembagian. Biaya untuk hitung adalah (penjumlahan = pengurangan) <= perkalian <= pembagian. Jika Anda tidak memiliki MPU yang dapat melakukan pembagian dalam jumlah siklus clock yang sama dengan penambahan (biasanya satu), maka pembagian lebih mahal daripada penambahan dan pengurangan dan biasanya lebih mahal dari perkalian juga.