好吧所以我是一个相当烦人的情况,我无法访问类型化的数组,如Float32Array,但仍然需要能够将Javascript数转换为字节。现在,我可以处理的整数很好,但我不知道如何为浮点值做。
我已经解决了以相反方式执行此操作的问题(将字节转换为浮点数),但是关于从float转换为字节的文档非常缺乏,因为大多数语言只是让您读取指针或具有用于处理的公共类它
理想情况下,我希望能够将浮点数转换为4字节和8字节表示,并选择使用哪一个。但是,可以简单地取一个数字并将其吐出为8字节的代码仍然很棒,因为我可以从那里自己想出32位版本。
答案 0 :(得分:7)
好的,所以我实际想出来了,所以我将分享我的单精度和双精度的解决方案。现在我无法保证它们符合100%标准,但它们不需要循环,看起来效果很好:
单精度(给定十进制值输出带有二进制表示的单个32位大端整数):
function toFloat32(value) {
var bytes = 0;
switch (value) {
case Number.POSITIVE_INFINITY: bytes = 0x7F800000; break;
case Number.NEGATIVE_INFINITY: bytes = 0xFF800000; break;
case +0.0: bytes = 0x40000000; break;
case -0.0: bytes = 0xC0000000; break;
default:
if (Number.isNaN(value)) { bytes = 0x7FC00000; break; }
if (value <= -0.0) {
bytes = 0x80000000;
value = -value;
}
var exponent = Math.floor(Math.log(value) / Math.log(2));
var significand = ((value / Math.pow(2, exponent)) * 0x00800000) | 0;
exponent += 127;
if (exponent >= 0xFF) {
exponent = 0xFF;
significand = 0;
} else if (exponent < 0) exponent = 0;
bytes = bytes | (exponent << 23);
bytes = bytes | (significand & ~(-1 << 23));
break;
}
return bytes;
};
双精度(给定十进制值以big-endian顺序输出两个32位整数和二进制表示):
function toFloat64(value) {
if ((byteOffset + 8) > this.byteLength)
throw "Invalid byteOffset: Cannot write beyond view boundaries.";
var hiWord = 0, loWord = 0;
switch (value) {
case Number.POSITIVE_INFINITY: hiWord = 0x7FF00000; break;
case Number.NEGATIVE_INFINITY: hiWord = 0xFFF00000; break;
case +0.0: hiWord = 0x40000000; break;
case -0.0: hiWord = 0xC0000000; break;
default:
if (Number.isNaN(value)) { hiWord = 0x7FF80000; break; }
if (value <= -0.0) {
hiWord = 0x80000000;
value = -value;
}
var exponent = Math.floor(Math.log(value) / Math.log(2));
var significand = Math.floor((value / Math.pow(2, exponent)) * Math.pow(2, 52));
loWord = significand & 0xFFFFFFFF;
significand /= Math.pow(2, 32);
exponent += 1023;
if (exponent >= 0x7FF) {
exponent = 0x7FF;
significand = 0;
} else if (exponent < 0) exponent = 0;
hiWord = hiWord | (exponent << 20);
hiWord = hiWord | (significand & ~(-1 << 20));
break;
}
return [hiWord, loWord];
};
对复制/粘贴中的任何错误表示道歉,代码也省略了对字节序的任何处理,尽管它很容易添加。
感谢所有人发布建议,但我最终主要依靠自己搞清楚,因为我想避免尽可能多地循环以获得速度;它仍然不是非常快,但它会做=)
答案 1 :(得分:1)
请参阅BinaryParser.encodeFloat here。
答案 2 :(得分:1)
您可以像http://ysangkok.github.io/IEEE-754/index.xhtml那样使用IEEE 754的JavaScript实现。它使用Emscripten和gmp.js。