This is an automated email from the ASF dual-hosted git repository.
chaokunyang 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 97edbfb80 feat(javascript): add bfloat16 and bfloat16_array support
(#3328)
97edbfb80 is described below
commit 97edbfb80bc8dede1bedc8bda20a84a54d997161
Author: Talha Amjad <[email protected]>
AuthorDate: Fri Feb 13 07:52:22 2026 +0500
feat(javascript): add bfloat16 and bfloat16_array support (#3328)
## Summary
Adds **bfloat16** and **bfloat16_array** support to the Fory JavaScript
runtime and codegen, following the same structure as the existing
float16 implementation.
Fixes #3288
## Changes
### Runtime
- **BFloat16** class with `fromBits()` / `toBits()` and `fromFloat32()`
/ `toFloat32()` (IEEE 754 compliant, round-to-nearest ties-to-even for
float32→bfloat16).
- **BFloat16Array** backed by `Uint16Array` for packed bfloat16 arrays;
supports iteration and `fromRaw()` for deserialization.
- Wire format: 2 bytes per value (little-endian), matching existing
float32/float64 behavior. NaN/Inf/±0/subnormals round-trip correctly.
### Type system & serialization
- `Type.bfloat16()` and `Type.bfloat16Array()`.
- Serializers registered in type resolver; reader returns `BFloat16` (no
raw uint16 in public API).
- Codegen: `gen/builder.ts`, `gen/number.ts`, and `gen/typedArray.ts`
updated for bfloat16 and bfloat16_array.
### API
- `BFloat16` and `BFloat16Array` exported from the package.
- Writer accepts `BFloat16 | number` for scalar bfloat16; arrays accept
`BFloat16[]` or `BFloat16Array`.
### Tests
- Scalar: normal values, NaN, Infinity, ±0 round-trip.
- Array: `bfloat16Array` with number array and with `BFloat16Array`.
## Checklist
- [x] BFloat16 type with to_bits/from_bits and float32 conversions
- [x] BFloat16Array with packed Uint16Array storage
- [x] Wire format 2 bytes, endianness aligned with float32/float64
- [x] Type.bfloat16() and Type.bfloat16Array(); resolver and codegen
- [x] Tests for scalar and array serialization/round-trip
---
javascript/packages/fory/index.ts | 3 +
javascript/packages/fory/lib/bfloat16.ts | 121 +++++++++++++++++++++++++
javascript/packages/fory/lib/gen/builder.ts | 8 ++
javascript/packages/fory/lib/gen/number.ts | 6 ++
javascript/packages/fory/lib/gen/typedArray.ts | 41 +++++++++
javascript/packages/fory/lib/reader/index.ts | 5 +
javascript/packages/fory/lib/typeInfo.ts | 19 +++-
javascript/packages/fory/lib/typeResolver.ts | 2 +
javascript/packages/fory/lib/writer/index.ts | 9 +-
javascript/packages/fory/lib/writer/number.ts | 22 +++++
javascript/test/array.test.ts | 37 +++++++-
javascript/test/number.test.ts | 70 +++++++++++++-
12 files changed, 338 insertions(+), 5 deletions(-)
diff --git a/javascript/packages/fory/index.ts
b/javascript/packages/fory/index.ts
index 36c73ac82..efb460796 100644
--- a/javascript/packages/fory/index.ts
+++ b/javascript/packages/fory/index.ts
@@ -29,6 +29,7 @@ import { Serializer, Mode } from "./lib/type";
import Fory from "./lib/fory";
import { BinaryReader } from "./lib/reader";
import { BinaryWriter } from "./lib/writer";
+import { BFloat16, BFloat16Array } from "./lib/bfloat16";
export {
Serializer,
@@ -41,6 +42,8 @@ export {
ForyField,
Dynamic,
BinaryReader,
+ BFloat16,
+ BFloat16Array,
};
export default Fory;
diff --git a/javascript/packages/fory/lib/bfloat16.ts
b/javascript/packages/fory/lib/bfloat16.ts
new file mode 100644
index 000000000..0beb46d44
--- /dev/null
+++ b/javascript/packages/fory/lib/bfloat16.ts
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const float32View = new Float32Array(1);
+const uint32View = new Uint32Array(float32View.buffer);
+
+export class BFloat16 {
+ private readonly _bits: number;
+
+ constructor(bits: number) {
+ this._bits = bits & 0xffff;
+ }
+
+ toBits(): number {
+ return this._bits;
+ }
+
+ static fromBits(bits: number): BFloat16 {
+ return new BFloat16(bits & 0xffff);
+ }
+
+ static fromFloat32(f32: number): BFloat16 {
+ float32View[0] = f32;
+ const bits = uint32View[0];
+ const exponent = (bits >> 23) & 0xff;
+ if (exponent === 255) {
+ return BFloat16.fromBits((bits >> 16) & 0xffff);
+ }
+ const remainder = bits & 0x1ffff;
+ let u = (bits + 0x8000) >> 16;
+ if (remainder === 0x8000 && (u & 1) !== 0) {
+ u--;
+ }
+ return BFloat16.fromBits(u & 0xffff);
+ }
+
+ toFloat32(): number {
+ float32View[0] = 0;
+ uint32View[0] = this._bits << 16;
+ return float32View[0];
+ }
+}
+
+export class BFloat16Array {
+ private readonly _data: Uint16Array;
+
+ constructor(length: number);
+ constructor(source: Uint16Array | BFloat16[] | number[]);
+ constructor(lengthOrSource: number | Uint16Array | BFloat16[] | number[]) {
+ if (typeof lengthOrSource === "number") {
+ this._data = new Uint16Array(lengthOrSource);
+ } else if (lengthOrSource instanceof Uint16Array) {
+ this._data = new Uint16Array(lengthOrSource.length);
+ this._data.set(lengthOrSource);
+ } else {
+ const arr = lengthOrSource as (BFloat16 | number)[];
+ this._data = new Uint16Array(arr.length);
+ for (let i = 0; i < arr.length; i++) {
+ const v = arr[i];
+ this._data[i]
+ = v instanceof BFloat16 ? v.toBits() :
BFloat16.fromFloat32(v).toBits();
+ }
+ }
+ }
+
+ get length(): number {
+ return this._data.length;
+ }
+
+ get(index: number): BFloat16 {
+ return BFloat16.fromBits(this._data[index]);
+ }
+
+ set(index: number, value: BFloat16 | number): void {
+ this._data[index]
+ = value instanceof BFloat16 ? value.toBits() :
BFloat16.fromFloat32(value).toBits();
+ }
+
+ get raw(): Uint16Array {
+ return this._data;
+ }
+
+ static fromRaw(data: Uint16Array): BFloat16Array {
+ const arr = new BFloat16Array(data.length);
+ arr._data.set(data);
+ return arr;
+ }
+
+ [Symbol.iterator](): IterableIterator<BFloat16> {
+ let i = 0;
+ const data = this._data;
+ const len = data.length;
+ return {
+ next(): IteratorResult<BFloat16> {
+ if (i < len) {
+ return { value: BFloat16.fromBits(data[i++]), done: false };
+ }
+ return { value: undefined as unknown as BFloat16, done: true };
+ },
+ [Symbol.iterator]() {
+ return this;
+ },
+ };
+ }
+}
diff --git a/javascript/packages/fory/lib/gen/builder.ts
b/javascript/packages/fory/lib/gen/builder.ts
index 7627340d1..e8610c0fe 100644
--- a/javascript/packages/fory/lib/gen/builder.ts
+++ b/javascript/packages/fory/lib/gen/builder.ts
@@ -115,6 +115,10 @@ export class BinaryReaderBuilder {
return `${this.holder}.float16()`;
}
+ bfloat16() {
+ return `${this.holder}.bfloat16()`;
+ }
+
uint16() {
return `${this.holder}.uint16()`;
}
@@ -257,6 +261,10 @@ class BinaryWriterBuilder {
return `${this.holder}.float16(${v})`;
}
+ bfloat16(v: number | string) {
+ return `${this.holder}.bfloat16(${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 dd3380d5a..0eef57bae 100644
--- a/javascript/packages/fory/lib/gen/number.ts
+++ b/javascript/packages/fory/lib/gen/number.ts
@@ -102,6 +102,12 @@ CodegenRegistry.register(TypeId.FLOAT16,
builder => builder.reader.float16()
)
);
+CodegenRegistry.register(TypeId.BFLOAT16,
+ buildNumberSerializer(
+ (builder, accessor) => builder.writer.bfloat16(accessor),
+ builder => builder.reader.bfloat16()
+ )
+);
CodegenRegistry.register(TypeId.FLOAT32,
buildNumberSerializer(
(builder, accessor) => builder.writer.float32(accessor),
diff --git a/javascript/packages/fory/lib/gen/typedArray.ts
b/javascript/packages/fory/lib/gen/typedArray.ts
index 38659a4d7..4330443fa 100644
--- a/javascript/packages/fory/lib/gen/typedArray.ts
+++ b/javascript/packages/fory/lib/gen/typedArray.ts
@@ -137,6 +137,46 @@ class Float16ArraySerializerGenerator extends
BaseSerializerGenerator {
return 7;
}
}
+
+class BFloat16ArraySerializerGenerator extends BaseSerializerGenerator {
+ typeInfo: TypeInfo;
+
+ constructor(typeInfo: TypeInfo, builder: CodecBuilder, scope: Scope) {
+ super(typeInfo, builder, scope);
+ this.typeInfo = <TypeInfo>typeInfo;
+ }
+
+ write(accessor: string): string {
+ const item = this.scope.uniqueName("item");
+ return `
+ ${this.builder.writer.varUInt32(`${accessor}.length * 2`)}
+ ${this.builder.writer.reserve(`${accessor}.length * 2`)};
+ for (const ${item} of ${accessor}) {
+ ${this.builder.writer.bfloat16(item)}
+ }
+ `;
+ }
+
+ read(accessor: (expr: string) => string, refState: string): string {
+ const result = this.scope.uniqueName("result");
+ const len = this.scope.uniqueName("len");
+ const idx = this.scope.uniqueName("idx");
+ return `
+ const ${len} = ${this.builder.reader.varUInt32()} / 2;
+ const ${result} = new Array(${len});
+ ${this.maybeReference(result, refState)}
+ for (let ${idx} = 0; ${idx} < ${len}; ${idx}++) {
+ ${result}[${idx}] = ${this.builder.reader.bfloat16()};
+ }
+ ${accessor(result)}
+ `;
+ }
+
+ getFixedSize(): number {
+ return 7;
+ }
+}
+
CodegenRegistry.register(TypeId.BOOL_ARRAY, BoolArraySerializerGenerator);
CodegenRegistry.register(TypeId.BINARY, build(Type.uint8(), `Uint8Array`, 1));
CodegenRegistry.register(TypeId.INT8_ARRAY, build(Type.int8(), `Int8Array`,
1));
@@ -148,5 +188,6 @@ CodegenRegistry.register(TypeId.UINT16_ARRAY,
build(Type.uint16(), `Uint16Array`
CodegenRegistry.register(TypeId.UINT32_ARRAY, build(Type.uint32(),
`Uint32Array`, 4));
CodegenRegistry.register(TypeId.UINT64_ARRAY, build(Type.uint64(),
`BigUint64Array`, 8));
CodegenRegistry.register(TypeId.FLOAT16_ARRAY,
Float16ArraySerializerGenerator);
+CodegenRegistry.register(TypeId.BFLOAT16_ARRAY,
BFloat16ArraySerializerGenerator);
CodegenRegistry.register(TypeId.FLOAT32_ARRAY, build(Type.float32(),
`Float32Array`, 4));
CodegenRegistry.register(TypeId.FLOAT64_ARRAY, build(Type.float64(),
`Float64Array`, 6));
diff --git a/javascript/packages/fory/lib/reader/index.ts
b/javascript/packages/fory/lib/reader/index.ts
index d63cd2f15..9786b0bf2 100644
--- a/javascript/packages/fory/lib/reader/index.ts
+++ b/javascript/packages/fory/lib/reader/index.ts
@@ -21,6 +21,7 @@ import { LATIN1, UTF16, UTF8 } from "../type";
import { isNodeEnv } from "../util";
import { PlatformBuffer, alloc, fromUint8Array } from "../platformBuffer";
import { readLatin1String } from "./string";
+import { BFloat16 } from "../bfloat16";
export class BinaryReader {
private sliceStringEnable;
@@ -508,6 +509,10 @@ export class BinaryReader {
}
}
+ bfloat16(): BFloat16 {
+ return BFloat16.fromBits(this.uint16());
+ }
+
getCursor() {
return this.cursor;
}
diff --git a/javascript/packages/fory/lib/typeInfo.ts
b/javascript/packages/fory/lib/typeInfo.ts
index 9359eb7ae..cfa6e69fb 100644
--- a/javascript/packages/fory/lib/typeInfo.ts
+++ b/javascript/packages/fory/lib/typeInfo.ts
@@ -19,6 +19,7 @@
import Fory from "./fory";
import { ForyTypeInfoSymbol, TypeId, Mode } from "./type";
+import { BFloat16 } from "./bfloat16";
const targetFieldInfo = new WeakMap<new () => any, { [key: string]:
StructFieldInfo }>();
@@ -465,6 +466,8 @@ export type HintInput<T> = T extends {
type: typeof TypeId.STRING;
}
? string
+ : T extends { type: typeof TypeId.BFLOAT16 }
+ ? BFloat16 | number
: T extends {
type:
| typeof TypeId["INT8"]
@@ -479,7 +482,6 @@ export type HintInput<T> = T extends {
| typeof TypeId.VAR_UINT32
| typeof TypeId.FLOAT8
| typeof TypeId.FLOAT16
- | typeof TypeId.BFLOAT16
| typeof TypeId.FLOAT32
| typeof TypeId.FLOAT64;
}
@@ -537,6 +539,8 @@ export type HintResult<T> = T extends never ? any : T
extends {
type: typeof TypeId.STRING;
}
? string
+ : T extends { type: typeof TypeId.BFLOAT16 }
+ ? BFloat16
: T extends {
type:
| typeof TypeId.INT8
@@ -549,7 +553,6 @@ export type HintResult<T> = T extends never ? any : T
extends {
| typeof TypeId.VAR_UINT32
| typeof TypeId.FLOAT8
| typeof TypeId.FLOAT16
- | typeof TypeId.BFLOAT16
| typeof TypeId.FLOAT32
| typeof TypeId.FLOAT64;
}
@@ -729,6 +732,12 @@ export const Type = {
);
},
+ bfloat16() {
+ return TypeInfo.fromNonParam<typeof TypeId.BFLOAT16>(
+ (TypeId.BFLOAT16),
+
+ );
+ },
float32() {
return TypeInfo.fromNonParam<typeof TypeId.FLOAT32>(
(TypeId.FLOAT32),
@@ -862,6 +871,12 @@ export const Type = {
);
},
+ bfloat16Array() {
+ return TypeInfo.fromNonParam<typeof TypeId.BFLOAT16_ARRAY>(
+ (TypeId.BFLOAT16_ARRAY),
+
+ );
+ },
float32Array() {
return TypeInfo.fromNonParam<typeof TypeId.FLOAT32_ARRAY>(
(TypeId.FLOAT32_ARRAY),
diff --git a/javascript/packages/fory/lib/typeResolver.ts
b/javascript/packages/fory/lib/typeResolver.ts
index e11de059a..a06c9e7f8 100644
--- a/javascript/packages/fory/lib/typeResolver.ts
+++ b/javascript/packages/fory/lib/typeResolver.ts
@@ -110,6 +110,7 @@ export default class TypeResolver {
registerSerializer(Type.taggedUInt64());
registerSerializer(Type.sliInt64());
registerSerializer(Type.float16());
+ registerSerializer(Type.bfloat16());
registerSerializer(Type.float32());
registerSerializer(Type.float64());
registerSerializer(Type.timestamp());
@@ -127,6 +128,7 @@ export default class TypeResolver {
registerSerializer(Type.uint64Array());
registerSerializer(Type.int64Array());
registerSerializer(Type.float16Array());
+ registerSerializer(Type.bfloat16Array());
registerSerializer(Type.float32Array());
registerSerializer(Type.float64Array());
diff --git a/javascript/packages/fory/lib/writer/index.ts
b/javascript/packages/fory/lib/writer/index.ts
index bbb28a419..2d7992c47 100644
--- a/javascript/packages/fory/lib/writer/index.ts
+++ b/javascript/packages/fory/lib/writer/index.ts
@@ -20,7 +20,8 @@
import { HalfMaxInt32, HalfMinInt32, Hps, LATIN1, UTF16, UTF8 } from "../type";
import { PlatformBuffer, alloc, strByteLength } from "../platformBuffer";
import { OwnershipError } from "../error";
-import { toFloat16 } from "./number";
+import { toFloat16, toBFloat16 } from "./number";
+import { BFloat16 } from "../bfloat16";
const MAX_POOL_SIZE = 1024 * 1024 * 3; // 3MB
@@ -455,6 +456,12 @@ export class BinaryWriter {
this.uint16(toFloat16(value));
}
+ bfloat16(value: BFloat16 | number) {
+ const bits
+ = value instanceof BFloat16 ? value.toBits() : toBFloat16(value);
+ this.uint16(bits);
+ }
+
getCursor() {
return this.cursor;
}
diff --git a/javascript/packages/fory/lib/writer/number.ts
b/javascript/packages/fory/lib/writer/number.ts
index 8729dc372..1c38ce39e 100644
--- a/javascript/packages/fory/lib/writer/number.ts
+++ b/javascript/packages/fory/lib/writer/number.ts
@@ -43,3 +43,25 @@ export function toFloat16(value: number) {
return sign | ((exponent + 15) << 10) | (significand >> 13);
}
+
+const float32ViewBf = new Float32Array(1);
+const uint32ViewBf = new Uint32Array(float32ViewBf.buffer);
+
+/**
+ * Convert float32 to bfloat16 bits (round-to-nearest, ties-to-even).
+ * BFloat16 layout: 1 sign, 8 exponent, 7 mantissa.
+ */
+export function toBFloat16(value: number): number {
+ float32ViewBf[0] = value;
+ const bits = uint32ViewBf[0];
+ const exponent = (bits >> 23) & 0xff;
+ if (exponent === 255) {
+ return (bits >> 16) & 0xffff;
+ }
+ const remainder = bits & 0x1ffff;
+ let u = (bits + 0x8000) >> 16;
+ if (remainder === 0x8000 && (u & 1) !== 0) {
+ u--;
+ }
+ return u & 0xffff;
+}
diff --git a/javascript/test/array.test.ts b/javascript/test/array.test.ts
index c8c094858..0abbd571a 100644
--- a/javascript/test/array.test.ts
+++ b/javascript/test/array.test.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import Fory, { Type } from '../packages/fory/index';
+import Fory, { Type, BFloat16Array } from '../packages/fory/index';
import { describe, expect, test } from '@jest/globals';
import * as beautify from 'js-beautify';
@@ -113,6 +113,41 @@ describe('array', () => {
expect(result.a6[1]).toBeCloseTo(2.5, 1)
expect(result.a6[2]).toBeCloseTo(-4.5, 1)
});
+
+ test('should bfloat16Array work', () => {
+ const typeinfo = Type.struct({
+ typeName: "example.foo"
+ }, {
+ a7: Type.bfloat16Array(),
+ });
+ const fory = new Fory({ refTracking: true });
+ const serialize = fory.registerSerializer(typeinfo).serializer;
+ const input = fory.serialize({
+ a7: [1.5, 2.5, -4.5],
+ }, serialize);
+ const result = fory.deserialize(input);
+ expect(result.a7).toHaveLength(3);
+ expect(result.a7[0].toFloat32()).toBeCloseTo(1.5, 2);
+ expect(result.a7[1].toFloat32()).toBeCloseTo(2.5, 2);
+ expect(result.a7[2].toFloat32()).toBeCloseTo(-4.5, 2);
+ });
+
+ test('should bfloat16Array accept BFloat16Array', () => {
+ const typeinfo = Type.struct({
+ typeName: "example.foo"
+ }, {
+ a7: Type.bfloat16Array(),
+ });
+ const fory = new Fory({ refTracking: true });
+ const serialize = fory.registerSerializer(typeinfo).serializer;
+ const arr = new BFloat16Array([1.25, -2.5, 0]);
+ const input = fory.serialize({ a7: arr }, serialize);
+ const result = fory.deserialize(input);
+ expect(result.a7).toHaveLength(3);
+ expect(result.a7[0].toFloat32()).toBeCloseTo(1.25, 2);
+ expect(result.a7[1].toFloat32()).toBeCloseTo(-2.5, 2);
+ expect(result.a7[2].toFloat32()).toBe(0);
+ });
});
diff --git a/javascript/test/number.test.ts b/javascript/test/number.test.ts
index a13185be9..3201905ce 100644
--- a/javascript/test/number.test.ts
+++ b/javascript/test/number.test.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import Fory, { Type } from '../packages/fory/index';
+import Fory, { Type, BFloat16 } from '../packages/fory/index';
import { describe, expect, test } from '@jest/globals';
describe('number', () => {
@@ -153,6 +153,74 @@ describe('number', () => {
expect(result.a).toBeCloseTo(Infinity)
});
+ test('should bfloat16 work', () => {
+ const fory = new Fory({ refTracking: true });
+ const serializer = fory.registerSerializer(Type.struct({
+ typeName: "example.foo"
+ }, {
+ a: Type.bfloat16()
+ })).serializer;
+ const input = fory.serialize({ a: BFloat16.fromFloat32(1.5) }, serializer);
+ const result = fory.deserialize(input);
+ expect(result.a).toBeInstanceOf(BFloat16);
+ expect(result.a.toFloat32()).toBeCloseTo(1.5, 2);
+ });
+
+ test('should bfloat16 accept number', () => {
+ const fory = new Fory({ refTracking: true });
+ const serializer = fory.registerSerializer(Type.struct({
+ typeName: "example.foo"
+ }, {
+ a: Type.bfloat16()
+ })).serializer;
+ const input = fory.serialize({ a: 1.5 }, serializer);
+ const result = fory.deserialize(input);
+ expect(result.a).toBeInstanceOf(BFloat16);
+ expect(result.a.toFloat32()).toBeCloseTo(1.5, 2);
+ });
+
+ test('should bfloat16 NaN work', () => {
+ const fory = new Fory({ refTracking: true });
+ const serializer = fory.registerSerializer(Type.struct({
+ typeName: "example.foo"
+ }, {
+ a: Type.bfloat16()
+ })).serializer;
+ const input = fory.serialize({ a: NaN }, serializer);
+ const result = fory.deserialize(input);
+ expect(result.a).toBeInstanceOf(BFloat16);
+ expect(Number.isNaN(result.a.toFloat32())).toBe(true);
+ });
+
+ test('should bfloat16 Infinity work', () => {
+ const fory = new Fory({ refTracking: true });
+ const serializer = fory.registerSerializer(Type.struct({
+ typeName: "example.foo"
+ }, {
+ a: Type.bfloat16()
+ })).serializer;
+ const input = fory.serialize({ a: Infinity }, serializer);
+ const result = fory.deserialize(input);
+ expect(result.a).toBeInstanceOf(BFloat16);
+ expect(result.a.toFloat32()).toBe(Infinity);
+ });
+
+ test('should bfloat16 zero and neg zero round-trip', () => {
+ const fory = new Fory({ refTracking: true });
+ const serializer = fory.registerSerializer(Type.struct({
+ typeName: "example.foo"
+ }, {
+ a: Type.bfloat16(),
+ b: Type.bfloat16()
+ })).serializer;
+ const input = fory.serialize({ a: 0, b: -0 }, serializer);
+ const result = fory.deserialize(input);
+ expect(result.a.toFloat32()).toBe(0);
+ expect(result.b.toFloat32()).toBe(-0);
+ expect(1 / result.a.toFloat32()).toBe(Infinity);
+ expect(1 / result.b.toFloat32()).toBe(-Infinity);
+ });
+
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]