두 개의 숫자를 하나로 묶어 벡터 수학을 할 수 있습니다. 작동 원리를 설명하기 전에 먼저 예를 보여 드리겠습니다.
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가 각각 26 비트 내에 들어가야하기 때문에 + -3300 만 범위에 있어야한다는 것입니다.