简体   繁体   English

将32位无符号“实数”数据类型(分成两个16位有符号字)转换为javascript

[英]Convert 32bit unsigned “Real” data type (splitted into two 16 bit signed words) to javascript

i've got a 32 bit unsigned "Real" value splitted into two 16 Bit signed "Word" (0-65535) values. 我有一个32位无符号“Real”值,分为两个16位有符号“Word”(0-65535)值。 How do I convert them to a javascript number? 如何将它们转换为javascript编号?

Example: Value1: 18584 Value2: 18081 The Real value is: 20644.3 示例:Value1:18584 Value2:18081 Real值为:20644.3

I'm searching for a function like back2Real(18584, 18081) which returns 20644.3. 我正在寻找像back2Real(18584,18081)这样的函数,它返回20644.3。 The values come from a modbus application (NodeJS / modbus_stack). 值来自modbus应用程序(NodeJS / modbus_stack)。 The SPS/modbus server sends a "Real" value splitted into two Word-registers. SPS / modbus服务器发送分为两个字寄存器的“Real”值。

Regards, root66 问候,root66

You can use the new(ish) typed array functionality to simplify this. 您可以使用新的(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));

Here's a transcript: 这是一个成绩单:

$ node floatsplit.js
Converted ints to 20644.296875
Converted float to [ 18584, 18081 ]
$

Use this function to convert to JavaScript numbers. 使用此函数可转换为JavaScript数字。 Since JavaScript uses double precision rather than single precision numbers, some rounding may occur. 由于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;
}

The following function converts JavaScript numbers into 32-bit IEEE floating point numbers, split into the low and high word: 以下函数将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]   
  }
}

I hope this helps. 我希望这有帮助。 The code is in the public domain. 代码属于公共领域。

Buffers normally arrays. 缓冲区通常是数组。 Slightly changed first function to accept array, not low and high. 略微改变了第一个接受数组的功能,而不是低和高。 It's important to say it's valid for Big Endian format without swap. 重要的是要说它对没有交换的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];
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将两个16位整数(高位字/低位字)转换为32位浮点数? - How To Convert Two 16bit Integer (High Word / Low Word) into 32bit Float? 在javascript中将32位整数转换为4字节的数据 - Convert a 32bit integer into 4 bytes of data in javascript 在JavaScript中将两个字节转换为带符号的16位整数 - Convert two bytes into signed 16 bit integer in JavaScript 在JavaScript中对32位有符号整数数组进行排序的最快方法? - Fastest way to sort 32bit signed integer arrays in JavaScript? 在 Javascript 中读取带符号的 16 位数据 - Reading signed 16 bit data in Javascript 使用无符号32位整数的javascript中的位移位/类型转换? - Bit shifting/type casting in javascript with unsigned 32 bit integers? 在JavaScript中将两个16位数组合并转换为一个32位数(浮点数) - Combine and convert two 16 bit numbers into one 32 bit number (float) in JavaScript javascript sharedArrayBuffer 和按位运算返回 32 位而不是 16 位数字 - javascript sharedArrayBuffer and bitwise operations returning a 32bit instead of 16bit number 在JavaScript中将float转换为32位十六进制字符串 - Convert float to 32bit hex string in JavaScript 如何在 javascript 中将 dec 转换为 32 位 int? - How to convert a dec to a 32bit int in javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM