diff --git a/javascript/packages/fory/lib/gen/builder.ts b/javascript/packages/fory/lib/gen/builder.ts index 972f5df23c..c03c9aba35 100644 --- a/javascript/packages/fory/lib/gen/builder.ts +++ b/javascript/packages/fory/lib/gen/builder.ts @@ -233,6 +233,10 @@ class BinaryWriterBuilder { return `${this.holder}.float32(${v})`; } + float16(v: number | string) { + return `${this.holder}.float16(${v})`; + } + int64(v: number | string) { return `${this.holder}.int64(${v})`; } diff --git a/javascript/packages/fory/lib/gen/number.ts b/javascript/packages/fory/lib/gen/number.ts index a330339756..2595e3610f 100644 --- a/javascript/packages/fory/lib/gen/number.ts +++ b/javascript/packages/fory/lib/gen/number.ts @@ -90,7 +90,7 @@ CodegenRegistry.register(TypeId.TAGGED_INT64, ); CodegenRegistry.register(TypeId.FLOAT16, buildNumberSerializer( - (builder, accessor) => builder.writer.float32(accessor), + (builder, accessor) => builder.writer.float16(accessor), builder => builder.reader.float16() ) ); diff --git a/javascript/packages/fory/lib/writer/number.ts b/javascript/packages/fory/lib/writer/number.ts index a9acab3c70..55b81883db 100644 --- a/javascript/packages/fory/lib/writer/number.ts +++ b/javascript/packages/fory/lib/writer/number.ts @@ -36,11 +36,9 @@ export function toFloat16(value: number) { } if (exponent < -14) { - return sign | 0x3ff; // returns ±max subnormal - } - - if (exponent <= 0) { - return sign | ((significand | 0x800000) >> (1 - exponent + 10)); + // subnormal + // shift amount = 13 - 14 - exponent = -1 - exponent + return sign | ((significand | 0x800000) >> (13 - 14 - exponent)); } return sign | ((exponent + 15) << 10) | (significand >> 13); diff --git a/javascript/test/array.test.ts b/javascript/test/array.test.ts index 365d62870a..2a53633f0c 100644 --- a/javascript/test/array.test.ts +++ b/javascript/test/array.test.ts @@ -23,7 +23,7 @@ import * as beautify from 'js-beautify'; describe('array', () => { test('should array work', () => { - + const typeinfo = Type.struct({ typeName: "example.bar" @@ -35,9 +35,9 @@ describe('array', () => { })) }); const fory = new Fory({ refTracking: true, hooks: { - afterCodeGenerated: (code: string) => { - return beautify.js(code, { indent_size: 2, space_in_empty_paren: true, indent_empty_lines: true }); - } + afterCodeGenerated: (code: string) => { + return beautify.js(code, { indent_size: 2, space_in_empty_paren: true, indent_empty_lines: true }); + } } }); const { serialize, deserialize } = fory.registerSerializer(typeinfo); const o = { a: "123" }; @@ -82,7 +82,7 @@ describe('array', () => { }, { a5: Type.float32Array(), }) - + const fory = new Fory({ refTracking: true }); const serialize = fory.registerSerializer(typeinfo).serializer; const input = fory.serialize({ a5: [2.43, 654.4, 55], @@ -94,6 +94,25 @@ describe('array', () => { expect(result.a5[1]).toBeCloseTo(654.4) expect(result.a5[2]).toBeCloseTo(55) }); + + test('should float16Array work', () => { + const typeinfo = Type.struct({ + typeName: "example.foo" + }, { + a6: Type.float16Array(), + }) + + const fory = new Fory({ refTracking: true }); const serialize = fory.registerSerializer(typeinfo).serializer; + const input = fory.serialize({ + a6: [1.5, 2.5, -4.5], + }, serialize); + const result = fory.deserialize( + input + ); + expect(result.a6[0]).toBeCloseTo(1.5, 1) + expect(result.a6[1]).toBeCloseTo(2.5, 1) + expect(result.a6[2]).toBeCloseTo(-4.5, 1) + }); }); diff --git a/javascript/test/number.test.ts b/javascript/test/number.test.ts index f668c96852..37c15a9e47 100644 --- a/javascript/test/number.test.ts +++ b/javascript/test/number.test.ts @@ -22,8 +22,8 @@ import { describe, expect, test } from '@jest/globals'; describe('number', () => { test('should i8 work', () => { - - const fory = new Fory({ refTracking: true }); + + const fory = new Fory({ refTracking: true }); const serialize = fory.registerSerializer(Type.struct({ typeName: "example.foo" }, { @@ -36,8 +36,8 @@ describe('number', () => { expect(result).toEqual({ a: 1 }) }); test('should i16 work', () => { - - const fory = new Fory({ refTracking: true }); + + const fory = new Fory({ refTracking: true }); const serialize = fory.registerSerializer(Type.struct({ typeName: "example.foo" }, { @@ -50,8 +50,8 @@ describe('number', () => { expect(result).toEqual({ a: 1 }) }); test('should i32 work', () => { - - const fory = new Fory({ refTracking: true }); + + const fory = new Fory({ refTracking: true }); const serializer = fory.registerSerializer(Type.struct({ typeName: "example.foo" }, { @@ -64,8 +64,8 @@ describe('number', () => { expect(result).toEqual({ a: 1 }) }); test('should i64 work', () => { - - const fory = new Fory({ refTracking: true }); + + const fory = new Fory({ refTracking: true }); const serializer = fory.registerSerializer(Type.struct({ typeName: "example.foo" }, { @@ -79,9 +79,9 @@ describe('number', () => { expect(result).toEqual({ a: 1 }) }); - test('should float work', () => { - - const fory = new Fory({ refTracking: true }); + test('should float32 work', () => { + + const fory = new Fory({ refTracking: true }); const serializer = fory.registerSerializer(Type.struct({ typeName: "example.foo" }, { @@ -94,8 +94,8 @@ describe('number', () => { expect(result.a).toBeCloseTo(1.2) }); test('should float64 work', () => { - - const fory = new Fory({ refTracking: true }); + + const fory = new Fory({ refTracking: true }); const serializer = fory.registerSerializer(Type.struct({ typeName: "example.foo" }, { @@ -108,6 +108,21 @@ describe('number', () => { expect(result.a).toBeCloseTo(1.2) }); + test('should float16 work', () => { + + const fory = new Fory({ refTracking: true }); + const serializer = fory.registerSerializer(Type.struct({ + typeName: "example.foo" + }, { + a: Type.float16() + })).serializer; + const input = fory.serialize({ a: 1.2 }, serializer); + const result = fory.deserialize( + input + ); + expect(result.a).toBeCloseTo(1.2, 1) + }); + test('should uint8 work', () => { const fory = new Fory({ refTracking: true }); const serializer = fory.registerSerializer(Type.struct({