İstisnaları desteklemeyen bir dilde bölmeyi sıfıra nasıl kaldırabilirim?


62

Bazı işletme gereksinimlerini çözmek için yeni bir programlama dili geliştirmenin tam ortasındayım ve bu dil acemi kullanıcıları hedef alıyor. Bu nedenle, dilde istisna yönetimi için bir destek yoktur ve eklesem bile kullanmalarını beklemiyorum.

Bölme operatörünü uygulamak zorunda olduğum noktaya ulaştım ve bir bölmeyi sıfır hatayla en iyi nasıl idare edeceğimi merak ediyorum?

Bu davayla başa çıkmak için sadece üç yolum var.

  1. Hatayı yoksay ve 0sonuç olarak üret . Mümkünse bir uyarı kaydı.
  2. NaNRakamlar için olası bir değer olarak ekleyin , ancak bu NaN, dilin diğer alanlarındaki değerlerin nasıl işleneceği ile ilgili sorular ortaya çıkarır .
  3. Programın yürütülmesini sonlandırın ve ciddi bir hata oluştuğunu kullanıcıya rapor edin.

Seçenek 1, tek makul çözüm gibi görünüyor. Seçenek 3, bu dili mantık çalıştırmak için gece cronu olarak kullanılacağından pratik değildir.

Sıfır hatayla bir bölme işlemine alternatiflerim nelerdir ve # 1 seçeneğiyle devam etmenin riskleri nelerdir?


12
istisna desteği eklediyseniz ve kullanıcı bunu yakalamazsa, # 3
cırcır ucube

82
Merak ediyorum, ne tür bir aptallık gereksinimi yepyeni bir programlama dili oluşturmanızı gerektiriyor? Tecrübelerime göre, şimdiye kadar yaratılan her dilin (genellikle hem, tasarım veya gerçekleştirilmesinde) berbat ve hatta almak için makul olmayan çok çaba aldı o kadar. Orada ilk birkaç istisna vardır, ama değil ikinci ve kolayca konum olarak <vakaların% 0,01, muhtemelen ölçüm hataları ;-) konum

16
@delnan, çoğu yeni dil, iş kurallarının uygulanma biçiminden ayrılmasını sağlamak için oluşturulmuştur. Kullanıcının nasıl reject "Foo"uygulandığını bilmesi gerekmez , ancak yalnızca anahtar kelimeyi içeriyorsa bir belgeyi reddettiğini söyler Foo. Dili, kullanıcının aşina olduğu terimleri kullanarak okumayı kolaylaştırmaya çalışıyorum. Bir kullanıcıya kendi programlama dilini vermek, teknik personele bağlı olmadan iş kuralları eklemelerini sağlar.
Tepki

19
@Mathew Foscarini. Asla, asla, hatayı ihmal etmeyin ve sessizce 0 döndürün. Bölme yaparken, 0 tamamen yasal bir değer olabilir (nedense, Power Basic'te böyle bir şey var ve bu gerçekten acı verici). Kayan nokta sayılarını değiştirirseniz Nan veya Inf iyi olur ( nedenini anlamak için IEEE 754'e bakın ). Tamsayıları bölerseniz, programı durdurabilirsiniz, 0'a bölmeye asla izin verilmemelidir (gerçek bir istisna sistemi uygulamak istemiyorsanız).

16
Turing-complete bir programlama dilini haklı çıkaracak kadar karmaşık bir iş alanı kompleksi tarafından eğlendim ve büyülendim ama ciddi derecede yanlış sonuçları tolere edebilecek kadar gevşek.
Mark E. Haase,

Yanıtlar:


98

1 numaraya şiddetle tavsiye ediyorum, çünkü sadece hataları gözardı etmek tehlikeli bir anti-paterndir. Analizi zor böceklere yol açabilir. Bölme sonucunun sıfıra 0 olarak ayarlanması hiçbir anlam ifade etmiyor ve saçma bir değere sahip program yürütmeye devam etmek sorun çıkaracak. Özellikle program katılımsız çalışıyorsa. Program yorumlayıcısı programda bir hata olduğunu fark ettiğinde (ve sıfıra bölme hemen hemen her zaman bir tasarım hatasıdır), iptal etmek ve her şeyi olduğu gibi tutmak genellikle veritabanınızı çöple doldurmaktan daha çok tercih edilir.

