Bugün bir online oyun fizik kütüphanesine bakıyordum ve ~~ operatörüne rastladım. Ben tek bir ~ bitsel değil DEĞİL biliyorum, bu ~~ bir DEĞİL DEĞİL, aynı değeri geri verecek bir DEĞİL, değil mi?
Bugün bir online oyun fizik kütüphanesine bakıyordum ve ~~ operatörüne rastladım. Ben tek bir ~ bitsel değil DEĞİL biliyorum, bu ~~ bir DEĞİL DEĞİL, aynı değeri geri verecek bir DEĞİL, değil mi?
Yanıtlar:
Ondalık noktadan sonraki her şeyi kaldırır, çünkü bitsel işleçler işlenenlerini örtük olarak işaretli 32 bit tamsayılara dönüştürür. Bu, işlenenlerin (kayan nokta) sayı mı yoksa dizgi mi olduğu ve sonuç bir sayı mı olduğu ile çalışır.
Başka bir deyişle, şunu verir:
function(x) {
if(x < 0) return Math.ceil(x);
else return Math.floor(x);
}
yalnızca x - (2 31 ) ve 2 31 - 1 arasındaysa. Aksi takdirde taşma meydana gelir ve sayı "etrafına sarılır".
Bu, bir işlevin dize bağımsız değişkenini bir sayıya dönüştürmek için yararlı kabul edilebilir, ancak her ikisi de taşma olasılığı ve tamsayı olmayanlarla kullanım için yanlış olduğundan, "kod golf" ( yani okunabilirlik ve sağlamlık pahasına programınızın kaynak kodunu gereksiz yere kırpmak). Ben kullanacağı +x
veya Number(x)
onun yerine.
Örneğin, -43.2 sayısı:
-43,2 10 = 11111111111111111111111111010101 2
imzalı (ikisinin tamamlayıcısı) 32 bit ikili sayı olarak. (JavaScript ondalık noktadan sonra olanları yok sayar.) Bitleri ters çevirmek şunları sağlar:
-43 10 DEĞİL = 00000000000000000000000000101010 2 = 42 10
Tekrar tersine çevirme:
NOT 42 10 = 11111111111111111111111111010101 2 = -43 10
Bu Math.floor(-43.2)
, negatif sayıların ondan uzakta değil, sıfıra yuvarlanması bakımından farklılık gösterir . (Sayının pozitif veya negatif olmasına bakılmaksızın, -44'e eşit olan zemin işlevi her zaman bir sonraki düşük tamsayıya yuvarlar.)
~~
Demek ki, kısmi bir işlev oluşturmak için kısa bir yol (ve muhtemelen iyi bir çözüm?) , Ancak açık bir şekilde javascript .
~~
.
İlk operatör, işleneni bir tamsayıya zorlar (muhtemelen değeri bir dizeye veya boole değerine zorladıktan sonra), ardından en düşük 31 biti tersine çevirir. Resmi olarak ECMAScript sayılarının hepsi kayan noktalı, ancak bazı sayılar SpiderMonkey motorunda 31 bit tamsayı olarak uygulanır.
1 elemanlı bir diziyi bir tamsayıya dönüştürmek için kullanabilirsiniz. Kayan noktalar C kuralına göre dönüştürülür, yani. kesirli kısmın kesilmesi.
İkinci operatör daha sonra bitleri tersine çevirir, böylece bir tamsayı elde edeceğinizi bilirsiniz. Bu, koşul ifadesinde boole değerine zorlamakla aynı şey değildir, çünkü boş bir nesne {} doğru olarak değerlendirirken ~~ {} yanlış olarak değerlendirir.
js>~~"yes"
0
js>~~3
3
js>~~"yes"
0
js>~~false
0
js>~~""
0
js>~~true
1
js>~~"3"
3
js>~~{}
0
js>~~{a:2}
0
js>~~[2]
2
js>~~[2,3]
0
js>~~{toString: function() {return 4}}
4
js>~~NaN
0
js>~~[4.5]
4
js>~~5.6
5
js>~~-5.6
-5
~~undefined // 0
~~null // 0
~
, ilk yaptığınız ~
şeyi yapar ve tersi de geçerlidir. ~
Operatör bir tekli operatörler ve sağdan sola doğru interpereted edilir ~~X
gibidir ~(~X)
değil gibi (~~)X
(ki bir yazım hatası olacaktır)
ECMAScript'te 6'da, eşdeğer ~~
olan Math.trunc :
Herhangi bir kesirli basamağı kaldırarak sayının integral bölümünü döndürür. Herhangi bir sayıyı yuvarlamaz.
Math.trunc(13.37) // 13
Math.trunc(42.84) // 42
Math.trunc(0.123) // 0
Math.trunc(-0.123) // -0
Math.trunc("-1.123")// -1
Math.trunc(NaN) // NaN
Math.trunc("foo") // NaN
Math.trunc() // NaN
Çok dolgu:
function trunc(x) {
return x < 0 ? Math.ceil(x) : Math.floor(x);
}
~
Yapmak gibi görünüyor -(N+1)
. Yani ~2 == -(2 + 1) == -3
-3 üzerinde tekrar yaparsanız, geri döndürür: ~-3 == -(-3 + 1) == 2
Muhtemelen bir stringi bir raunta çevirir.
Bu konuya bakın: http://www.sitepoint.com/forums/showthread.php?t=663275
Ayrıca, daha ayrıntılı bilgiye buradan ulaşabilirsiniz: http://dreaminginjavascript.wordpress.com/2008/07/04/28/
Verilen ~N
is -(N+1)
, ~~N
daha sonra -(-(N+1) + 1)
. Bu, açıkça, temiz bir numaraya yol açar .
Sadece bir uyarı. Buradaki diğer cevaplar beni biraz belaya soktu.
Amaç, kayan nokta sayısının ondalık noktasından sonra herhangi bir şeyi kaldırmaktır, ancak hata tehlikesi haline getiren bazı köşe vakaları vardır. Kaçınmayı tavsiye ederim ~~.
İlk olarak, ~~ çok büyük sayılar üzerinde çalışmaz.
~~1000000000000 == -727279968
Alternatif olarak, kullanın Math.trunc()
(Gajus'un belirttiği gibi, Math.trunc()
bir kayan nokta sayısının tamsayı kısmını döndürür, ancak yalnızca ECMAScript 6 uyumlu JavaScript'te kullanılabilir). Bunu Math.trunc()
yaparak ECMAScript-6 dışındaki ortamlar için her zaman kendi ortamınızı oluşturabilirsiniz:
if(!Math.trunc){
Math.trunc = function(value){
return Math.sign(value) * Math.floor(Math.abs(value));
}
}
Bu konuda referans için bir blog yazısı yazdım: http://bitlords.blogspot.com/2016/08/the-double-tilde-x-technique-in.html
İşte bu operatörün verimli bir şekilde nasıl kullanılabileceğine, onu kullanmanın mantıklı olduğu bir örnek:
leftOffset = -(~~$('html').css('padding-left').replace('px', '') + ~~$('body').css('margin-left').replace('px', '')),
Kaynak:
Dizeleri Sayılara Dönüştürme
console.log(~~-1); // -1
console.log(~~0); // 0
console.log(~~1); // 1
console.log(~~"-1"); // -1
console.log(~~"0"); // 0
console.log(~~"1"); // 1
console.log(~~true); // 1
console.log(~~false); // 0
~ -1 0
if (~someStr.indexOf("a")) {
// Found it
} else {
// Not Found
}
Tilde (~) bir algoritmaya sahiptir - (N + 1)
Sınav için:
~0 = -(0+1) = -1
~5 = -(5+1) = -6
~-7 = -(-7+1) = 6
Çift dalga işareti - (- (N + 1) +1)
Örneğin:
~~5 = -(-(5+1)+1) = 5
~~-3 = -(-(-3+1)+1) = -3
Üçlü yaklaşık işareti - (- (- (N + 1) +1) +1)
Örneğin:
~~~2 = -(-(-(2+1)+1)+1) = -3
~~~3 = -(-(-(3+1)+1)+1) = -4