[英]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.