Ayrıca, bu kalıbı tamamen takip ederek başarılı olamayacaksınız. Er ya da geç, göz ardı edilemeyecek hata durumlarıyla karşılaşacaksınız (bellek tükenmesi veya yığın taşması gibi) ve programı yine de sonlandırmak için bir yol uygulamanız gerekecek.

Seçenek # 2 (NaN kullanarak) biraz iş olurdu, ama sandığınız kadar değil. NaN'in farklı hesaplamalarda nasıl kullanılacağı IEEE 754 standardında iyi bir şekilde belgelenmiştir, bu nedenle tercümanınızın yazıldığı dilin ne olduğunu yapabilirsiniz.

Bu arada: Programcı olmayanlar tarafından kullanılabilen bir programlama dili oluşturmak, 1964'ten beri yapmaya çalıştığımız bir şeydir (Dartmouth BASIC). Şimdiye kadar başarısız olduk. Ama yine de iyi şanslar.


14
+1 teşekkürler. Beni bir hata atmaya ikna ettin ve şimdi cevabını okuduğumda neden tereddüt ettiğimi anlamıyorum. PHPbana kötü bir etkisi oldu.
Tepki

24
Evet, var. Sorunuzu okuduğumda, hemen yanlış çıktı üretmenin ve hatalar karşısında taşımayı sürdürmenin çok PHP-esque bir şey olduğunu düşündüm. PHP'nin bunu yapmasının istisna olmasının iyi nedenleri var.
Joel,

4
BASIC yorumu için +1. NaNYeni başlayan bir dilde kullanmanızı tavsiye etmiyorum , ancak genel olarak büyük cevap.
Ross Patterson

8
@Joel Yeterince uzun yaşadıysa, Dijkstra muhtemelen "[PHP] 'nin kullanımı zihni sakatlar; bu yüzden öğretimi bu nedenle bir suç olarak kabul edilmelidir" derdi.
Ross Patterson

12
@Ross. "bilgisayar biliminde kibir nano Dijkstras ölçülür" - Alan Kay

33

1 - Hatayı dikkate almayın ve 0sonuç olarak üretin . Mümkünse bir uyarı kaydı.

Bu iyi bir fikir değil. Hiç. İnsanlar buna bağlı olarak başlayacak ve bir daha düzeltmek zorunda kalırsanız çok fazla kod kıracaksınız.

2 - NaNRakamlar için olası bir değer olarak ekleyin , ancak bu NaN, dilin diğer alanlarındaki değerlerin nasıl ele alınacağı hakkında sorular ortaya çıkarır .

NaN'i diğer dillerin çalışma zamanlarının yaptığı gibi yapmalısınız: Başka bir hesaplama da NaN verir ve her karşılaştırma (NaN == NaN olsa bile) yanlış verir.

Bence bu kabul edilebilir, ama mutlaka yeni gelenler için uygun değil.

3 - Programın çalışmasını sonlandırın ve kullanıcıya ciddi bir hata oluştuğunu rapor edin.

Bu bence en iyi çözüm. Bu bilgiler eldeki kullanıcılar tarafından 0 ile başa çıkabilmelidir. Özellikle geceleri bir kez çalışacaksa bir test ortamı sağlamalısınız.

Dördüncü bir seçenek de var. Bölünmeyi üçlü bir işlem yapın. Bu ikisinden herhangi biri işe yarayacak:

  • div (pay, payda, alternative_result)
  • div (pay, payda, alternative_denumerator)

Yaptığınız Ama eğer NaN == NaNolmak false, o zaman eklemek gerekir isNaN()kullanıcılar tespit edebiliyoruz, böylece fonksiyonu NaNs.
AJMansfield

2
Ya o, ya da insanlar kendileri uygulamak: @AJMansfield: isNan(x) => x != x. Yine de, NaNprogramlama kodunuzda karşılaştığınızda, isNaNkontroller eklemeye başlamamalısınız , bunun yerine sebebini bulup gerekli kontrolleri yapmalısınız. Bu nedenle NaNtam olarak yayılması önemlidir .
back2dos

5
NaNbüyük ölçüde karşı sezgiseldir. Yeni başlayan bir dilde, varışta ölmüşlerdir.
Ross Patterson

2
@RossPatterson Ancak yeni başlayanlar kolayca söyleyebilir 1/0- onunla bir şeyler yapmalısın. InfVeya haricinde muhtemelen yararlı bir sonuç yoktur NaN- hatayı programa daha da ilerletecek bir şey. Aksi halde tek çözüm bu noktada bir hata ile durmaktır.
Mark Hurd,

