เป็นไปได้ที่จะทำคณิตศาสตร์เวกเตอร์โดยรวมตัวเลขสองตัวไว้ในหนึ่งเดียว ให้ฉันดูตัวอย่างก่อนที่จะอธิบายวิธีการทำงาน:
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");
ฉันใช้ความจริงที่ว่าถ้าคุณขยับตัวเลขสองตัว X ครั้งแล้วบวกหรือลบก่อนที่จะขยับกลับคุณจะได้ผลลัพธ์เหมือนกับว่าคุณไม่ได้เลื่อนไปเริ่มต้นด้วย การคูณและการหารสเกลาร์ในทำนองเดียวกันจะทำงานแบบสมมาตรสำหรับค่าที่เลื่อน
หมายเลข JavaScript มีความแม่นยำจำนวนเต็ม 52 บิต (ลอยตัว 64 บิต) ดังนั้นฉันจะรวมตัวเลขหนึ่งเข้าไปในเขาที่สูงกว่าที่มีอยู่ 26 บิตและอีกอันหนึ่งเป็นตัวเลขที่ต่ำกว่า รหัสจะยุ่งขึ้นเล็กน้อยเพราะฉันต้องการรองรับหมายเลขที่ลงชื่อ
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;
}
}
ข้อเสียอย่างเดียวที่ฉันเห็นคือ x และ y ต้องอยู่ในช่วง + -33 ล้านเนื่องจากต้องพอดีภายใน 26 บิตต่อกัน