2016-07-16 34 views
0

我需要將座標值,這是一個浮點數,轉換爲protobuf對象發送到服務器 問題是我需要將其轉換爲fixed64對象, 這是64位長,JavaScript不支持這麼長的數字。轉換一個座標值到一個fixed64 protobuf對象

我正在使用this庫創建我的protobuf緩衝區。 我已經找到了工作的Python代碼段剷球同樣的問題

def f2i(float): 
    return struct.unpack('<Q', struct.pack('<d', float))[0] 

這裏使用了結構庫,而且基本上浮動轉換成二進制,然後回長。 我需要得到相同的輸出

所以51.366805將成爲4632426052430037296

失去精確一點點是不是最大的問題,我只需要值

回答

1

至於你提到的JS沒有按轉換不支持64位整數,所以你將無法獲得相同的輸出。您可以得到最接近的兩個32位整數,它們表示相同的64位整數,根據您的Protobuf庫期望的輸入類型,這可能也可能不起作用。

我建議看看在接受的答案this question toFloat64()函數。

下面是一個略微簡化的版本:

function toFloat64(value) { 
    var hiWord = 0, loWord = 0; 

    if (value <= -0.0) { 
     hiWord = 0x80000000; 
     value = -value; 
    } 

    var exponent = Math.floor(Math.log(value)/Math.log(2)); 
    var significand = Math.floor((value/Math.pow(2, exponent)) * Math.pow(2, 52)); 

    loWord = significand & 0xFFFFFFFF; 
    significand /= Math.pow(2, 32); 

    exponent += 1023; 
    if (exponent >= 0x7FF) { 
     exponent = 0x7FF; 
     significand = 0; 
    } else if (exponent < 0) exponent = 0; 

    hiWord = hiWord | (exponent << 20); 
    hiWord = hiWord | (significand & ~(-1 << 20)); 

    return [hiWord, loWord]; 
} 

讓我們試試看:

var res = toFloat64(51.366805), 
    hexHi = ('0000000' + res[0].toString(16)).substr(-8, 8), 
    hexLo = ('0000000' + res[1].toString(16)).substr(-8, 8); 

console.log('32-bit high word = 0x' + hexHi); 
console.log('32-bit low word = 0x' + hexLo); 
console.log('64-bit result = 0x' + hexHi + hexLo); 

輸出:

32-bit high word = 0x4049aef3 
32-bit low word = 0x775b8130 
64-bit result = 0x4049aef3775b8130 

其中0x4049aef3775b8130確實4632426052430037296一次轉換回十進制。

如果你真的需要一個原子JS號碼,最後的選擇是把它與53位精度轉換回整數

var int53 = parseInt(hexHi + hexLo, 16); 
console.log(int53); 

輸出:

4632426052430037000 
相關問題