1
Seçenek 4, beklenmeyen 0 bölenden kurtulmak için gerekli olan her şeyi gerçekleştirebilecek bir işlevin çağrılmasına izin verilerek iyileştirilebilir.
CyberFonic

21

Çalışan uygulamayı aşırı önyargılı şekilde sonlandırın. (Yeterli hata ayıklama bilgisi sağlarken)

Sonra, kullanıcılarınızı, bölenin sıfır olabileceği koşulları belirlemek ve ele almak için eğitin (kullanıcı tarafından girilen değerler vb.)


13

Haskell'de (ve Scala'da benzer), istisnalar atmak (veya boş referanslar döndürmek) yerine, sarıcı türleri Maybeve Eitherkullanılabilir. İle Maybekullanıcı o var değeri "boş" olup olmadığını test için bir şansı var, yoksa "unwrapping" varsayılan bir değer sağlayabilir. Eitherbenzer, ancak kullanılabilir olması durumunda sorunu açıklayan bir nesne (örneğin bir hata dizesi) döndürür.


1
Doğru, ancak Haskell'in bunu sıfıra bölmek için kullanmadığını unutmayın. Bunun yerine, her Haskell tipi örtük olarak olası bir değer olarak "dip" e sahiptir. Bu, sonlandırmayı başaramayan bir ifadenin "değeri" anlamına gelen boş işaretçilere benzemez. Kuşkusuzluğu bir değer olarak test edemezsiniz, ama operasyonel anlambilimde sonlandırılamayan durumlar bir ifadenin anlamının bir parçasıdır. Haskell'de, bu "alt" değer error "some message", değerlendirilen işlev gibi ek hata durumu sonuçlarını da işler .
Steve314

Şahsen, tüm programın iptal edilmesinin etkisi geçerli sayılırsa, saf kodun neden bir istisna atma etkisine sahip olamayacağını bilmiyorum, ama bu sadece benim - Haskellsaf ifadelerin istisnalar atmasına izin vermiyor.
Steve314

Bunun iyi bir fikir olduğunu düşünüyorum çünkü bir istisna atmak dışında, önerilen tüm seçenekler kullanıcılara hata yaptıklarını bildirmiyor. Temel fikir, kullanıcının programa vermiş olduğu değerle ilgili bir hata yapmasıdır, bu nedenle program kullanıcıya yanlış girdi verdiğini söylemelidir (daha sonra kullanıcı, düzeltmenin bir yolunu düşünebilir). Kullanıcılara hatalarından bahsetmeden herhangi bir çözüm çok garip geliyor.
InformedA,

Bence bu böyle gitmeli ... Rust programlama dili onu standart kütüphanesinde yoğun olarak kullanıyor.
aochagavia

12

Diğer cevaplar fikirlerin göreceli yararlarını zaten göz önüne almıştır. Değişken olmadığını belirlemek için temel akış kullanım analiz: Başka bir teklif olabilir sıfır. O zaman bölünmeyi, potansiyel olarak sıfır olan değişkenlere göre basitçe reddedebilirsiniz.

x = ...
y = ...

if y ≠ 0:
  return x / y    // In this block, y is known to be nonzero.
else:
  return x / y    // This, however, is a compile-time error.

Alternatif olarak, değişmezleri kuran akıllı bir assert işlevine sahip olun:

x = ...
require x ≠ 0, "Unexpected zero in calculation"
// For the remainder of this scope, x is known to be nonzero.

Bu, bir çalışma zamanı hatası atmak kadar iyidir; tanımsız işlemleri tamamıyla yitirirsiniz - ancak potansiyel yolun ortaya çıkması için kod yolunun bile vurulmasının gerekmediği avantajına sahiptir. Değişmeyenleri izlemek ve doğrulamak için programın tüm dallarını iç içe yazma ortamlarıyla değerlendirerek, sıradan yazım denetimi gibi yapılabilir:

x = ...           // env1 = { x :: int }
y = ...           // env2 = env1 + { y :: int }
if y ≠ 0:         // env3 = env2 + { y ≠ 0 }
  return x / y    // (/) :: (int, int ≠ 0) → int
else:             // env4 = env2 + { y = 0 }
  ...
...               // env5 = env2

