Bir bilgisayar sıfıra bölmeyi dener mi?


59

Hepimiz biliyoruz ve bir hesap makinesine koyarsam bir hata döndürür ve eğer bir program oluşturacak olsaydım (en azından C 0/0cinsinden Undefined) işletim sistemi sıfıra bölmeyi denediğimde işletim sistemini sonlandırırdı.

Ama merak ettiğim şey, bilgisayarın sıfıra bölmeyi denemeye çalışmasına mı yoksa sadece "yerleşik korumaya" mı sahip olduğu, yani "gördüğünde" 0/0hesaplamaya çalışmadan önce bile bir hata vermesi mi?


10
0/0 tanımsız, başka bir sayı / 0 farklı bir hatadır,
ikişeyi

7
0'a bölünen herhangi bir sayı tanımsızdır, matematiksel olarak konuşur.
ManoDestra

12
@jwg: "eğer bir değeri olsaydı 1 olurdu" - zorunlu değil; Farklı durumlarda değerin ne olabileceğine adanmış bütün matematik dalları var :)
psmear

11
Burada terminolojiyi açıklamak için, 0/0 bir denir belirsiz form sıfırdan farklı x / 0 iken x olan tanımsız . 0/0 ile biten bir hesaplama, genellikle gerçek bir cevap verecek şekilde farklı bir şekilde hesaplanabilir, oysa x / 0 aslında anlamsızdır.
Çağ

9
@jwg l'hopital'in kurallarıyla ilgileniyor olabilirsiniz. 0/0 1. değerini anlamına gelmez durumlar kesinlikle vardır
d0nut

Yanıtlar:


74

CPU yerleşik olarak tespit edildi. Çoğu komut kümesi mimarisi, CPU'nun tamsayı bölme için bir özel durum işleyicisine sıfıra yakalanacağını belirtir (temettünün sıfır olup olmadığını umursamıyorum).

Sıfır bölen için yapılan kontrolün, bölünme girişimi ile birlikte donanımda paralel olarak gerçekleşmesi olasıdır, ancak, rahatsız edici durumun tespiti, bölünmeyi ve tuzakları etkin bir şekilde iptal eder; bunun bölünme girişiminde bulunup bulunmadığı.

(Donanım genellikle böyle çalışır, paralel olarak birden fazla şey yapmak ve ardından uygun sonucu seçmek için daha sonra uygun işlem seçimine göre seri hale getirmek yerine her bir işlem hemen başlatılabilir.)

İstisnaya karşı çıkma mekanizmasıyla aynı tuzak, genellikle farklı add / sub / mul komutları (veya bu talimatların üzerine bir bayrak) kullanarak istediğiniz taşma algılaması açıldığında da kullanılacaktır.

Kayan nokta bölümü ayrıca sıfıra bölmek için algılamada yerleşiktir, ancak bir istisna işleyiciye binmek yerine farklı bir değer ( IEEE 754 NaN belirtir ) verir.


Varsayımca söylemek gerekirse, eğer CPU sıfıra bölme girişimi için herhangi bir algılama yapmazsa, aşağıdakileri içerebilir:

  • CPU'yu asmak (örneğin inf. döngüsünde) - bu, CPU, pay bölenden (mutlak değerde) daha küçük olduğunda durması için bölünen bir algoritma kullanıyorsa gerçekleşebilir. Bunun gibi bir takılma işlemcinin çökmesini engeller.
  • CPU, olası maksimum bölme adımlarında (örneğin, 32-bit bir makinede 31 veya 32) bölmeyi sonlandırmak için bir sayaç kullanıyorsa (muhtemelen tahmin edilebilir) bir çöp cevabı.

51
@Ankush Bir "sistem çökmesi" gerçekten CPU seviyesinde olan bir şey değildir. Sıfırla bölmeye binmeyen bir CPU'nun en muhtemel davranışı, bölme işlemini basitçe yaptığı, saçma sapan bir sonuç ürettiği ve devam ettiğidir. Tıpkı taşan iki tamsayı eklediğinizde olduğu gibi.
Ixrec

6
Kayan nokta için, "NaN" ve "tuzak" arasındaki seçim genellikle FPU'daki bayrakların çevrilmesiyle belirlenir.
Vatine

10
@Ankush lxrec'in söylediklerinin net olmadığı durumda: CPU ile ilgili olarak, çökme diye bir şey yoktur.
kullanıcı253751

7
@Ankush Birkaç durum CPU seviyesinde bir "sistem çökmesine" neden olur. Bu durumlarda termal koruma kapatma (aşırı ısınma koruması), üçlü arızalar ve benzeri durumlar hakkında konuşuyoruz . Geçersiz işlem kodları da dahil, sıradan kullanımda karşılaşacağınız hemen hemen her çarpışma , bir şekilde tuzağa düşürmek ve toparlamak ya da basitçe hataya aldırmamak ve potansiyel olarak kirli bir durumda, belki de bir hata bayrağı koymuş olarak yürütmeye devam etmek suretiyle ele alınır.
CVn

8
Eğer bölmeyi sıfıra bölmediyseniz, sonuç programlama paritesinde "Tanımsız Davranış" olur. Bu, bilgisayarın her şeyi yapabileceği anlamına gelir. Bergi'nin belirttiği gibi, bir buggy döngüsüne girip takılabilir. Bölünme mantığını uyguladıklarından ortaya çıkan bazı belirtilmemiş bit dizilerini basitçe ortaya çıkarabilir (unutma, bir bilgisayar matematiksel anlamda "bölmez". Bölmeye yetecek kadar yakın iki sayı üzerinde bir işlem yapar. biz genellikle basitçe "bölme" olarak adlandırırız.
Cort Ammon

34

Bu, dile, derleyiciye, tam sayı mı yoksa kayan nokta sayıları mı kullandığınıza vb. Bağlıdır.

Kayan nokta sayısı için çoğu uygulama , 0'a bölünmenin iyi tanımlandığı IEEE 754 standardını kullanır . 0/0, iyi tanımlanmış bir NaN (sayı değil) sonucu verir ve x ≠ için x / 0, x işaretine bağlı olarak + Infinity veya -Infinity değerini verir.

C, C ++ gibi dillerde sıfıra bölmek tanımsız davranışa neden olur. Yani dil tanımına göre her şey olabilir. Özellikle de olmasını istemediğin şeyler. Müşterinin kullandığı zaman kodu yazarken ve verileri yok ederken mükemmel çalışan her şey gibi. Yani dil açısından bunu yapma . Bazı diller , uygulamanızın çökeceğini garanti eder; Bunun nasıl uygulanacağı onlara bağlı. Bu diller için, sıfıra bölmek çökecektir.

Birçok işlemcide, işlemciye bağlı olarak farklı davranacak bir tür yerleşik "bölme" komutu vardır. Intel 32bit ve 64 bit işlemcilerde "böl" talimatları, sıfıra bölmeyi denediğinizde uygulamanızın çökmesine neden olacak. Diğer işlemciler farklı davranabilir.

Bir derleyici, bazı kodları çalıştırdığınızda sıfıra bölmenin olacağını algılarsa ve derleyici kullanıcılarına iyi davranıyorsa, muhtemelen bir uyarı verir ve yerleşik bir "böl" talimatı oluşturur, böylece davranış aynı.


22
"Intel 32bit ve 64 bit işlemcilerde" böl "yönergeleri sıfıra bölmeyi denediğinizde uygulamanızın çökmesine neden olacak.” Kaynak belirtilmeli. CPU'lar uygulamalar hakkında hiçbir fikre sahip değillerdir, yönergeleri uygularlar ve (MMU'yu eklersek) bellek erişim sınırlarını zorlarlar ( 0 halkası olmadıkça veya Intel-x86 dışındaki mimarilerde eşdeğer olmadıkça ). Talimatın Uygulama B veya İşletim Sistemi Bileşen C yerine Uygulama A'nın bir parçası olması CPU ile ilgisizdir; Talimatın Talimat X olabileceği veya Y Adresini kullanıp kullanamadığı ile ilgilidir.
CVn

1
@ MichaelKjörling yorumuna eklemek için: İşletim sisteminin bu uygulamanın (ve diğer hata türlerinin) uygulanmasında kararsızlık yolları vardır. Windows dünyasında öyle EXCEPTION_INT_DIVIDE_BY_ZEROdeğer EXCEPTION_RECORDtarafından ele alınacaktır (umarım) yüklü Structed durum işleme Handler
user45891

1
Bazen uygulamanızın çökeceğini garanti etmekten başka şeyler de yaparlar. Örneğin, birçok dil / platform, sıfıra bölme konusunda bir istisna atmalarını garanti eder. Ardından, söz konusu istisnayı kilitlenmeden yakalayabilir ve işleyebilirsiniz.
reirab,

2
"May" ı silebilirsiniz "içindeki" Diğer işlemciler farklı davranabilir ": X86 platformunun panik davranışından çok daha kullanışlı.
cmaster

13

Birisi, bölmeden önce açıkça sıfırı kontrol etmeyen bir CPU yaptıysa ne olacağını merak ediyor gibisiniz. Ne olacağı tamamen bölünmenin uygulanmasına bağlıdır. Ayrıntılara girmeden, bir tür uygulama tüm bitlerin ayarlandığı bir sonuç üretecektir, örneğin 16 bit CPU'da 65535. Başka biri kapanabilir.


1

Ama merak ettiğim şey, bilgisayar sıfıra bölmeye kalkıştığında mı, yoksa sadece "yerleşik koruma" da mı yaptığını, böylece "0/0" gördüğü zaman, onu hesaplamadan önce bile bir hata döndürdüğü mü?

