![](/img/trans.png)
[英]How To Convert Two 16bit Integer (High Word / Low Word) into 32bit Float?
[英]Convert 32bit unsigned “Real” data type (splitted into two 16 bit signed words) to javascript
我有一個32位無符號“Real”值,分為兩個16位有符號“Word”(0-65535)值。 如何將它們轉換為javascript編號?
示例:Value1:18584 Value2:18081 Real值為:20644.3
我正在尋找像back2Real(18584,18081)這樣的函數,它返回20644.3。 值來自modbus應用程序(NodeJS / modbus_stack)。 SPS / modbus服務器發送分為兩個字寄存器的“Real”值。
問候,root66
您可以使用新的(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 ]
$
使用此函數可轉換為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;
}
以下函數將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]
}
}
我希望這有幫助。 代碼屬於公共領域。
緩沖區通常是數組。 略微改變了第一個接受數組的功能,而不是低和高。 重要的是要說它對沒有交換的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.