Ayrıca, nulldilinizde böyle özellikler varsa, doğal olarak aralık ve denetleme uzanır .


4
Düzgün bir fikir, ancak bu tür bir kısıtlama çözme NP tamamlandı. Gibi bir şey düşünün def foo(a,b): return a / ord(sha1(b)[0]). Statik analizör SHA-1'i ters çeviremez. Clang bu tür statik analizlere sahiptir ve sığ böcekleri bulmak için harikadır ancak idare edemediği birçok durum vardır.
Mark E. Haase,

9
bu NP tamamlanmış değil, bu imkansız - diyor ki, lemma. Bununla birlikte, statik analizörün bunu çözmesi gerekmez, bunun gibi bir ifadeyi mahvedebilir ve açık bir iddia veya dekorasyon eklemenizi gerektirir.
MK01,

1
@ MK01: Başka bir deyişle, analiz “muhafazakar” dır.
Jon Purdy

11

Sayı 1 (hata ayıklanabilir sıfır ekleyin) her zaman hatalı. # 2 (NaN propagandası) ve # 3 (prosesi öldür) arasındaki seçim bağlama bağlıdır ve ideal olarak Numpy'deki gibi global bir ayar olmalıdır.

Büyük, bütünleşik bir hesaplama yapıyorsanız, NaN'i yaymak kötü bir fikirdir, çünkü sonunda tüm hesaplamanızı yayar ve bulaştırır --- sabah sonuçlarına baktığınızda ve hepsinin NaN olduğunu görünce, Sonuçlardan vazgeçip tekrar başlamalıyım. Program sona erdiyse daha iyi olurdu, gecenin ortasında bir arama yapıp en azından boşa harcanan saat sayısı açısından onu düzelttiniz.

Çok küçük, çoğunlukla bağımsız hesaplamalar yapıyorsanız (harita azaltma veya utanç verici şekilde paralel hesaplamalar gibi) ve NaN'ler nedeniyle kullanılamaz olma oranlarının bir kısmına tahammül edemezseniz, muhtemelen en iyi seçenek budur. Programı sonlandırmak ve hatalı biçimlendirilmiş ve sıfıra bölmek% 1 nedeniyle iyi ve faydalı olacak% 99 yapmamak bir hata olabilir.

NaN'lerle ilgili başka bir seçenek: aynı IEEE kayan nokta özelliği, Inf ve -Inf'i tanımlar ve bunlar, NaN'den farklı şekilde üretilir. Örneğin, Inf> 'ın herhangi bir sayıdan ve -Inf <herhangi bir sayıdan eminim, sıfıra bölüştürdüğünüzde, sıfırın küçük bir sayı olması gerektiğinden istediğiniz gibi olurdu. Girdileriniz yuvarlanırsa ve ölçüm hatasından muzdaripse (elle yapılan fiziksel ölçümler gibi), iki büyük miktarın farkı sıfırla sonuçlanabilir. Sıfıra bölme olmadan, çok fazla sayı almış olacaktınız ve belki de ne kadar büyük olduğu umrunda değil. Bu durumda, In ve -Inf, kusursuz biçimde geçerli sonuçlardır.

Resmi olarak da doğru olabilir --- sadece genişletilmiş gerçeklerde çalıştığınızı söyleyin.


Ancak, paydanın pozitif mi yoksa negatif mi olduğunu söyleyemeyiz, bu nedenle -inf istendiğinde bölme + inf ya da tam tersi sonuç verebilir.
Daniel Lubarov

Doğru, ölçüm hatanız + inf ile -inf arasındaki farkı ayırt etmek için çok küçük. Bu, en karmaşık uçağın tam olarak bir sonsuz noktaya (orijin tabanına zıt bir nokta) sahip olan bir topla eşlendiği Riemann küresine en çok benzemektedir. Çok büyük pozitif sayılar, çok büyük negatif sayılar ve hatta çok büyük hayali ve karmaşık sayılar bile bu sonsuz noktaya yakındır. Küçük bir ölçüm hatasıyla, onları ayırt edemezsiniz.
Jim Pivarski 15:13

Bu tür bir sistemde çalışıyorsanız, + inf ve -inf değerlerini eşdeğer olarak tanımlamanız gerekir, tıpkı +0 ve -0 değerlerini farklı ikili gösterimlere sahip olsalar bile, eşdeğer olarak tanımlamanız gerekir.
Jim Pivarski

