转换32位无符号;“真正的”;javascript的数据类型(拆分为两个16位有符号字)

转换32位无符号;“真正的”;javascript的数据类型(拆分为两个16位有符号字),javascript,node.js,floating-point,Javascript,Node.js,Floating Point,我将一个32位无符号“实”值拆分为两个16位有符号“字”(0-65535)值。如何将它们转换为javascript数字 例如: 价值1:18584 价值2:18081 实际值为:20644.3 我正在搜索像back2Real(1858418081)这样的函数,它返回20644.3。这些值来自modbus应用程序(NodeJS/modbus_堆栈)。SPS/modbus服务器发送一个分为两个字寄存器的“真实”值 问候,, root66使用此函数转换为JavaScript数字。由于JavaScrip

我将一个32位无符号“实”值拆分为两个16位有符号“字”(0-65535)值。如何将它们转换为javascript数字

例如: 价值1:18584 价值2:18081 实际值为:20644.3

我正在搜索像back2Real(1858418081)这样的函数,它返回20644.3。这些值来自modbus应用程序(NodeJS/modbus_堆栈)。SPS/modbus服务器发送一个分为两个字寄存器的“真实”值

问候,,
root66使用此函数转换为JavaScript数字。由于JavaScript使用双精度而不是单精度数字,因此可能会出现一些舍入

function back2Real(low, high){
  var fpnum=low|(high<<16)
  var negative=(fpnum>>31)&1;
  var exponent=(fpnum>>23)&0xFF
  var mantissa=(fpnum&0x7FFFFF)
  if(exponent==255){
   if(mantissa!=0)return Number.NaN;
   return (negative) ? Number.NEGATIVE_INFINITY :
         Number.POSITIVE_INFINITY;
  }
  if(exponent==0)exponent++;
  else mantissa|=0x800000;
  exponent-=127
  var ret=(mantissa*1.0/0x800000)*Math.pow(2,exponent)
  if(negative)ret=-ret;
  return ret;
}
功能back2Real(低、高){
var fpnum=低|(高31)&1;
变量指数=(fpnum>>23)&0xFF
变量尾数=(fpnum和0x7FFFFF)
如果(指数=255){
如果(尾数!=0)返回Number.NaN;
返回值(负数)?数字负无穷大:
正无穷大;
}
如果(指数==0)指数++;
else尾数|=0x800000;
指数-=127
var ret=(尾数*1.0/0x800000)*数学功率(2,指数)
如果(负)ret=-ret;
返回ret;
}
以下函数将JavaScript数字转换为32位IEEE浮点数,并拆分为低位和高位字:

function real2Back(value){
  if(isNaN(value))return [0,0xFFC0]
  if(value==Number.POSITIVE_INFINITY || value>=3.402824e38)
    return [0,0x7F80]
  if(value==Number.NEGATIVE_INFINITY || value<=-3.402824e38)
    return [0,0xFF80]
  var negative=(value<0)
  var p,x,mantissa
  value=Math.abs(value)
  if(value==2.0)return [0,0x4000]
  else if(value>2.0){
   // positive exponent
   for(var i=128;i<255;i++){
     p=Math.pow(2,i+1-127)
     if(value<p){
      x=Math.pow(2,i-127)
      mantissa=Math.round((value*1.0/x)*8388608)
      mantissa&=0x7FFFFF
      value=mantissa|(i<<23)
      if(negative)value|=(1<<31)
      return [value&0xFFFF,(value>>16)&0xFFFF]
     }
   }
   // return infinity
   return negative ? [0,0xFF80] : [0,0x7F80]
  } else {
   for(var i=127;i>0;i--){
   // negative exponent
     p=Math.pow(2,i-127)
     if(value>p){
      x=p
      mantissa=Math.round(value*8388608.0/x)
      mantissa&=0x7FFFFF
      value=mantissa|(i<<23)
      if(negative)value|=(1<<31)
      return [value&0xFFFF,(value>>16)&0xFFFF]
     }
   }
   // subnormal
   x=Math.pow(2,i-126)
   mantissa=Math.round((value*8388608.0/x))
   if(mantissa>0x7FFFFF)mantissa=0x800000
   value=mantissa
   if(negative)value|=(1<<31)
   return [value&0xFFFF,(value>>16)&0xFFFF]   
  }
}
函数real2Back(值){
if(isNaN(值))返回[0,0xFFC0]
如果(值==Number.POSITIVE||value>=3.402824e38)
返回[0,0x7F80]
如果(value==Number.NEGATIVE | | | value,则可以使用新的(ish)类型数组功能来简化此过程

function uint16ToFloat32(low, high) {
  var buffer = new ArrayBuffer(4);
  var intView = new Uint16Array(buffer);
  var floatView = new Float32Array(buffer);

  intView[0] = low;
  intView[1] = high;
  return floatView[0];
}

function float32ToUint16(value) {
  var buffer = new ArrayBuffer(4);
  var intView = new Uint16Array(buffer);
  var floatView = new Float32Array(buffer);

  floatView[0] = value;
  return [intView[0], intView[1]];
}

console.log("Converted ints to", uint16ToFloat32(18584, 18081));
console.log("Converted float to", float32ToUint16(20644.297));
这是一份记录:

$ node floatsplit.js
Converted ints to 20644.296875
Converted float to [ 18584, 18081 ]
$
缓冲区通常是数组。 稍微更改了第一个函数以接受数组,而不是低和高。 很重要的一点是,它对于没有交换的Big-Endian格式是有效的

function uint16ToFloat32(uint16array) {
    var buffer = new ArrayBuffer(4);
    var intView = new Uint16Array(buffer);
    var floatView = new Float32Array(buffer);

    intView[0] = uint16array[0];
    intView[1] = uint16array[1];
    return floatView[0];
  }

我对“真实”的含义有点困惑数字的格式是什么?IEEE浮点数?它是一个32位IEEE浮点数,第一个参数是低16位,第二个参数是高16位。我正在制作一个JavaScript函数来简单回答这个问题。反向函数是什么,将32位IEEE浮点数放入并获取低16位和高16位输出?我已经在我的答案中添加了这个函数。这个答案不能解释endianness。