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]