Skip to content

Instantly share code, notes, and snippets.

@Shoghy
Last active April 14, 2025 13:41
Show Gist options
  • Save Shoghy/d0aedca358b3e083d9a513f90553a9c1 to your computer and use it in GitHub Desktop.
Save Shoghy/d0aedca358b3e083d9a513f90553a9c1 to your computer and use it in GitHub Desktop.
Manual float 16 add
const byteMask = 0xff_ff;
function AddFloat16(a: number, b: number): number {
a = a & byteMask;
b = b & byteMask;
const signA = a >> 15;
const signB = b >> 15;
let expA = (a >> 10) & 0b11111;
let expB = (b >> 10) & 0b11111;
let mantA = a & 0b1111111111;
let mantB = b & 0b1111111111;
if (expA === 0x1f && mantA !== 0) return a;
if (expB === 0x1f && mantB !== 0) return b;
if (expA === 0x1f && expB === 0x1f) {
if (signA !== signB) {
return 0x7e00;
}
return a;
}
if (expA === 0x1f) return a;
if (expB === 0x1f) return b;
mantA = mantA | 0x400;
if (expA !== 0) {
expA -= 1;
}
mantB = mantB | 0x400;
if (expB !== 0) {
expB -= 1;
}
if (expA > expB) {
mantB = mantB >> (expA - expB);
expB = expA;
} else if (expB > expA) {
mantA = mantA >> (expB - expA);
expA = expB;
}
let resultMant: number;
if (signA === signB) {
resultMant = mantA + mantB;
} else {
resultMant = mantA - mantB;
}
let resultSign = signA;
if (resultMant < 0) {
resultSign = 1;
resultMant = -resultMant;
}
let resultExp = expA + 1;
while (resultMant >= 0x800) {
resultMant = resultMant >> 1;
resultExp += 1;
}
while (resultMant < 0x400 && resultExp > 0) {
resultMant = resultMant << 1;
resultExp -= 1;
}
if (resultExp >= 0x1f) {
return (resultSign << 15) | 0x7c00;
}
if (resultExp === 0) {
return (resultSign << 15) | (resultMant & 0x3ff);
}
return (resultSign << 15) | (resultExp << 10) | (resultMant & 0x3ff);
}
const f16Arr = new Float16Array(1);
const i16Arr = new Int16Array(f16Arr.buffer);
f16Arr[0] = 7;
const a = i16Arr[0];
f16Arr[0] = 3;
const b = i16Arr[0];
i16Arr[0] = AddFloat16(a, b);
console.log(f16Arr[0]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment