feat: yaaay a triangle :)))
This commit is contained in:
@ -4,7 +4,7 @@ import { encodeFloat, decodeFloat } from "./encode"
|
||||
test("encode_float", () => {
|
||||
const input = 1.23;
|
||||
const encoded = encodeFloat(input)
|
||||
const output = decodeFloat(encoded[0], encoded[1])
|
||||
const output = decodeFloat(encoded)
|
||||
console.log(input, output)
|
||||
expect(output).toBeCloseTo(input);
|
||||
});
|
||||
@ -12,7 +12,7 @@ test("encode_float", () => {
|
||||
test("encode 2.0", () => {
|
||||
const input = 2.0;
|
||||
const encoded = encodeFloat(input)
|
||||
expect(encoded).toEqual([0, 128])
|
||||
expect(encoded).toEqual(1073741824)
|
||||
});
|
||||
|
||||
test("floating point imprecision", () => {
|
||||
@ -20,7 +20,7 @@ test("floating point imprecision", () => {
|
||||
new Array(10_000).fill(null).forEach((_, i) => {
|
||||
const input = i < 5_000 ? i : Math.random() * 100;
|
||||
const encoded = encodeFloat(input);
|
||||
const output = decodeFloat(encoded[0], encoded[1]);
|
||||
const output = decodeFloat(encoded);
|
||||
|
||||
const error = Math.abs(input - output);
|
||||
if (error > maxError) {
|
||||
@ -36,7 +36,7 @@ test("negative numbers", () => {
|
||||
const inputs = [-1, -0.5, -123.456, -0.0001];
|
||||
inputs.forEach(input => {
|
||||
const encoded = encodeFloat(input);
|
||||
const output = decodeFloat(encoded[0], encoded[1]);
|
||||
const output = decodeFloat(encoded);
|
||||
expect(output).toBeCloseTo(input);
|
||||
});
|
||||
});
|
||||
@ -45,7 +45,7 @@ test("negative numbers", () => {
|
||||
test("very small numbers", () => {
|
||||
const input = 1.2345e-38;
|
||||
const encoded = encodeFloat(input)
|
||||
const output = decodeFloat(encoded[0], encoded[1])
|
||||
const output = decodeFloat(encoded)
|
||||
expect(output).toBeCloseTo(input);
|
||||
});
|
||||
|
||||
@ -53,7 +53,7 @@ test("very small numbers", () => {
|
||||
test("zero", () => {
|
||||
const input = 0;
|
||||
const encoded = encodeFloat(input)
|
||||
const output = decodeFloat(encoded[0], encoded[1])
|
||||
const output = decodeFloat(encoded)
|
||||
expect(output).toBe(0);
|
||||
});
|
||||
|
||||
@ -61,7 +61,7 @@ test("zero", () => {
|
||||
test("infinity", () => {
|
||||
const input = Infinity;
|
||||
const encoded = encodeFloat(input)
|
||||
const output = decodeFloat(encoded[0], encoded[1])
|
||||
const output = decodeFloat(encoded)
|
||||
expect(output).toBe(Infinity);
|
||||
});
|
||||
|
||||
@ -70,7 +70,7 @@ test("large numbers", () => {
|
||||
const inputs = [1e+5, 1e+10];
|
||||
inputs.forEach(input => {
|
||||
const encoded = encodeFloat(input);
|
||||
const output = decodeFloat(encoded[0], encoded[1]);
|
||||
const output = decodeFloat(encoded);
|
||||
// Note: Large numbers may lose precision, hence using toBeCloseTo with a tolerance
|
||||
expect(output).toBeCloseTo(input, 0);
|
||||
});
|
||||
|
@ -1,34 +1,19 @@
|
||||
// Create a buffer to hold the float as bytes
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const view = new DataView(buffer);
|
||||
|
||||
export function encodeFloat(f: number): [number, number] {
|
||||
let buffer = new ArrayBuffer(4); // Create a buffer of 4 bytes (32 bits)
|
||||
let floatView = new Float32Array(buffer);
|
||||
let intView = new Uint32Array(buffer);
|
||||
export function encodeFloat(value: number): number {
|
||||
// Write the number as a float to the buffer
|
||||
view.setFloat32(0, value, true); // 'true' for little-endian
|
||||
|
||||
floatView[0] = f; // Store the float into the buffer
|
||||
let bits = intView[0]; // Read the bits as integer
|
||||
|
||||
let mantissa = bits & 0x007FFFFF;
|
||||
let exponent = (bits >> 23) & 0xFF;
|
||||
let sign = (f < 0.0) ? 1 : 0;
|
||||
|
||||
// Include the sign bit in the mantissa
|
||||
mantissa = mantissa | (sign << 23);
|
||||
|
||||
return [mantissa, exponent];
|
||||
// Read the buffer as an integer
|
||||
return view.getInt32(0, true);
|
||||
}
|
||||
|
||||
export function decodeFloat(mantissa: number, exponent: number): number {
|
||||
let signBit = (mantissa >> 23) & 1;
|
||||
let mantissaBits = mantissa & 0x007FFFFF;
|
||||
let exponentBits = (exponent & 0xFF) << 23;
|
||||
export function decodeFloat(value: number): number {
|
||||
// Write the integer back as an int32
|
||||
view.setInt32(0, value, true);
|
||||
|
||||
// Reconstruct all bits including sign
|
||||
let bits = (signBit << 31) | exponentBits | mantissaBits;
|
||||
|
||||
let buffer = new ArrayBuffer(4);
|
||||
let floatView = new Float32Array(buffer);
|
||||
let intView = new Uint32Array(buffer);
|
||||
|
||||
intView[0] = bits; // Set the bits as integer
|
||||
return floatView[0]; // Read the float back from the buffer
|
||||
// Read the buffer as a float
|
||||
return view.getFloat32(0, true);
|
||||
}
|
||||
|
Reference in New Issue
Block a user