8

3. Programın çalışmasını sonlandırın ve kullanıcıya ciddi bir hata oluştuğunu rapor edin.

[Bu seçenek] pratik değil…

Elbette pratiktir: Gerçekten mantıklı bir program yazmak programcıların sorumluluğundadır. 0'a bölünmek bir anlam ifade etmiyor. Bu nedenle, programcı bir bölüm gerçekleştiriyorsa, önceden bölenin 0'a eşit olmadığını doğrulamak da onun sorumluluğundadır. Programcı bu doğrulama kontrolünü yapamazsa, o zaman en kısa zamanda bu hatayı yapmalıdır. Mümkün ve denormalize (NaN) veya yanlış (0) hesaplama sonuçları bu konuda yardımcı olmaz.

Seçenek 3, en basit, dürüst ve matematiksel olarak doğru olanı olmak için size önerdiğim şeydi.


4

Hataların göz ardı edildiği bir ortamda önemli görevleri (örneğin; "gece cronu") yürütmek kötü bir fikir gibi görünüyor. Bunu bir özellik haline getirmek korkunç bir fikir. Bu seçenek 1 ve 2 seçeneklerini hariç tutar.

Seçenek 3, kabul edilebilir tek çözümdür. İstisnalar dilin bir parçası olmak zorunda değildir, ancak gerçekliğin bir parçasıdır. Fesih mesajınız, hata hakkında mümkün olduğunca spesifik ve bilgilendirici olmalıdır.


3

IEEE 754 aslında probleminiz için iyi tanımlanmış bir çözüme sahiptir. İstisnasız kullanım http://en.wikipedia.org/wiki/IEEE_floating_point#Exception_handling kullanmadanexceptions

1/0  = Inf
-1/0 = -Inf
0/0  = NaN

bu şekilde tüm operasyonlarınız matematiksel olarak mantıklı geliyor.

\ lim_ {x \ - 0} 1 / x = Inf

Bence IEEE 754'ü takip etmek en mantıklı olanıdır; çünkü hesaplamalarınızın bir bilgisayarda olacağı kadar doğru olmasını ve diğer programlama dillerinin davranışlarıyla da tutarlı olmanızı sağlar.

Ortaya çıkan tek sorun Inf ve NaN'in sonuçlarınızı kirleteceği ve kullanıcılarınızın sorunun nereden geldiğini tam olarak bilmeyecekleri. Julia gibi bir dile bir bakın ve bunu çok iyi yapın.

julia> 1/0
Inf

julia> -1/0
-Inf

julia> 0/0
NaN

julia> a = [1,1,1] ./ [2,1,0]
3-element Array{Float64,1}:
   0.5
   1.0
 Inf

julia> sum(a)
Inf

julia> a = [1,1,0] ./ [2,1,0]
3-element Array{Float64,1}:
   0.5
   1.0
 NaN

julia> sum(a)
NaN

Bölme hatası, matematiksel işlemlerle doğru bir şekilde yayılır, ancak kullanıcı hatanın hangi işlemden kaynaklandığını mutlaka bilmez.

edit:Cevabın ikinci bölümünü temelde yukarıda söylediğim şey olan Jim Pivarski'nin görmedim. Benim hatam.


2

Programlamacı olmayanlar tarafından en yaygın kullanılan dil olan SQL, neye mal olursa olsun, 3 numara yapar. Program yazarı olmayanların SQL yazmalarını gözlemleme ve onlara yardım etme deneyimlerime göre, bu davranış genellikle iyi anlaşılır ve kolayca telafi edilir (bir durum ifadesi veya benzeri ile). Aldığınız hata mesajının oldukça doğrudan olma eğiliminde olmasına yardımcı olur, örneğin Postgres 9'da "ERROR: zero by division" alırsınız.


2

Bence sorunun "acemi kullanıcıları hedef almasıdır. -> Öyleyse destek yok ..."

Neden istisna yönetiminin acemi kullanıcılar için sorunlu olduğunu düşünüyorsunuz?

Kötü olan nedir? "Zor" bir özelliğe mi sahip oldunuz ya da bir şeyin neden olduğunu bilmiyor musunuz? Daha fazla ne karıştırabilir? Çekirdek dökümü veya "Ölümcül hata: Böl, Sıfırla" ile olan bir çöküş?

