【问题标题】:Converting two Uint32Array values to Javascript number将两个 Uint32Array 值转换为 Javascript 数字
【发布时间】:2014-02-12 08:44:12
【问题描述】:

我从here 中找到了一个代码,该代码将 Javascript 数字转换为内部 IEEE 表示为两个 Uint32 值:

function DoubleToIEEE(f)
{
  var buf = new ArrayBuffer(8);
  (new Float64Array(buf))[0] = f;
  return [ (new Uint32Array(buf))[0] ,(new Uint32Array(buf))[1] ];
}

如何将返回值转换回 Javascript 数字?这样:

var number = -10.3245535;
var ieee = DoubleToIEEE(number)
var number_again = IEEEtoDouble(ieee);
// number and number_again should be the same (if ever possible)

【问题讨论】:

标签: javascript types numbers


【解决方案1】:

那段代码丑得要命。使用

function DoubleToIEEE(f) {
  var buf = new ArrayBuffer(8);
  var float = new Float64Array(buf);
  var uint = new Uint32Array(buf);
  float[0] = f;
  return uint;
}

如果您想要一个实际的 Array 而不是 Uint32Array(在大多数情况下应该不会产生影响),请添加一个 Array.from 调用。您还可以通过将值传递给 Float64Array 构造函数来将其简化为单线:

function DoubleToIEEE(f) {
  // use either
  return new Uint32Array(Float64Array.of(f).buffer);
  return Array.from(new Uint32Array(Float64Array.of(f).buffer));
  return Array.from(new Uint32Array((new Float64Array([f])).buffer));
}

逆向只会将输入写入uint 插槽并返回float[0] 值:

function IEEEToDouble(is) {
  var buf = new ArrayBuffer(8);
  var float = new Float64Array(buf);
  var uint = new Uint32Array(buf);
  uint[0] = is[0];
  uint[1] = is[1];
  return float[0];
}

可以简写为

function IEEEToDouble(is) {
  return (new Float64Array(Uint32Array.from(is).buffer))[0];
}

【讨论】:

  • 您能向我们这些傻瓜解释一下为什么代码很丑吗?
  • @TimoKähkönen 左侧的一次性类型数组的赋值令人困惑,最好用变量显式地写出来。两个Uint32Arrays 一个就够了似乎效率低下。所有这些都让我们很难理解数据流并找到反函数。当然,我更喜欢单表达式形式:-)
  • 感谢您的解释。我接受了你的回答。
  • 这需要哪个版本的 Javascript/ECMAscript?
  • @JasonS ES6,虽然类型化数组可以填充,并且在早于 ES6 的某些浏览器中也支持 IIRC。
【解决方案2】:

我找到了一个可能的解决方案,似乎可行:

function IEEEToDouble(f)
{
  var buffer = new ArrayBuffer(8);
  (new Uint32Array(buffer))[0] = f[0];
  (new Uint32Array(buffer))[1] = f[1];
  return new Float64Array(buffer)[0];
}

用法:

var a = DoubleToIEEE(-0.1234);
console.log(a); // [0, 3220176896]
var b = IEEEToDouble(a);
console.log(b); // -0.1234

【讨论】:

  • 如果有人希望从二进制表示字符串转换:const BinaryStringToDouble = (x) => IEEEToDouble([x.substring(32), x.substring(0, 32)].map(p => parseInt(p, 2)));
猜你喜欢
  • 2017-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多