Negatif sıfır neden önemlidir?


64

Neden olumlu ve olumsuz sıfır için farklı temsillere önem verdiğimizi kafam karıştı.

Negatif bir sıfır temsiline sahip olmanın karmaşık sayıları içeren programlamada son derece önemli olduğunu okumak için belirsizce hatırlıyorum. Karmaşık sayıları içeren bir kod yazma fırsatım olmadı, bu yüzden neden böyle olacağı konusunda biraz şaşırdım.

Wikipedia'nın bu konudaki makalesi özellikle yararlı değil; doğru anladıysam, sadece işaretli sıfır ile ilgili belirsiz iddialarda bulunur; Bu cevap , farklı davranış gösteren birkaç işlevi listeler ve nasıl kullanılacağına aşina iseniz, örneklerden bir şey çıkarılabilir. (Her ne kadar karmaşık kareköklerin belirli bir örneği yanlış görünüyor, iki sayı matematiksel olarak eşdeğer olduğundan, yanlış anlamadığım sürece.) Ama orada olmasaydı ne tür bir sorun yaşayacağına dair net bir açıklama bulamadım. Daha matematiksel kaynaklar, ikisini matematiksel bir perspektiften ayırt etmenin mümkün olmadığını belirttiğimi ve Wikipedia makalesinin bunun sınırları tanımlamanın dışında bir hesaplama yapmanın dışında nadiren bulunduğunu öne sürdüğü görülüyor.

Öyleyse bilgisayardaki negatif sıfır neden önemlidir? Eminim bir şeyleri özlüyorumdur.


6
Negatif sıfır, bir IEEE kayan nokta sayısında taşma sinyalini verebilir, ancak bunun ötesinde kullanımı tartışmalı ve belirsiz görünüyor. Tahmin edersem, negatif sıfırın IEEE kayan noktada temsil edildiğini söyleyebilirim çünkü ... yapabilirsin. Daha da ilginç bir sürüş için, kayan nokta sinyali olan NaN hakkındaki bilgilere bakın.
Robert Harvey,

1
Belirli bir örnek "1 / 0.0" / "1 / -0.0" ise, 0, 1 / x için kesilmiş daldır ve sınır, aşağıdan veya yukarıdan yaklaşmanıza bağlı olarak değişir.
Vatine

@Vatine Hayır, belirli bir örnek sqrt(-1+0i) = ive sqrt(-1-0i) = -ibazı programlama dilleri için uygun bir sözdizimi ile giyinmiş olmasına rağmen, inanıyorum. Daha net olmak için düzenleme yapacağım.
jpmc26


Cevaplarda karmaşık rakamların hiç ortaya çıkmamasına gerçekten şaşırdım, özellikle de belirttiğim karekök örneği verildiğinde.
jpmc26

Yanıtlar:


69

FPU aritmetikte 0'ın mutlaka sıfır anlamına gelmesi gerekmediğini, ancak verilen veri türü kullanılarak gösterilemeyecek kadar küçük bir değere sahip olduğunu unutmamanız gerekir.

a = -1 / 1000000000000000000.0

a, float (32 bit) ile doğru şekilde temsil edilemeyecek kadar küçüktür, bu nedenle -0'a yuvarlanır.

Şimdi, hesaplamamızın devam ettiğini söyleyelim:

b = 1 / a

A float olduğundan, -1000000000000000000.0.0'ın doğru yanıtından oldukça uzakta olan -in sonsuzluğuna neden olur.

Şimdi -0 yoksa b'yi hesaplayalım (yani a +0'a yuvarlanır):

b = 1 / +0
b = +infinity

