diff --git a/src/index.test.ts b/src/index.test.ts index 249bbb0..7a681cf 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -676,6 +676,31 @@ describe('stringify & parse', () => { }, }, + 'preserves negative zero in Float64Array and Float32Array': { + input: { + a: new Float64Array([-0, 0, -0, 1]), + b: new Float32Array([-0, 2]), + }, + output: { + a: ['-0', 0, '-0', 1], + b: ['-0', 2], + }, + outputAnnotations: { + values: { + a: [['typed-array', 'Float64Array']], + b: [['typed-array', 'Float32Array']], + }, + }, + customExpectations: (value: any) => { + expect(Object.is(value.a[0], -0)).toBe(true); + expect(Object.is(value.a[1], 0)).toBe(true); + expect(Object.is(value.a[2], -0)).toBe(true); + expect(value.a[3]).toBe(1); + expect(Object.is(value.b[0], -0)).toBe(true); + expect(value.b[1]).toBe(2); + }, + }, + 'works with BigInt typed arrays': { input: { a: new BigInt64Array([1n, 2n, -3n, 9007199254740993n]), diff --git a/src/transformer.ts b/src/transformer.ts index cce7d55..86fae24 100644 --- a/src/transformer.ts +++ b/src/transformer.ts @@ -250,6 +250,9 @@ const typedArrayRule = compositeTransformation( if (Number.isNaN(n)) return 'NaN'; if (n === Infinity) return 'Infinity'; if (n === -Infinity) return '-Infinity'; + // Negative zero also doesn't survive JSON (JSON.stringify(-0) === '0'), + // so it's stored as a string like the other special float values. + if (n === 0 && 1 / n === -Infinity) return '-0'; } return n; }), @@ -271,6 +274,7 @@ const typedArrayRule = compositeTransformation( if (n === 'NaN') return NaN; if (n === 'Infinity') return Infinity; if (n === '-Infinity') return -Infinity; + if (n === '-0') return -0; return n as number; });