This is an automated email from the ASF dual-hosted git repository.

wangweipeng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new 6100ebc79 feat(javascript): add float16 support (#3253)
6100ebc79 is described below

commit 6100ebc79fa392fe1a289c8b7f805273a1b0bf67
Author: Ayush Kumar <[email protected]>
AuthorDate: Tue Feb 10 13:11:41 2026 +0530

    feat(javascript): add float16 support (#3253)
    
    ## Why?
    
    Javascript package had the `float16` support but during serialization it
    fallbacks to `float32`, much like the `float16` was just a pseudo type
    which in real was a `float32`.
    
    ## What does this PR do?
    
    ### 1. Adds float16(v: number | string) method to the
    `BinaryWriterBuilder` class
    ```js
      float16(v: number | string) {
        return `${this.holder}.float16(${v})`
      }
    ```
    
    ### 2. Updated the `float16` accessor in the Codegen Regsitery
    ```js
    CodegenRegistry.register(TypeId.FLOAT16,
      buildNumberSerializer(
        (builder, accessor) => builder.writer.float16(accessor),
        builder => builder.reader.float16()
      )
    );
    ```
    ### 3. Updated the `writer/number.ts` and added `float16` test suites in
    `test/number.test.ts`
    ## Related Issue
    - Closes #3210
    
    ## Does this PR introduce any user-facing change?
    
    * [ ] Does this PR introduce any public API change?
    * [ ] Does this PR introduce any binary protocol compatibility change?
    ## Benchmark
    N/A
    
    ---------
    
    Co-authored-by: weipeng <[email protected]>
---
 javascript/packages/fory/lib/gen/builder.ts   |  4 +++
 javascript/packages/fory/lib/gen/number.ts    |  2 +-
 javascript/packages/fory/lib/writer/number.ts |  8 ++----
 javascript/test/array.test.ts                 | 29 +++++++++++++++----
 javascript/test/number.test.ts                | 41 ++++++++++++++++++---------
 5 files changed, 60 insertions(+), 24 deletions(-)

diff --git a/javascript/packages/fory/lib/gen/builder.ts 
b/javascript/packages/fory/lib/gen/builder.ts
index 972f5df23..c03c9aba3 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 4c5f6e3a0..83c3ffe27 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 a9acab3c7..55b81883d 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 365d62870..2a53633f0 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 f668c9685..37c15a9e4 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({


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to