0

I need to replicate my hashing algorithm in JavaScript that i have in C#. It requires that i convert a double to a byte array but i can't seem to figure out how the c# method BitConvert.GetBytes() is producing its data. I put in the number 448502400.0 and it outputs 0,0,0,128,154,187,186,65 aka (0x809ABBBA41). If i turn the number to a long before i run it through getBytes() it produces the correct result. 128,154,187,26,0,0,0

How would i go about turning that number (448502400) into a byte[] containing 0x809ABBBA41 in JavaScript where numbers aren't stored the same way?

Just for reference it is NOT possible to change the C# code anymore.

EDIT: Here are the two methods (shamelessly stolen from other questions) to turn a number into bytes. But this generates the long represenation and not the double representation i'm after.

 var timestampBytes = [0,0,0,0,0,0,0,0];
    var i = 8;
    do {
        timestampBytes[--i] = timestamp & (255);
        timestamp = timestamp >> 8;
    } while (i)

And this one

    function numberToByte(/*long*/long) {
    // we want to represent the input as a 8-bytes array
    var byteArray = [0, 0, 0, 0, 0, 0, 0, 0];

    for (var index = 0; index < byteArray.length; index++) {
        var byte = long & 0xff;
        byteArray[index] = byte;
        long = (long - byte) / 256;
    }

    return byteArray;
}

EDIT: My question has been answered in a round about way in the attached answer.

This is my working code which will generate a byte[] which formats to the same byte[] as BitConvert.GetBytes(double)

var bytes = [];
var view = new DataView(new ArrayBuffer(8));
    view.setFloat64(0, numberToTurnToDouble);
    bytes = bytes.concat(numberToByteArray(view.getUint32(4))); // The second half of the new number
    bytes = bytes.concat(numberToByteArray(view.getUint32(0))); // The first half of the number

// Converts an int32 number to its byte array representation
function numberToByteArray(int32) {
    var byteArray = [0, 0, 0, 0];
    for (var index = 0; index < byteArray.length; index++) {
        var byte = int32 & 0xff;
        byteArray[index] = byte;
        int32 = (int32 - byte) / 256;
    }
    return byteArray;
}
Chris Rice
  • 728
  • 2
  • 9
  • 32
  • 2
    Well yes, the representations of `double` and `long` are very different. That shouldn't be a surprise. It's not really clear what you're trying to achieve here, to be honest... is the value in JavaScript always definitely an integer, and you're trying to reproduce the `BitConverter.GetBytes(long)` behaviour? – Jon Skeet Mar 20 '15 at 14:15
  • What determines 'correct result' ? – H H Mar 20 '15 at 14:16
  • @JonSkeet I am attempting to replicate the behavior in javascript. I need to put in the number 448502400 and get the same output. I understand that they are different as they are packed differently internally. The value will never have a decimal place and i'm trying to replicate the BitConvert.GetBytes(double) behavior. – Chris Rice Mar 20 '15 at 14:27
  • @HenkHolterman Correct result in this case is a number that i can throw into a calculator and actually turn back into the original number. I didn't understand that a 0 precision double value will still be converted with all the extra double junk instead of a clean flat representation. – Chris Rice Mar 20 '15 at 14:29
  • When it needs to be represented as a long, it's weird that it ends up in a double at all. But does truncating all doubles to long solve your problem? – H H Mar 20 '15 at 14:32
  • @HenkHolterman Truncating to a long would have worked, but i am unable to change the C# code anymore which means i have to somehow generate the same output (0x809ABBBA41) from the javascript number 448502400. – Chris Rice Mar 20 '15 at 14:37
  • 1
    @ChrisRice Have you tried to apply http://stackoverflow.com/questions/24564460/how-to-apply-bitwise-operations-to-the-actual-ieee-754-representation-of-js-numb? It looks promising. – Eugene Podskal Mar 20 '15 at 14:55
  • 1
    @ChrisRice: A double that contains the number 1234 and a long that contains that number are completely different; your assumption that they would have a similar structure is completely unwarranted. A double is a fractional number 1.[binary digits here] multiplied by an integral power of two; it's inner structure represents those binary digits and the power. For a C# program that shows you the inner structure of a double, see http://ericlippert.com/2011/02/17/looking-inside-a-double/. Implementing a similar program in JavaScript is an interesting challenge. – Eric Lippert Mar 20 '15 at 17:12

0 Answers0