Okumak, ECMAScript 5.1 tarifnamede , +0
ve-0
ayırt edilir.
Öyleyse neden +0 === -0
değerlendiriyor true
?
Object.is
+0 ve -0'ı ayırt etmek için kullanabileceğinizi unutmayın
Okumak, ECMAScript 5.1 tarifnamede , +0
ve-0
ayırt edilir.
Öyleyse neden +0 === -0
değerlendiriyor true
?
Object.is
+0 ve -0'ı ayırt etmek için kullanabileceğinizi unutmayın
Yanıtlar:
JavaScript sayıları göstermek için IEEE 754 standardını kullanır . Gönderen Vikipedi :
İşaretli sıfır , ilişkili bir işaretle sıfırdır. Sıradan aritmetikte, −0 = +0 = 0. Ancak, hesaplamada, bazı sayı gösterimleri, genellikle −0 (negatif sıfır) ve +0 (pozitif sıfır) ile gösterilen iki sıfırın varlığına izin verir . Bu, tamsayılar için bazı imzalı sayı gösterimlerinde ve çoğu kayan nokta sayısı gösterimlerinde oluşur. 0 sayısı genellikle +0 olarak kodlanır, ancak +0 veya −0 ile temsil edilebilir.
Kayan noktalı aritmetik için IEEE 754 standardı (şu anda kayan noktalı sayıları destekleyen çoğu bilgisayar ve programlama dili tarafından kullanılmaktadır) hem +0 hem de −0 gerektirir. Sıfırlar, 1 / −0 = −∞ ve 1 / + 0 = + ∞ olacak şekilde uzatılmış gerçek sayı çizgisinin bir varyantı olarak düşünülebilir, sıfıra bölme yalnızca ± 0 / ± 0 ve ± ∞ / ± ∞ için tanımlanmamıştır .
Makale, farklı temsiller hakkında daha fazla bilgi içermektedir.
Bu nedenle, teknik olarak, her iki sıfırın da ayırt edilmesi gerekir.
Ancak,
+0 === -0
doğru olarak değerlendirir. Neden (...) ?
Bu davranış, açık bir şekilde tanımlanır bölüm 11.9.6 , Katı Eşitlik karşılaştırma algoritması (ağırlık kısmı benim):
Değerler
x === y
neredex
vey
olduğunda karşılaştırma doğru veya yanlış üretir . Böyle bir karşılaştırma aşağıdaki gibi yapılır:(...)
Tür (x) Sayı ise, o zaman
- X NaN ise false değerini döndürün.
- Y NaN ise false değerini döndürün.
- X, y ile aynı Sayı değeriyse, true değerini döndürün.
- X +0 ve y -0 ise true değerini döndürün.
- X −0 ve y +0 ise true değerini döndürün.
- Yanlış döndür.
(...)
(Aynı şey +0 == -0
btw için de geçerlidir .)
Mantıksal +0
ve -0
eşit olarak muamele etmek gibi görünüyor . Aksi takdirde bunu kodumuzda dikkate almak zorunda kalacağız ve ben şahsen bunu yapmak istemiyorum;)
Not:
ES2015 yeni bir karşılaştırma yöntemi sunar Object.is
. ve Object.is
arasında açıkça ayrım yapar :-0
+0
Object.is(-0, +0); // false
1/0 === Infinity; // true
ve 1/-0 === -Infinity; // true
.
1 === 1
ve +0 === -0
ancak 1/+0 !== 1/-0
. Ne kadar tuhaf!
+0 !== -0
;) Bu gerçekten sorun yaratabilir.
0 !== +0
/ 0 !== -0
, gerçekten de sorun yaratacaktır!
@ User113716 adlı kullanıcının yorumunu göz ardı ettiğim için bunu yanıt olarak ekleyeceğim.
Bunu yaparak -0 için test yapabilirsiniz:
function isMinusZero(value) {
return 1/value === -Infinity;
}
isMinusZero(0); // false
isMinusZero(-0); // true
e±308
numaranız sadece denormalize formda temsil edilebilir ve farklı uygulamalar, onları destekleyecekleri veya destekleyecekleri konusunda farklı görüşlere sahiptir. Buradaki nokta, bazı kayan nokta modlarındaki bazı makinelerde -0
sayınızın denormalize sayı olarak ve diğerlerinde sayınızdır 0.000000000000001e-308
. Bu tür yüzer, çok eğlenceli
+0 ve -0'ın gerçekten çok farklı davrandığı bir örnekle karşılaştım:
Math.atan2(0, 0); //returns 0
Math.atan2(0, -0); //returns Pi
Dikkatli olun: Math.round'u -0.0001 gibi negatif bir sayı üzerinde kullanırken bile, aslında -0 olacaktır ve yukarıda gösterildiği gibi sonraki hesaplamaları bozabilir.
Bunu düzeltmenin hızlı ve kirli yolu, aşağıdaki gibi davranmaktır:
if (x==0) x=0;
ya da sadece:
x+=0;
Bu, -0 olması durumunda sayıyı +0'a dönüştürür.
In IEEE 754 standardına JavaScript sayısı türü temsil etmek için kullanılır, gösterge bir bit ile temsil edilmektedir (a, 1, negatif bir sayı gösterir).
Sonuç olarak, her bir temsil edilebilir sayı için hem negatif hem de pozitif bir değer vardır; 0
.
Bu yüzden hem -0
ve +0
sağlıklı olur.
Orijinal başlığın cevaplanması Are +0 and -0 the same?
:
brainslugs83
(yanıtın yorumlarında Spudley
) JS'de +0 ve -0'ın aynı olmadığı ve işlev olarak uygulandığı önemli bir duruma dikkat çekti:
var sign = function(x) {
return 1 / x === 1 / Math.abs(x);
}
Bu standart dışında Math.sign
+0 ve -0 doğru işaretlerini döndürür.
0 için iki olası değer vardır (bit gösterimleri). Bu benzersiz değildir. Özellikle kayan nokta sayılarında bu meydana gelebilir. Çünkü kayan nokta sayıları aslında bir tür formül olarak saklanır.
Tamsayılar ayrı şekillerde de saklanabilir. Ek işaret bitine sahip sayısal bir değere sahip olabilirsiniz, bu nedenle 16 bit alanda 15 bit tam sayı değeri ve işaret biti depolayabilirsiniz. Bu gösterimde, 1000 (hex) ve 0000 değerlerinin her ikisi de 0'dır, ancak bunlardan biri +0 ve diğeri -0'dır.
-1 ile -2 ^ 16 arasında değişen tam sayı değerinden 1 çıkarılarak bu önlenebilir, ancak bu rahatsız edici olacaktır.
Daha yaygın bir yaklaşım, tam sayıları 'iki tamamlayıcıda' saklamaktır, ancak görünüşe göre ECMAscript yapmamayı seçmiştir. Bu yöntemde sayılar 0000 ila 7FFF pozitif arasında değişmektedir. Negatif sayılar FFFF (-1) ile 8000 arasında başlar.
Tabii ki, aynı kurallar daha büyük tamsayılar için de geçerlidir, ancak F'nin yıpranmasını istemiyorum. ;)
+0 === -0
biraz garip bulmuyorsun . Çünkü şimdi var 1 === 1
ve +0 === -0
ama 1/+0 !== 1/-0
...
+0 === -0
İki bit gösteriminin farklı olmasına rağmen nedenini açıklamıyorsunuz .
Sıkı Eşitlik Karşılaştırma yöntemini ('===') suçluyorum. Bölüm 4d'ye bakın
bakınız 7.2.13 Sıkı Eşitlik Karşılaştırma üzerinde şartname
Wikipedia'nın bu fenomeni açıklamak için iyi bir makalesi var: http://en.wikipedia.org/wiki/Signed_zero
Kısacası, hem +0 hem de -0, IEEE kayan nokta özelliklerinde tanımlanmıştır. Her ikisi de teknik olarak bir tamsayı olmayan bir işaret olmadan 0'dan farklıdır, ancak pratikte hepsi sıfıra değerlendirir, bu nedenle ayrım tüm pratik amaçlar için göz ardı edilebilir.