Skip to content

Commit

Permalink
Implement the js u16 arithmetic and bitwise operations (#905)
Browse files Browse the repository at this point in the history
  • Loading branch information
dfellis authored Sep 20, 2024
1 parent 7cce430 commit e87001f
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 0 deletions.
140 changes: 140 additions & 0 deletions alan_std.js
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,17 @@ export function wrappingPowU8(a, b) {
return v;
}

export function notU8(a) {
let v = ~a;
while (v > 255) {
v -= 256;
}
while (v < 0) {
v += 256;
}
return v;
}

export function wrappingShlU8(a, b) {
let v = a << b;
while (v > 255) {
Expand Down Expand Up @@ -687,3 +698,132 @@ export function rotateRightU8(a, b) {
let p2 = a & rhs;
return wrappingShrU8(p1, 8 - c) + wrappingShlU8(p2, c);
}

export function wrappingAddU16(a, b) {
let v = a + b;
while (v > 65_535) {
v -= 65_536;
}
while (v < 0) {
v += 65_536;
}
return v;
}

export function wrappingSubU16(a, b) {
let v = a - b;
while (v > 65_535) {
v -= 65_536;
}
while (v < 0) {
v += 65_536;
}
return v;
}

export function wrappingMulU16(a, b) {
let v = a * b;
while (v > 65_535) {
v -= 65_536;
}
while (v < 0) {
v += 65_536;
}
return v;
}

export function wrappingDivU16(a, b) {
let v = Math.floor(a / b);
while (v > 65_535) {
v -= 65_536;
}
while (v < 0) {
v += 65_536;
}
return v;
}

export function wrappingModU16(a, b) {
let v = a % b;
while (v > 65_535) {
v -= 65_536;
}
while (v < 0) {
v += 65_536;
}
return v;
}

export function wrappingPowU16(a, b) {
let v = Math.floor(a ** b);
while (v > 65_535) {
v -= 65_536;
}
while (v < 0) {
v += 65_536;
}
return v;
}

export function notU16(a) {
let v = ~a;
while (v > 65_535) {
v -= 65_536;
}
while (v < 0) {
v += 65_536;
}
return v;
}

export function wrappingShlU16(a, b) {
let v = a << b;
while (v > 65_535) {
v -= 65_536;
}
while (v < 0) {
v += 65_536;
}
return v;
}

export function wrappingShrU16(a, b) {
let v = a >> b;
while (v > 65_535) {
v -= 65_536;
}
while (v < 0) {
v += 65_536;
}
return v;
}

export function rotateLeftU16(a, b) {
let c = b;
while (c > 15) {
c -= 16;
}
if (c == 0) {
return a;
}
let lhs = clampU16(65_535 << c);
let rhs = clampU16(65_535 ^ lhs);
let p1 = a & lhs;
let p2 = a & rhs;
return wrappingShrU16(p1, 16 - c) + wrappingShlU16(p2, c);
}

export function rotateRightU16(a, b) {
let c = b;
while (c > 15) {
c -= 16;
}
if (c == 0) {
return a;
}
let rhs = clampU16(65_535 << c);
let lhs = clampU16(65_535 ^ rhs);
let p1 = a & lhs;
let p2 = a & rhs;
return wrappingShrU16(p1, 16 - c) + wrappingShlU16(p2, c);
}
26 changes: 26 additions & 0 deletions alan_std.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,36 @@ assert(alanStd.wrappingModU8(5, 2) == 1, "wrappingModU8 5 % 2 = 1");

assert(alanStd.wrappingPowU8(2, 8) == 0, "wrappingPowU8 2 ^ 8 = 0");

assert(alanStd.notU8(0) == 255, "notU8 0 = 255");

assert(alanStd.wrappingShlU8(128, 1) == 0, "wrappingShlU8 128 << 1 = 0");

assert(alanStd.wrappingShrU8(128, 1) == 64, "wrappingShrU8 128 >> 1 = 64");

assert(alanStd.rotateLeftU8(128, 1) == 1, "rotateLeftU8 128 <<< 1 = 1");

assert(alanStd.rotateRightU8(64, 1) == 128, "rotateRightU8 64 >>> 1 = 128");

assert(alanStd.wrappingAddU16(1, 2) === 3, "wrappingAddU16 1 + 2 = 3");
assert(alanStd.wrappingAddU16(65_535, 1) === 0, "wrappingAddU16 65_535 + 1 = 0");

assert(alanStd.wrappingSubU16(1, 2) === 65_535, "wrappingSubU16 1 - 2 = 65_535");
assert(alanStd.wrappingSubU16(65_535, 1) === 65_534, "wrappingSubU16 65_535 - 1 = 65_534");

assert(alanStd.wrappingMulU16(256, 256) === 0, "wrappingMulU16 256 * 256 = 0");

assert(alanStd.wrappingDivU16(128, 2) == 64, "wrappingDivU16 128 / 2 = 64");

assert(alanStd.wrappingModU16(5, 2) == 1, "wrappingModU16 5 % 2 = 1");

assert(alanStd.wrappingPowU16(2, 16) == 0, "wrappingPowU16 2 ^ 8 = 0");

assert(alanStd.notU16(0) == 65_535, "notU16 0 = 65_535");

assert(alanStd.wrappingShlU16(32_768, 1) == 0, "wrappingShlU16 32_768 << 1 = 0");

assert(alanStd.wrappingShrU16(128, 1) == 64, "wrappingShrU16 128 >> 1 = 64");

assert(alanStd.rotateLeftU16(32_768, 1) == 1, "rotateLeftU16 128 <<< 1 = 1");

assert(alanStd.rotateRightU16(64, 1) == 128, "rotateRightU16 64 >>> 1 = 128");

0 comments on commit e87001f

Please sign in to comment.