Bire yerleştirilmiş iki sayıyla vektör matematiği yapmak mümkündür. Nasıl çalıştığını açıklamadan önce önce bir örnek göstermeme izin verin:
let a = vec_pack([2,4]);
let b = vec_pack([1,2]);
let c = a+b;
let d = c-b;
let e = d*2;
let f = e/2;
console.log(vec_unpack(c));
console.log(vec_unpack(d));
console.log(vec_unpack(e));
console.log(vec_unpack(f));
if(a === f) console.log("Equality works");
if(a > b) console.log("Y value takes priority");
İki sayıyı X kez değiştirirseniz ve sonra onları geri kaydırmadan önce ekler veya çıkarırsanız, başlangıçta kaydırmamışsınız gibi aynı sonucu elde edeceğiniz gerçeğini kullanıyorum. Benzer şekilde skaler çarpma ve bölme, kaydırılmış değerler için simetrik olarak çalışır.
Bir JavaScript numarası 52 bit tamsayı hassasiyetine sahiptir (64 bit kayar), bu yüzden bir sayıyı mevcut 26 bitten daha yüksek ve bir sayıyı daha düşük olana paketleyeceğim. İmzalı numaraları desteklemek istediğim için kod biraz daha karmaşık hale getirildi.
function vec_pack(vec){
return vec[1] * 67108864 + (vec[0] < 0 ? 33554432 | vec[0] : vec[0]);
}
function vec_unpack(number){
switch(((number & 33554432) !== 0) * 1 + (number < 0) * 2){
case(0):
return [(number % 33554432),Math.trunc(number / 67108864)];
break;
case(1):
return [(number % 33554432)-33554432,Math.trunc(number / 67108864)+1];
break;
case(2):
return [(((number+33554432) % 33554432) + 33554432) % 33554432,Math.round(number / 67108864)];
break;
case(3):
return [(number % 33554432),Math.trunc(number / 67108864)];
break;
}
}
Bununla görebildiğim tek dezavantaj, x ve y'nin + -33 milyon aralığında olması gerektiğidir, çünkü her biri 26 bit'e sığmaları gerekir.