isaiasmac
isaiasmac

Reputation: 316

Java number precision in Javascript

I have the following code in Java that convert Hex values to Long numbers, in the example I used the value: 'B4EEB49B04C0'

public static long HexStr2Long(String value)
{
    value = value.toUpperCase();
    long result = 0;
    for (int i = 0; i < value.length(); i++)
    {
        int x = value.length() - i - 1;
        char ch = value.charAt(i);
        result += keys.indexOf(ch) * Pow(exponent, x);
    }
    return result;
}

public static long Pow(long baseNo, long x)
{
    long value = 1;
    while (x > 0)
    {
        value = value * baseNo;
        x--;
    }
    return value;
}

public static void main(String[] args) {
    long result = HexStr2Long("B4EEB49B04C0");
    System.out.print("resultado: "+result+"\n");
}

The result is: 1463925582232863984

Now, I created the equivalent code in Javascript:

pow = function(baseNo, x){
  var value = 1;
  while(x > 0){
    value = value * baseNo;
    x--;
  }

  return value;
}

hexStr2Long = function(val){
 var keys = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 var exponent = keys.length;

 val = val.toUpperCase();
 var result = 0;
 for (var i = 0; i < val.length; i++) {
    var x = val.length - i - 1;
    var ch = val.charAt(i);
    result +=  keys.indexOf(ch) * Math.pow(exponent, x);
 }

 return result;
}
var r = hexStr2Long(wifimac);
console.log('Result: '+r);

The result is: 1463925582232864000, this in wrong, it has to be the same as Java code.

How can I accomplish that? I've already tried to use the library (BigNumber) but without success.

Upvotes: 0

Views: 1272

Answers (3)

Frank Schmid
Frank Schmid

Reputation: 311

After some experiments, I saw that 0xB4EEB49B04C0 is in IEEE-754 FP hexadecimal representation. So this answer is not appropriate at all.

1463925582232863984 is the correct decimal representation for the input!

Accordingly you should use a bignumber library that supports IEEE-754 input.

IGNORE old answer

Using BigNumber works as expected:

var r2 = new BigNumber("B4EEB49B04C0", 16);
console.log(r2.toString());

It outputs 198937325274304. Also online bignumber converters give this result. That tends me to suspect that the output of your Java code is wrong too. Can you verify that "1463925582232863984" is the correct result?

The input is a 48-bit number, so it cannot be greater as the maximum supported 64 bit number. Your posted result should equal "1450e88f9298c4f0" as input.

Upvotes: 0

JellyKid
JellyKid

Reputation: 302

Here is some info into why: https://modernweb.com/what-every-javascript-developer-should-know-about-floating-points/

The problem is with Javascript's floating point precision.

You could always try another library like Math.js

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500785

1463925582232864000 is the nearest 64-bit IEEE-754 floating point number to 1463925582232863984. Numbers in Javascript are (at the moment - I believe this is changing) always 64-bit IEEE-754 floating point numbers.

Basically, in order to do this you'll need a Javascript library that supports numeric types other than what's built in. (I'd expect BigNumber to work, but you haven't shown us what you tried with it, so it's hard to know what you did wrong.)

Upvotes: 2

Related Questions