admin管理员组文章数量:1357672
I am trying to convert some Java code into JavaScript which is needed for the application I am working on. I am stuck on one class and its methods that convert a variable of type double to long, and then long to a byte array that consists of 8 bytes representing that long number. The Java code is as follows:
public static byte[] doubleToByteArray(double number)
{
// double to long representation
long longNum = Double.doubleToLongBits(number);
// long to 8 bytes
return new byte[] {(byte)((longNum >>> 56) & 0xFF),
(byte)((longNum >>> 48) & 0xFF),
(byte)((longNum >>> 40) & 0xFF),
(byte)((longNum >>> 32) & 0xFF),
(byte)((longNum >>> 24) & 0xFF),
(byte)((longNum >>> 16) & 0xFF),
(byte)((longNum >>> 8) & 0xFF),
(byte)((longNum >>> 0) & 0xFF)};
} // end doubleToByte(.)
How would I go about doing this in JavaScript? My first issue is with the doubleToLongBits method. Does anything similar exist in JavaScript? Furthermore, how to cast a variable into a Byte?
Thank you in advance.
I am trying to convert some Java code into JavaScript which is needed for the application I am working on. I am stuck on one class and its methods that convert a variable of type double to long, and then long to a byte array that consists of 8 bytes representing that long number. The Java code is as follows:
public static byte[] doubleToByteArray(double number)
{
// double to long representation
long longNum = Double.doubleToLongBits(number);
// long to 8 bytes
return new byte[] {(byte)((longNum >>> 56) & 0xFF),
(byte)((longNum >>> 48) & 0xFF),
(byte)((longNum >>> 40) & 0xFF),
(byte)((longNum >>> 32) & 0xFF),
(byte)((longNum >>> 24) & 0xFF),
(byte)((longNum >>> 16) & 0xFF),
(byte)((longNum >>> 8) & 0xFF),
(byte)((longNum >>> 0) & 0xFF)};
} // end doubleToByte(.)
How would I go about doing this in JavaScript? My first issue is with the doubleToLongBits method. Does anything similar exist in JavaScript? Furthermore, how to cast a variable into a Byte?
Thank you in advance.
Share Improve this question edited Sep 15, 2016 at 18:29 Ciprian Tomoiagă 4,0104 gold badges45 silver badges67 bronze badges asked Sep 19, 2014 at 21:19 elberethelbereth 371 gold badge4 silver badges10 bronze badges 1- Almost a duplicate of stackoverflow./q/4414077/24874 – Drew Noakes Commented Oct 11, 2017 at 18:47
3 Answers
Reset to default 5Based on Brian's answer and on your desired representation, you can use the typed array as follows:
function doubleToByteArray(number) {
var buffer = new ArrayBuffer(8); // JS numbers are 8 bytes long, or 64 bits
var longNum = new Float64Array(buffer); // so equivalent to Float64
longNum[0] = number;
return Array.from(new Int8Array(buffer)).reverse(); // reverse to get little endian
}
function interactiveExample() {
var input = parseFloat(document.getElementById('input').value);
var output = document.getElementById('output');
var result = doubleToByteArray(input);
output.innerHTML = '[' + result[0];
for (var i = 1; i < result.length; i++) {
output.innerHTML += ', ' + result[i];
}
output.innerHTML += ']';
}
document.getElementById('input').value = Math.PI;
interactiveExample();
<input type="number" id="input" step="0.01" onchange="interactiveExample()" />
<div id="output"></div>
You can use typed arrays and an ArrayBuffer
to acplish this. I'm no expert on floating-point representation, but this should do what you need:
function doubleToByteArray(number) {
var buffer = new ArrayBuffer(4);
var intView = new Int32Array(buffer);
var floatView = new Float32Array(buffer);
floatView[0] = number;
// Debug: display binary representation of `number`
// console.log(intView[0].toString(2));
return [
(intView[0] >> 24) & 0xFF,
(intView[0] >> 16) & 0xFF,
(intView[0] >> 8) & 0xFF,
(intView[0] >> 0) & 0xFF,
(intView[1] >> 24) & 0xFF,
(intView[1] >> 16) & 0xFF,
(intView[1] >> 8) & 0xFF,
(intView[1] >> 0) & 0xFF
];
}
function interactiveExample() {
var input = parseFloat(document.getElementById('input').value);
var output = document.getElementById('output');
var result = doubleToByteArray(input);
output.innerHTML = '[' + result[0];
for (var i = 1; i < result.length; i++) {
output.innerHTML += ', ' + result[i];
}
output.innerHTML += ']';
}
document.getElementById('input').value = Math.PI;
interactiveExample();
<input type="number" id="input" step="0.01" onchange="interactiveExample()" />
<div id="output"></div>
You might look at JavaScript Exact Arithmetic. This site implements, among many things, conversion of IEEE Double to ByteArray and ByteArray to IEEE Double. IEEE Double is the representation used by Java. So, a byte array produced by this site will convert to the exact double using Java.
I have extracted the underlying code and build up the library JRS (for J R Stockton, the author of the original code). The JRS library offers two methods:
- doubleToHexString(): converts an IEEE Double to an hexadecimal string
- hexStringToDouble(): converts an hexadecimal string to an IEEE Double
The library is provided below. Please take a look at the Copyright page for fair usage.
The JRS library is as follows:
/**
* A library that allow conversion of double to byteArray and vis versa.
* Extracted from "JRS - JavaScript Exact Arithmetic - J R Stockton (See
* http://www.merlyn.demon.co.uk/js-exact.htm#DW4 and
* http://www.merlyn.demon.co.uk/contents.htm#Copy).
*/
JRS = function(){
function numberToBinString(number, binStringLength) {
var A = [], T = null; // number>=0
while (binStringLength--) {
T = number % 2;
A[binStringLength] = T;
number -= T;
number /= 2;
}
return A.join("");
}
function HexFn(fourBitsBinString) {
return parseInt(fourBitsBinString, 2).toString(16);
}
function binStringToHexString(binString) {
return binString.replace(/(\d{4})/g, HexFn );
}
function hexStringToBinString(hexString) {
var binString = "";
for(var i=0; i< hexString.length-1; i+=2) {
binString += numberToBinString(parseInt(hexString.substr(i, 2), 16), 8);
}
return binString;
}
function SngFwd(Sg, Ex, Mt) {
var B = {};
Mt = Math.pow(2, 23) * Mt + 0.5; // round
B.a = 0xFF & Mt;
B.b = 0xFF & (Mt >> 8);
B.c = 0x7F & (Mt >> 16) | (Ex & 1) << 7;
B.d = Sg << 7 | (Ex >> 1);
return B;
}
function DblFwd(Sg, Ex, Mt) {
var B = {};
Mt = Math.pow(2, 52) * Mt;
B.a = 0xFFFF & Mt;
B.b = 0xFFFF & (Mt >> 16);
Mt /= Math.pow(2, 32); // Integers are only 32-bit
B.c = 0xFFFF & Mt;
B.d = Sg << 15 | Ex << 4 | 0x000F & (Mt >> 16);
return B;
}
function CVTFWD(NumW, Qty) { // Function now without side-effects
var Sign = null, Expo = null, Mant = null, Bin = null, nb01 = ""; // , OutW = NumW/4
var Inf = {
32 : {d: 0x7F, c: 0x80, b: 0, a : 0},
64 : {d: 0x7FF0, c: 0, b: 0, a : 0}
};
var ExW = {32: 8, 64: 11}[NumW], MtW = NumW - ExW - 1;
if (isNaN(Qty)) {
Bin = Inf[NumW];
Bin.a = 1;
Sign = false;
Expo = Math.pow(2, ExW) - 1;
Mant = Math.pow(2, -MtW);
}
if (!Bin) {
Sign = Qty < 0 || 1 / Qty < 0; // OK for +-0
if (!isFinite(Qty)) {
Bin = Inf[NumW];
if (Sign)
Bin.d += 1 << (NumW / 4 - 1);
Expo = Math.pow(2, ExW) - 1;
Mant = 0;
}
}
if (!Bin) {
Expo = {32: 127, 64: 1023}[NumW];
Mant = Math.abs(Qty);
while (Mant >= 2) {
Expo++;
Mant /= 2;
}
while (Mant < 1 && Expo > 0) {
Expo--;
Mant *= 2;
}
if (Expo <= 0) {
Mant /= 2;
nb01 = "Zero or Denormal";
}
if (NumW == 32 && Expo > 254) {
nb01 = "Too big for Single";
Bin = {
d : Sign ? 0xFF : 0x7F,
c : 0x80,
b : 0,
a : 0
};
Expo = Math.pow(2, ExW) - 1;
Mant = 0;
}
}
if (!Bin)
Bin = {32: SngFwd, 64: DblFwd}[NumW](Sign, Expo, Mant);
Bin.sgn = +Sign;
Bin.exp = numberToBinString(Expo, ExW);
Mant = (Mant % 1) * Math.pow(2, MtW);
if (NumW == 32)
Mant = Math.floor(Mant + 0.5);
Bin.mnt = numberToBinString(Mant, MtW);
Bin.nb01 = nb01;
return Bin;
}
function CVTREV(BinStr) {
var ExW = {32: 8,64: 11}[BinStr.length];
var M = BinStr.match(new RegExp("^(.)(.{" + ExW + "})(.*)$"));
// M1 sign, M2 exponent, M3 mantissa
var Sign = M[1] == "1" ? -1 : +1;
if (!/0/.test(M[2])) { // NaN or Inf
var X = /1/.test(M[3]) ? NaN : Sign / 0;
throw new Error("Max Coded " + M[3] + " " + X.toString());
}
var Denorm = +M[2] == 0;
if (Denorm) {
console.log("Zero or Denormal");
}
var Expo = parseInt(M[2], 2) - Math.pow(2, ExW - 1) + 1;
var Mant = parseInt(M[3], 2) / Math.pow(2, M[3].length) + !Denorm;
return Sign * Mant * Math.pow(2, Expo + Denorm);
}
this.doubleToHexString = function( /* double */d, /* int */size) {
var NumW = size;
var Qty = d;
with (CVTFWD(NumW, Qty)) {
return binStringToHexString(sgn + exp + mnt);
}
};
this.hexStringToDouble = function (/*String*/hexString, /*int*/size) {
var NumW = size ;
var binString = hexStringToBinString(hexString) ;
var X = new RegExp("^[01]{" + NumW + "}$");
if (!X.test(binString)) {
alert(NumW + " bits 0/1 needed");
return;
}
return CVTREV(binString);
};
};
本文标签: binaryDouble to Byte array conversion in javascriptStack Overflow
版权声明:本文标题:binary - Double to Byte array conversion in javascript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744068927a2585527.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论