Sonuç, yuvarlama nedeniyle tekrar yanlıştır, ancak şimdi "daha yanlış" dır - yalnızca sayısal olarak değil, daha da önemlisi farklı işaretlerden dolayı (hesaplama sonucu + sonsuzdur, doğru sonuç -1000000000000000000.0'dır).

Yine de her ikisinin de yanlış olduğu gibi önemli olmadığını söyleyebilirsin. Önemli olan, hesaplamanın en önemli sonucunun işaret olduğu çok sayıda sayısal uygulama olmasıdır - örneğin, bazı makine öğrenme algoritmasını kullanarak kavşakta sola mı sağa mı dönmeye karar verirken, pozitif değeri => dönüş şeklinde yorumlayabilirsiniz. sol, negatif değer => sağa dönün, değerin gerçek "büyüklüğü" sadece "güven katsayısı" dır.


Akıntı işaretinin hayali / karmaşık sayı hesaplamalarında özellikle önemli olup olmadığı hakkında bir fikriniz var mı?
jpmc26

@qbd: Bu sayısal uygulamaların ne olduğunu biliyor musunuz? Tetikleyen ve kullanan +infve -infnormal çalışmadaki programların tıkalı olduğunu söyleyebilirim .
Björn Lindqvist

@ BjörnLindqvist Eğer somut, indirilebilir uygulamalar istiyorsanız - hiçbir zaman bilmiyorum. Ben mutlaka buggy - sanırım float / double yerine sınırsız hassasiyetle BigDecimal gibi bir şey kullanabilirsiniz. Ancak, programın şamandıra / çift olanla aynı sonuçların elde edilebileceği, ancak daha kötü bir performans göstereceği zaman buna değer mi?
qbd

Bunu ben inanamıyorum "hesaplama en önemli sonuç işaretidir sayısal uygulamalar" yazdı ama -0 üzerinde ve değerler olmak itimat herhangi iyi yazılmış uygulamalar vardır inanamıyorum +infve -inf. Programınız kayan nokta akışına neden oluyorsa, bu bir hatadır ve daha sonra ne olacağı çok ilginç değildir, imho. Hala -0'ın kullanışlı olduğu pratik örnekleri hala kaçırıyoruz.
Björn Lindqvist

1
@ BjörnLindqvist x265'in büyük kısmı, performans adına çok az kişinin bildiği karanlık detaylarına (CPU mimarisine bağlı olan) dayanarak montajda yapılır. Yanlış mı? Yaygın olarak uygulanan 30 yıllık standartlara (kalmak için burada) güvenmek, performans adına basit, iyi anlaşılan bir özellik için aniden o kadar da kötü görünmüyor.
qbd

8

İlk önce, nasıl -0 oluşturabilirsin? İki yol vardır: (1) matematiksel sonucun negatif olduğu, fakat sıfıra o kadar yakın olan ve sıfır olmayan bir sayıya yuvarlanacak kayan nokta işlemi yapar. Bu hesaplama -0 verecek. (b) Sıfır içeren belirli işlemler: Pozitif sıfırı negatif bir sayıyla çarpın veya pozitif sıfırı negatif bir sayıya bölün veya pozitif sıfırı azaltın.

Negatif bir sıfıra sahip olmak çarpmayı ve bölmeyi biraz kolaylaştırır, x * y veya x / y işareti her zaman x, özel veya y işaretidir. Negatif sıfır olmadan, -0 yerine +0 olan bir miktar ekstra kontrol yapılmalıdır.

Yararlı olduğu bazı çok nadir durumlar vardır. Bir çarpma ya da bölmenin sonucunun, bir akış olsa bile (sonucun matematiksel bir sıfır olmadığını bildiğiniz sürece) matematiksel olarak sıfırdan büyük ya da küçük olup olmadığını kontrol edebilirsiniz. Fark yaratan hiçbir yerde yazılı kod olduğunu asla hatırlayamıyorum.

Derleyicileri optimize etmek -0. Örneğin, x + 0.0'ı x ile değiştiremezsiniz çünkü x, -0.0 ise sonuç x olmamalıdır. X * 0.0'ı 0.0 ile değiştiremezsiniz çünkü x-0 veya x -0.0 ise sonuç -0.0 olmalıdır.


7
IEEE-754'ün dört sıfır içermesini dilerim: "kesin", pozitif sonsuz küçük, negatif sonsuz küçük ve işaretsiz (ikincisi ayırt edilemez değerler arasındaki farktır). Bunu yapmak, çok fazla kayan noktalı aksiyomun çalışmasını sağlardı - bunların arasında, x + 0.0 eşdeğer x-0.0 eşdeğer x, xy eşdeğer x + (- 1.0) * y ve 1.0 / x eşdeğer -1.0 / (- 1.0 * x) [eğer x pozitif sıfırsa, her ikisi de infüzyon olur; neg-zero ise, her ikisi de neg-inf; Kesin veya imzasız, her ikisi de NaN].
supercat

Ben geçirerek olumsuz sıfır elde edebildi -5ve 5içine fmod(). Kullanım davam için oldukça can sıkıcı.
Aaron Franke

6

IEEE 754 ile uyumlu C # Çifti

    double a = 3.0;
    double b = 0.0;
    double c = -0.0;

    Console.WriteLine(a / b);
    Console.WriteLine(a / c);

baskılar:

Infinity
-Infinity

Aslında biraz açıklamak için ...

Double d = -0.0; 

Bu, d = The Limit of x as x approaches 0-veya öğesine çok daha yakın bir şey anlamına gelir The Limit of x as x approaches 0 from the negatives.


Philipp'in yorumuna ...

Temel olarak negatif sıfır, akıntı anlamına gelir.

Olumsuz sıfır için çok az pratik kullanım var, eğer varsa ...

örneğin, bu kod (tekrar C #):

double a = -0.0;
double b = 0.0;

Console.WriteLine(a.Equals(b));
Console.WriteLine(a==b);
Console.WriteLine(Math.Sign(a));

bu sonucu verir:

True
True
0

Gayri resmi açıklamak gerekirse, bir IEEE 754 kayan noktaya sahip olabileceği tüm özel değerler (pozitif sonsuzluk, negatif sonsuzluk, NAN, -0.0) pratik anlamda bir anlamı yoktur. Herhangi bir fiziksel değeri veya "gerçek dünya" hesaplamasında anlamlı olan herhangi bir değeri temsil edemezler. Demek istedikleri temelde bu:

  • pozitif sonsuzluk, pozitif uçta kayan bir noktanın temsil edebileceği bir taşma anlamına gelir
  • negatif sonsuzluk, bir yüzen noktanın temsil edebileceği pozitif uçta bir taşma anlamına gelir
  • Negatif sıfır bir alçak anlamına gelir ve işlenenler zıt işaretlere sahip
  • pozitif sıfır , bir alt akış anlamına gelebilir ve işlenenler aynı işarete sahipti
  • NAN, hesaplamanızın açık bir şekilde tanımsız olduğu, sqrt(-7)olduğu gibi 0/0veya benzeri veya benzeri bir sınırı olmadığı anlamına gelirPositiveInfinity/PositiveInfinity

7
Evet, ama bu neden önemlidir? Farkın önemli olduğu pratik, gerçek dünyaya örnek verebilir misiniz?
Philipp

5

Bunun, karmaşık sayı hesaplamaları ile nasıl ilişkili olduğu sorusu, hem +0 hem de -0'ın kayan nokta içinde olmasının nedeninin tam kalbinde yer alıyor. Karmaşık Analiz'i hiç incelerseniz, çıktıdan 'Riemann yüzeyi' olarak bilinen şeyi oluşturan 'kibar kurgu' benimsemediği sürece, Karmaşıktan Karmaşa'ya sürekli işlevlerin genellikle 'tek değerli' olarak değerlendirilemediğini hızlı bir şekilde keşfedersiniz. Örneğin, karmaşık logaritma her girişe sonsuz sayıda çıkış atar; Sürekli bir çıktı oluşturmak için 'bağladığınızda', köken çevresinde 'sonsuz bir tirbuşon' yüzeyi oluşturan tüm gerçek parçalarla sonuçlanırsınız. 'Eksensel-hayali tarafından aşağıya doğru' gerçek ekseni geçen ve 'direğin etrafına dolanıp' gerçek ekseni geçen 'bir diğer eğriyi geçen kesintisiz bir eğri

Şimdi bunu karmaşık kayan nokta kullanarak hesaplayan sayısal bir programa uygulayın. Belirli bir hesaplamadan sonra gerçekleştirilen işlem, programın şu anda hangi 'sayfasını' açtığına bağlı olarak çok farklı olabilir ve son hesaplanan sonucun işareti muhtemelen size hangi 'sayfanın' olduğunu gösterir. Şimdi bu sonucun sıfır olduğunu varsayalım. Unutmayın, burada 'sıfır' gerçekten 'doğru temsil etmek için çok küçük' demektir. Ancak eğer hesaplama sıfır olduğunda, hesaplama işareti (- işaretini koruyacak şekilde) (yani hangi 'levhayı' hatırlayacağını) düzenleyebilirse, kod bu durumda bile işareti kontrol edebilir ve doğru işlemi yapabilir.


1

Sebep normalden daha basittir

Tabii ki gerçekten güzel görünen ve yararlı olan birçok kesmek var (onlar yuvarlama -0.0ya da +0.0ama başlangıçta eksi / artı işareti ile imzalı bir int gösterdiğimizi varsayalım (bunun U2 ikili koduyla çözüldüğünü biliyorum) tamsayılarda genellikle ancak çiftin daha az karmaşık bir gösterimini varsayarsak:

0 111 = 7
^ sign

Ya negatif numara varsa?

1 111 = -7

Tamam, bu kadar basit. Öyleyse 0'ı temsil edelim:

0 000 = 0

Bu da iyi. Peki ya 1 000? Yasak bir numara olmak zorunda mı? Daha iyisi hayır.

Öyleyse, iki sıfır türü olduğunu varsayalım:

0 000 = +0
1 000 = -0

Peki, bu bizim hesaplamaları basitleştirmek ve tabii ki biraz yuvarlama ek özellikler verecektir. Böylece +0ve -0sadece ikili temsil sorunlarından geliyorlar.


6
Bunu doğru okuyorsam, aslında sadece standartları tanımlayan veya uygulayan kişilerin bunu yasaklamak sorununa gitmek istemediklerini söylüyorsunuz. Bu mantığın, 2'nin tamamlayıcısının tamamen farklı bir sayı için "negatif sıfır" gösterimini kullandığı ve negatif sıfır gösterimi olmadığı gerçeğine dayandığını sanmıyorum. Bağlandığım Wikipedia makalesine bakın.
jpmc26

1
@ jpmc26 Bunun aslında bazı gerçekleri olduğunu düşünüyorum, yasaklamamak, uygulamaların özel bir durumda olmasını gerektirmemek anlamına geliyor. Olduğu gibi, her sayının bir işaret biti vardır ve işaret biti değiştirilerek ihmal edilebilir. NaN'ler bile imzalanır ve uygulamalar bir NaN üretilirken uygun bir işaret seçebilir (ancak zorunlu değildir). Negatif sıfır olmasaydı, 0 sonuçlandı her hesaplama işareti biraz düzeltmek için ekstra işler yapmak, vb gerekir
Hobbs

4
@ jpmc26 (iki sayının diğer çarpımlarında, sonucun işareti çarpım işaretlerinin xoru ve büyüklüğü iki büyüklüğün çarpımıdır. Gerçek hayatta bu -1 * 0 = - . işaret biti çevrilmiş sıfır bazı özel sıfırdan farklı bir değer, kontrol edin ve yanlışlıkla o özel değeri üretmez emin olmak gerekir 0 üretebilir her ürün olsaydı) 0. Ama
hobbs
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.