Javascript 如何高效地序列化64位浮点,以便字节数组保持自然的数字顺序?
我正在处理的项目要求我将javascript数字(双倍)作为BLOB主键存储在数据库表中(不能使用数据库本机浮点数据类型)。因此,基本上我需要将数字序列化为字节数组,以便: 1-字节数组的长度为8(这是序列化双精度通常需要的长度) 2-字节数组必须保持自然顺序,以便数据库对索引b树中的行进行透明排序 我正在寻找一个简单的函数,它接受一个数字并返回一个表示字节的数字数组。我更喜欢用JavaScript编写的函数,但是在爪哇、C、C、C++或Python中的答案也会被接受。< P>提供了一个API,用于在8字节容器中写入双倍。 使用方法Javascript 如何高效地序列化64位浮点,以便字节数组保持自然的数字顺序?,javascript,python,c,serialization,natural-sort,Javascript,Python,C,Serialization,Natural Sort,我正在处理的项目要求我将javascript数字(双倍)作为BLOB主键存储在数据库表中(不能使用数据库本机浮点数据类型)。因此,基本上我需要将数字序列化为字节数组,以便: 1-字节数组的长度为8(这是序列化双精度通常需要的长度) 2-字节数组必须保持自然顺序,以便数据库对索引b树中的行进行透明排序 我正在寻找一个简单的函数,它接受一个数字并返回一个表示字节的数字数组。我更喜欢用JavaScript编写的函数,但是在爪哇、C、C、C++或Python中的答案也会被接受。< P>提供了一个API,
getFloat64()
和setFloat64()
上面提到的链接显然没有实现setFloat64(),但至少提供了一些透视图,说明了编写这样一个函数所涉及的内容
对于浏览器来说,最好、最快的方法无疑是从类型化数组中使用Float64Array(并可能修复字节顺序)。显而易见的答案是取消不能使用本机数据库类型的限制。我看不出有什么意义。它仍然是8个字节,可以为您进行排序,无需进行任何进一步的调查、工作、实验、测试等。要满足排序要求,您需要:
导入结构
def反转(x):
返回字节(c^255表示x中的c)
def托宾(x):
binx=struct.pack('>d',x)
如果binx>b'\x80':#负
返回仰拱(binx)
其他:
返回结构包('>d',-x)
数据=[float('-inf'),-100.0,-2.0,-.9,-.1,-0.0,
0.0、.1、.9、2.0、100.0、浮点('inf')、浮点('nan')]
打印(已排序(数据,键=托宾))
#[-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上,将反转为:
def反转(x):
返回“”。为x中的c加入(chr(ord(c)^255)
以下是等效的node.js,它已经通过“Buffer”类实现了一个Big-Endian序列化函数,以供参考:
函数序列化(n){
var缓冲区=新缓冲区(8);
var l=缓冲区长度;
buffer.writeDoubleBE(n,0);
if(缓冲区[0]<0x80){
缓冲区[0]^=0x80;
}否则{
对于(变量i=0;i=0x80){
缓冲区[0]^=0x80;
}否则{
对于(变量i=0;i
如何将JavaScript链接到数据库?在那一层进行转换不是更有意义吗?如果你知道以上提到的任何一种语言的答案,我也会接受:)为什么是BLOB?为什么不直接使用FP值作为主键呢?为什么不能使用原生DB类型?好吧,这是我正在进行的项目的一个不可协商的要求。我要求的是一个javascript函数:)顺便说一句,这个函数将在服务器上使用,而不是在浏览器中使用,除非它满足订购要求,但它似乎不满足,这不是对这个问题的回答。@EJP:为什么?在big-endian格式中,双精度是按字典顺序排列的。@AkiSuihkonen:IEEE浮点几乎是按字典顺序排列的,但不完全是。Janne的回答完成了交易。是的,再加上一点切换。但在代表任务最后1%的javascript中……我多么希望我能轻松地更改我所从事的所有项目的需求:)实际上,这有许多有效的用例。例如Azure表存储中的键、AWS DynamoDB、AWS S3,以及可能大量的其他NoSQL解决方案。它们通常只有字符串作为键,但按字典顺序排列……回答得好,我编辑了它以添加javascript版本供将来参考javascript解决方案无法序列化和反序列化NaN
和-0
。它正确处理+0
。我看不出有什么好的NaN
,但我认为需要正确的序列化/反序列化:)@jonasfj谢谢。现在看起来正确吗?Python版本也将-0排序到错误的位置。