Bunun yerine, BÜYÜK mesaj hatalarını hedeflemek için FAR'ın daha iyi olduğunu düşünüyorum. Bunun yerine yapın: "Kötü hesaplama bölün 0/0" (yani: Her zaman sorunu değil, sadece neden DATA göstermek tür sorun). PostgreSql'in mesaj hatalarını nasıl yaptığına bakın, bu harika IMHO'dur.

Ancak, aşağıdaki istisnalarla çalışmanın başka yollarını da inceleyebilirsiniz:

http://dlang.org/exception-safe.html

Ayrıca bir dil inşa etmeyi hayal ettim ve bu durumda normal / İstisnalarla İsteğe Bağlı / İsteğe Bağlı bir karışımı karıştırmanın en iyisini yapabileceğini düşünüyorum:

def openFile(fileName): File | Exception
    if not(File.Exist(fileName)):
        raise FileNotExist(fileName)
    else:
        return File.Open()

#This cause a exception:

theFile = openFile('not exist')

# But this, not:

theFile | err = openFile('not exist')

1

Benim görüşüme göre, diliniz hataları tespit etmek ve ele almak için genel bir mekanizma sağlamalıdır. Programlama hataları derleme zamanında (veya mümkün olduğunca erken) tespit edilmeli ve normalde programın sonlandırılmasına neden olmalıdır. Beklenmeyen veya hatalı verilerden veya beklenmeyen dış koşullardan kaynaklanan hatalar tespit edilmeli ve uygun eylem için uygun hale getirilmelidir, ancak programın mümkün olduğunda devam etmesine izin verilmelidir.

Muhtemel eylemler (a) sonlandırmak (b) kullanıcıdan bir işlem yapmasını istemek (c) hatayı günlüğe kaydetmek (d) düzeltilmiş bir değer yerine koymak (e) (f) kodunda test edilecek bir gösterge ayarlamak, bir hata işleme yordamını çağırmaktır. Bunlardan hangisini erişilebilir kılıyorsunuz ve hangi yollarla seçim yapmanız gerekiyor?

Tecrübelerime göre, hatalı dönüşümler, sıfıra bölme, taşma ve aralık dışı değer gibi yaygın veri hataları iyi huyludur ve varsayılan olarak farklı bir değer kullanılarak ve bir hata bayrağı ayarlayarak ele alınmalıdır. Bu dili kullanan (programlayıcı olmayan) hatalı verileri görecek ve hataları kontrol edip bunları kontrol etme ihtiyacını hızla anlayacaktır.

[Örneğin, bir Excel elektronik tablosu düşünün. Excel, elektronik tablolarınızı sonlandırmıyor, çünkü bir sayı taşmış ya da her neyse. Hücre tuhaf bir değer alır ve nedenini bulup düzeltmeye devam edersiniz.]

Bu yüzden sorunuzu cevaplamak için: kesinlikle sonlandırmamalısınız. NaN'nin yerine geçebilir ancak bunu görünür kılmamalısınız, sadece hesaplamanın tamamlandığından ve tuhaf bir değer ürettiğinden emin olmalısınız. Ve bir hata bayrağını ayarlayın, böylece ihtiyacı olan kullanıcılar bir hatanın meydana geldiğini belirleyebilirler.

Açıklama: Ben sadece böyle bir dil uygulaması (Powerflex) yarattım ve 1980'lerde tam olarak bu sorunu (ve diğerlerini) ele aldım. Programcı olmayanlar için son 20 yılda diller üzerinde çok az ilerleme kaydedildi veya hiç ilerleme kaydedilmedi ve denemek için çok fazla eleştiri çekeceksin, ama gerçekten başarılı olmanı umuyorum.


1

Payda 0 olduğunda alternatif bir değer verdiğiniz üçlü operatöre bayıldım.

Görmedim bir fikir daha genel bir "geçersiz" değer üretmektir. Genel olarak "bu değişken bir değere sahip değildir çünkü program kötü bir şey yaptı", bu da kendisiyle birlikte tam bir yığın izi taşıyor. Ardından, bu değeri herhangi bir yerde kullanırsanız, sonuç tekrar geçersiz olur; yeni işlem en üstte denenmiştir (yani, geçersiz değer bir ifadede görünürse, ifadenin tamamı geçersiz olur ve hiçbir işlev çağrısı yapılmaz; boolean operatörleri olun - doğru veya geçersiz doğru ve yanlış ve geçersiz yanlıştır - bunun başka istisnaları da olabilir). Bu değer artık hiçbir yerde referans alınmadığında, her şeyin yanlış olduğu zincirin tümünün uzun ve güzel bir tanımını girersiniz ve her zamanki gibi çalışmaya devam edersiniz. Belki de izini projenin liderine veya başkalarına gönder.

Temelde belki monad gibi bir şey. Aynı zamanda başarısız olabilecek başka bir şeyle çalışacaktır ve insanların kendi geçersizliklerini inşa etmelerine izin verebilirsiniz. Ve hata çok derin olmadığı sürece programın çalışmaya devam edeceğini düşünüyorum.


1

Sıfırla bölmenin iki temel nedeni vardır.

  1. Kesin bir modelde (tamsayılar gibi), giriş yanlış olduğu için sıfır DBZ ile bölme elde edersiniz. Bu, çoğumuzun düşündüğü DBZ türüdür.
  2. Kesin olmayan modelde (kayan nokta gibi), giriş geçerli olsa bile yuvarlama hatası nedeniyle bir DBZ alabilirsiniz. Normalde düşünmediğimiz şey budur.

1. için, kullanıcılara bir hata yaptıklarını bildirmelisiniz, çünkü sorumlu olan onlar ve durumun nasıl çözüleceğini en iyi bilenler onlar.

2 için. Bu kullanıcı hatası değildir, algoritmayı, donanım uygulamasını vb. Gösterebilir, ancak bu kullanıcının hatası değildir, bu nedenle programı sonlandırmamalısınız, hatta istisna alamazsınız (eğer bu durumda değilse). Bu yüzden makul bir çözüm operasyonlara makul bir şekilde devam etmektir.

Bu soruyu soran kişinin durum 1'i sorduğunu görebiliyorum. Dolayısıyla, kullanıcıyla tekrar iletişim kurmanız gerekiyor. Hangi kayar nokta standardı kullanıyorsanız, Inf, -Inf, Nan, IEEE bu duruma uymaz. Temelde yanlış strateji.


0

Dilde izin verme. Başka bir deyişle, ilk önce test ederek, kesinlikle sıfır olmayana kadar bir sayıya bölünmeye izin vermeyin. Yani.

int div = random(0,100);
int b = 10000 / div; // Error E0000: div might be zero

Bunu yapmak için bir tamsayı yerine, yeni bir sayısal türe, doğal bir numaraya ihtiyacınız vardır. Başa çıkması zor ... zor olabilir.
Servi

@Servy: Hayır, yapmazsın. Neden sen Olası değerleri belirlemek için derleyicide mantığa ihtiyacınız var, ancak yine de bunu (nedenlerini optimize etmek için) istiyorsunuz.
MSalters

Farklı bir türünüz yoksa, biri sıfır için diğeri sıfır olmayan değerler için ise, sorunu genel durumda çözemezsiniz. Ya yanlış pozitiflere sahip olursunuz ve kullanıcıyı sıfır yoldan gerçekte olduğundan daha sık kontrol etmeye zorlarsınız ya da hala sıfıra bölebilecekleri durumlar yaratırsınız.
Servi

@ Hizmet: Hatalısın: bir derleyici böyle bir türe ihtiyaç duymadan bu durumu izleyebilir ve örneğin GCC zaten böyle yapar. Örneğin, C tipi intsıfır değerlerine izin verir, ancak GCC hala belirli kodların nerede sıfır olamayacağını belirleyebilir.
MSalters

2
Ancak sadece bazı durumlarda; her durumda% 100 doğrulukla bunu yapamaz. Ya yanlış pozitiflere ya da yanlış negatiflere sahip olacaksınız. Bu kesinlikle doğru. Örneğin, tamamlayabilecek ya da tamamlamayabilecek bir kod pasajı oluşturabilirim . Derleyici bittiyse bile bilemezse, sonuçta elde edilen int'in sıfır olmadığını nasıl bilebilir? Basit ve basit vakaları yakalayabiliyor, ancak tüm vakaları yakalayamıyor .
Servi

0

Bir programlama dili yazarken, gerçeğin avantajından yararlanmalı ve sıfır durum için cihaz için bir eylem eklemeyi zorunlu hale getirmelisiniz. a <= n / c: 0 div-by-action

Az önce önerdiğim şeyin, esas olarak PL'nize bir 'goto' eklemek olduğunu biliyorum.

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.