Yana x/0hiçbir anlamı, dönemini yapar, bilgisayarlar her zaman sıfıra bölme kontrol edilmelidir. Burada bir sorun var: Programcılar (a+b)/cbu hesaplamanın bir anlam ifade edip etmediğini kontrol etmek için uğraşmadan hesaplama yapmak istiyor . CPU + sayı tipi + işletim sistemi + dili tarafından sıfıra bölünme yanıtının altında, çok sert bir şey yapmak (örneğin, programın çökmesine) ya da aşırı derecede iyi huylu bir şey yapmak (örn. IEEE kayan nokta NaN, "Sayı Değil" olan bir sayı gibi

Sıradan bir ortamda, bir programcının (a+b)/cmantıklı olup olmadığını bilmesi beklenir . Bu bağlamda, bölünmeyi sıfır ile kontrol etmek için hiçbir neden yoktur. Eğer sıfıra bölünme gerçekleşirse ve makine dili + uygulama dili + veri tipi + buna verilen işletim sistemi ise programın çökmesine neden oluyorsa, sorun değil. Yanıt sonunda programdaki her sayıyı kirletebilecek bir değer oluşturmaksa, bu da sorun değil.

Ne "sert bir şey" ne de "aşırı derecede iyi huylu", yüksek güvenilirlikli bilgi işlem dünyasında yapılacak doğru şey değildir. Bu varsayılan tepkiler bir hastayı öldürebilir, bir uçağı çökertebilir veya bir bombayı yanlış yere patlatabilir. Yüksek güvenilirlikli bir ortamda, (a+b)/ckod yazarken veya modern zamanlarda belki de verboten yapıları kontrol eden bir araç tarafından otomatik olarak ölüme toplanacak olan bir programcı ölüme götürülecektir. Bu ortamda, bu programcının satırları boyunca bir şeyler yazması gerekirdi div(add(a,b),c)(ve muhtemelen bazı hata durumlarını kontrol ediyordu ). Kaputun altında, div(ve ayrıca add) işlevleri / makroları bölmeye karşı sıfır (veya durumunda taşma) karşı korur add. Bu korumanın ne gerektirdiği, uygulamaya özeldir.


NaN okulda öğrenilen aritmetik uymayanlar diye yapar bunu yapar anlamına hiçbir anlam. Farklı aritmetiklere uyar
Caleth

-2

Şimdilik bunu biliyoruz x/0ve 0/0iyi tanımlanmış cevaplarımız yok. 0/0Yine de hesaplamayı denerseniz ne olur ?

Modern bir sistemde, hesaplama CPU içindeki MPU'ya iletilir ve geri dönen, geçersiz bir işlem olarak işaretlenir NaN.

Çok daha eski bir sistemde, 'çip üzerinde bölünme olmayan 80'li ev bilgisayarları gibi hesaplamalar, hangi yazılımın çalıştığı ile yapıldı. Birkaç olası seçenek var:

  • Değer sıfıra gelinceye kadar bölenin daha küçük ve daha küçük kopyalarını çıkarın ve hangi boyutlu kopyaların alındığını takip edin
    • İlk çıkarma işleminden önce sıfırı kontrol ederse, hızlı bir şekilde çıkacak ve sonuç 0
    • En az bir kere çıkarması gerektiğini varsayarsa, sonuç 1
  • Her iki sayının logaritmalarını hesaplayın, çıkartın ve e sonucun gücüne yükseltin . Yukarıdaki çıkarma yöntemine kıyasla çok verimsiz bir yöntem, ancak matematiksel olarak geçerli
    • Hesaplamaya çalışırken taşma meydana gelebilir log(0)ve yazılım ya hata işleme yordamlarını kullanır ya da kilitlenir
    • Yazılım, tüm logaritmaların belli sayıda adımda hesaplanabileceğini varsayabilir ve büyük fakat hatalı bir değer döndürebilir. Her iki logaritma aynı olacağından, fark olacaktır 0ve e 0 = 1 olur ve sonuç1

Başka bir deyişle, ne olacağı uygulamaya bağlı olacaktır ve her değer için doğru ve öngörülebilir sonuçlar üreten bir yazılım yazmak mümkün olacaktır, ancak 0/0bunun için yine de tutarlı bir şekilde tuhaf görünmektedir .


3
Bu soru tamsayılarda sıfıra bölmekle ilgilidir ve tamsayılarda olduğu gibi bir şey yoktur NaN.
David Hammen

3
Hiçbir CPU günlükleri hesaplayamaz ve bölmenin sonucunu hesaplamak için çıkaramaz. Logaritma komut zamanlaması bir bölmeden daha büyük boyutlardadır. Log (0) değeri nedir?
wallyk

1
@DavidHammen OP, bir zamanlar tamsayılardan bahsetmedi ve soruyu yorumlayan hiç kimseyi yapmadı. Tamsayılar yalnızca cevaplarda belirtilir.
CJ Dennis

@wallyk Cevabımda zaten logaritmaların very inefficientbölünme için olduğunu söyledim . Aritmetik maliyeti (toplama = çıkarma) <= çarpma <= bölmedir. Toplama işlemi ile aynı sayıda saat döngüsünde bölme yapabilen bir MPU'nuz yoksa (genellikle bir), bölme toplama ve çıkarma işleminden daha pahalıdır ve genellikle çarpma işleminden daha pahalıdır.
CJ Dennis,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.