Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 042337a

Browse files
authored
Merge pull request #79 from msgpack/prefer-float32
implement `forceFloat32` to encode numbers in float32 instead of float64
2 parents c4a1ef5 + 91eeb98 commit 042337a

File tree

4 files changed

+50
-5
lines changed

4 files changed

+50
-5
lines changed

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ extensionCodec | ExtensionCodec | `ExtensinCodec.defaultCodec`
114114
maxDepth | number | `100`
115115
initialBufferSize | number | `2048`
116116
sortKeys | boolean | false
117+
forceFloat32 | boolean | false
117118

118119
### `decode(buffer: ArrayLike<number> | ArrayBuffer, options?: DecodeOptions): unknown`
119120

‎src/Encoder.ts‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class Encoder {
1818
readonly maxDepth = DEFAULT_MAX_DEPTH,
1919
readonly initialBufferSize = DEFAULT_INITIAL_BUFFER_SIZE,
2020
readonly sortKeys = false,
21+
readonly forceFloat32 = false,
2122
) {}
2223

2324
encode(object: unknown, depth: number): void {
@@ -118,8 +119,16 @@ export class Encoder {
118119
}
119120
}
120121
} else {
121-
this.writeU8(0xcb);
122-
this.writeF64(object);
122+
// non-integer numbers
123+
if (this.forceFloat32) {
124+
// float 32
125+
this.writeU8(0xca);
126+
this.writeF32(object);
127+
} else {
128+
// float 64
129+
this.writeU8(0xcb);
130+
this.writeF64(object);
131+
}
123132
}
124133
}
125134

@@ -345,9 +354,14 @@ export class Encoder {
345354
this.pos += 4;
346355
}
347356

357+
writeF32(value: number) {
358+
this.ensureBufferSizeToWrite(4);
359+
this.view.setFloat32(this.pos, value);
360+
this.pos += 4;
361+
}
362+
348363
writeF64(value: number) {
349364
this.ensureBufferSizeToWrite(8);
350-
351365
this.view.setFloat64(this.pos, value);
352366
this.pos += 8;
353367
}

‎src/encode.ts‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ export type EncodeOptions = Partial<
77
maxDepth: number;
88
initialBufferSize: number;
99
sortKeys: boolean;
10+
11+
/**
12+
* If `true`, non-integer numbers are encoded in float32, not in float64 (the default).
13+
*
14+
* Only use it if precisions don't matter.
15+
*/
16+
forceFloat32: boolean;
1017
}>
1118
>;
1219

@@ -19,7 +26,13 @@ const defaultEncodeOptions = {};
1926
* The returned buffer is a slice of a larger `ArrayBuffer`, so you have to use its `#byteOffset` and `#byteLength` in order to convert it to another typed arrays including NodeJS `Buffer`.
2027
*/
2128
export function encode(value: unknown, options: EncodeOptions = defaultEncodeOptions): Uint8Array {
22-
const encoder = new Encoder(options.extensionCodec, options.maxDepth, options.initialBufferSize, options.sortKeys);
29+
const encoder = new Encoder(
30+
options.extensionCodec,
31+
options.maxDepth,
32+
options.initialBufferSize,
33+
options.sortKeys,
34+
options.forceFloat32,
35+
);
2336
encoder.encode(value, 1);
2437
return encoder.getUint8Array();
2538
}

‎test/encode.test.ts‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,28 @@ import { encode, decode } from "@msgpack/msgpack";
33

44
describe("encode", () => {
55
context("sortKeys", () => {
6-
it("canonicalize encoded binaries", () => {
6+
it("canonicalizes encoded binaries", () => {
77
assert.deepStrictEqual(encode({ a: 1, b: 2 }, { sortKeys: true }), encode({ b: 2, a: 1 }, { sortKeys: true }));
88
});
99
});
1010

11+
context("forceFloat32", () => {
12+
it("encodes numbers in float64 wihout forceFloat32", () => {
13+
assert.deepStrictEqual(encode(3.14), Uint8Array.from([0xcb, 0x40, 0x9, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f]));
14+
});
15+
16+
it("encodes numbers in float32 when forceFloate32=true", () => {
17+
assert.deepStrictEqual(encode(3.14, { forceFloat32: true }), Uint8Array.from([0xca, 0x40, 0x48, 0xf5, 0xc3]));
18+
});
19+
20+
it("encodes numbers in float64 with forceFloat32=false", () => {
21+
assert.deepStrictEqual(
22+
encode(3.14, { forceFloat32: false }),
23+
Uint8Array.from([0xcb, 0x40, 0x9, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f]),
24+
);
25+
});
26+
});
27+
1128
context("ArrayBuffer as buffer", () => {
1229
const buffer = encode([1, 2, 3]);
1330
const arrayBuffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteLength);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /