gpt4 book ai didi

javascript - 如何有效地序列化 64 位 float 以便字节数组保留自然数字顺序?

转载 作者:太空宇宙 更新时间:2023-11-03 14:30:04 25 4
gpt4 key购买 nike

我正在从事的项目要求我将 javascript 数字( double )存储为数据库表中的 BLOB 主键(不能使用数据库 native float 数据类型)。所以基本上我需要以这样的方式将数字序列化为字节数组:

1 - 字节数组的长度为 8(这是序列化 double 通常需要的长度)

2 - 字节数组必须保持自然顺序,这样数据库才能透明地对索引 b 树中的行进行排序。

我正在寻找一个接受数字并返回表示字节的数字数组的简单函数。我更喜欢用 javascript 编写的函数,但也接受使用 java、C、C#、C++ 或 python 编写的答案。

最佳答案

为了满足排序需求,您需要:

  1. 使用大端表示
  2. 如果符号位为 0,则将其翻转为 1。检查实际位 - 将原始数字与 0 进行比较,在特殊情况下(例如负零)会给出不同的结果。
  3. 如果符号位为1,翻转所有位

Python 3 代码:

import struct

def invert(x):
return bytes(c ^ 255 for c in x)

def tobin(x):
binx = struct.pack('>d', x)
if binx > b'\x80': #negative
return invert(binx)
else:
return struct.pack('>d', -x)

data = [float('-inf'), -100.0, -2.0, -.9, -.1, -0.0,
0.0, .1, .9, 2.0, 100.0, float('inf'), float('nan')]

print(sorted(data, key=tobin))
#[-inf, -100.0, -2.0, -0.9, -0.1, -0.0, 0.0, 0.1, 0.9, 2.0, 100.0, inf, nan]

在 Python 2 上,将 invert 更改为:

def invert(x):
return "".join(chr(ord(c) ^ 255) for c in x)

作为引用,这里是等效的 node.js,它已经通过“Buffer”类实现了 Big Endian 序列化功能:

function serialize(n) {
var buffer = new Buffer(8);
var l = buffer.length;
buffer.writeDoubleBE(n, 0);
if (buffer[0] < 0x80) {
buffer[0] ^= 0x80;
} else {
for (var i = 0; i < l; i++)
buffer[i] ^= 0xff;
}
return buffer
}

function deserialize(buffer) {
var l = buffer.length;
// 0x80 is the most significant byte of the representation of
// the first positive number(Number.MIN_VALUE)
if (buffer[0] >= 0x80) {
buffer[0] ^= 0x80;
} else {
for (var i = 0; i < l; i++)
buffer[i] ^= 0xff;
}
return buffer.readDoubleBE(0);
}

关于javascript - 如何有效地序列化 64 位 float 以便字节数组保留自然数字顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12932663/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com