gpt4 book ai didi

javascript - 如何在 Javascript 中将 float 转换为其二进制表示形式(IEEE 754)?

转载 作者:行者123 更新时间:2023-12-02 22:39:18 25 4
gpt4 key购买 nike

在 Javascript 中将 float 转换为其二进制表示形式的最简单方法是什么? (例如 1.0 -> 0x3F800000)。

我尝试手动执行此操作,这在一定程度上有效(对于通常的数字),但对于非常大或非常小的数字(没有范围检查)以及特殊情况(NaN、无穷大等)会失败。 :

function floatToNumber(flt)
{
var sign = (flt < 0) ? 1 : 0;
flt = Math.abs(flt);
var exponent = Math.floor(Math.log(flt) / Math.LN2);
var mantissa = flt / Math.pow(2, exponent);

return (sign << 31) | ((exponent + 127) << 23) | ((mantissa * Math.pow(2, 23)) & 0x7FFFFF);
}

我是在重新发明轮子吗?

编辑:我改进了我的版本,现在它可以处理特殊情况。

function assembleFloat(sign, exponent, mantissa)
{
return (sign << 31) | (exponent << 23) | (mantissa);
}

function floatToNumber(flt)
{
if (isNaN(flt)) // Special case: NaN
return assembleFloat(0, 0xFF, 0x1337); // Mantissa is nonzero for NaN

var sign = (flt < 0) ? 1 : 0;
flt = Math.abs(flt);
if (flt == 0.0) // Special case: +-0
return assembleFloat(sign, 0, 0);

var exponent = Math.floor(Math.log(flt) / Math.LN2);
if (exponent > 127 || exponent < -126) // Special case: +-Infinity (and huge numbers)
return assembleFloat(sign, 0xFF, 0); // Mantissa is zero for +-Infinity

var mantissa = flt / Math.pow(2, exponent);
return assembleFloat(sign, exponent + 127, (mantissa * Math.pow(2, 23)) & 0x7FFFFF);
}

我仍然不确定这是否 100% 正确,但它似乎工作得足够好。(我仍在寻找现有的实现)。

最佳答案

新技术使这一切变得简单,而且可能也更具前向兼容性。我喜欢扩展内置原型(prototype),但不是每个人都喜欢。因此,请随意将以下代码修改为经典的过程方法:

(function() {
function NumberToArrayBuffer() {
// Create 1 entry long Float64 array
return [new Float64Array([this]).buffer];
}
function NumberFromArrayBuffer(buffer) {
// Off course, the buffer must be at least 8 bytes long, otherwise this is a parse error
return new Float64Array(buffer, 0, 1)[0];
}
if(Number.prototype.toArrayBuffer) {
console.warn("Overriding existing Number.prototype.toArrayBuffer - this can mean framework conflict, new WEB API conflict or double inclusion.");
}
Number.prototype.toArrayBuffer = NumberToArrayBuffer;
Number.prototype.fromArrayBuffer = NumberFromArrayBuffer;
// Hide this methods from for-in loops
Object.defineProperty(Number.prototype, "toArrayBuffer", {enumerable: false});
Object.defineProperty(Number.prototype, "fromArrayBuffer", {enumerable: false});
})();

测试:

(function() {
function NumberToArrayBuffer() {
// Create 1 entry long Float64 array
return new Float64Array([this.valueOf()]).buffer;
}
function NumberFromArrayBuffer(buffer) {
// Off course, the buffer must be ar least 8 bytes long, otherwise this is a parse error
return new Float64Array(buffer, 0, 1)[0];
}
if(Number.prototype.toArrayBuffer) {
console.warn("Overriding existing Number.prototype.toArrayBuffer - this can mean framework conflict, new WEB API conflict or double inclusion.");
}
Number.prototype.toArrayBuffer = NumberToArrayBuffer;
Number.fromArrayBuffer = NumberFromArrayBuffer;
// Hide this methods from for-in loops
Object.defineProperty(Number.prototype, "toArrayBuffer", {enumerable: false});
Object.defineProperty(Number, "fromArrayBuffer", {enumerable: false});
})();
var test_numbers = [0.00000001, 666666666666, NaN, Infinity, -Infinity,0,-0];
console.log("Conversion symethry test: ");
test_numbers.forEach(
function(num) {
console.log(" ", Number.fromArrayBuffer((num).toArrayBuffer()));
}
);

console.log("Individual bytes of a Number: ",new Uint8Array((666).toArrayBuffer(),0,8));
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

关于javascript - 如何在 Javascript 中将 float 转换为其二进制表示形式(IEEE 754)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3096646/

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