Reputation: 1793
Now I'm try to convert some js code into java , there is a problem:
In js
46022*65535 = 3016051770
and
(46022*65535)|7867 = -1278910789
In java
46022*65535 = -1278915526 this is overflow
46022L*65535L = 3016051770L this is the same result to js
(46022*65535)|7867 = -1278910789 this one and the one below is the problem
(46022L*65535L)|7867L = 3016056507L
So , why the |
operator will make two positive number to be nagtive number?
What's the different between java and js when dealing with the int and long to do this operation?
And then , how to write java code compatible with js in this situation ?
Attention:I know the range of int and long , my problem is |
.
More problems :
According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
&
is also 32bit operation, then:
In js
2996101485 & 65535 = 57709
In java
2996101485 is overflow to int so I use double to store it and cast it into int when I need to do AND.
double a = 2996101485l;
double b = 65535;
int c = (int) a & (int) b; Now c = 65535
But if I use long to cast :
long c = (long) a & (long) b; Now c = 57709
So , just simply cast double into int will cause problems. And I want to know why?
I got the problem , 2996101485 can be present in 32bit in js and in java it should be long. So I write functions to convert those operations , for example, &
should use this java function to run give same result in js:
private double doOR(double x, double y) {
if (x > Integer.MAX_VALUE && x <= 1l << 32) {
if (y > Integer.MAX_VALUE && y <= 1l << 32) {
return (long) x | (long) y;
} else {
return (long) x | (int) y;
}
} else {
return (int) x | (int) y;
}
}
Upvotes: 2
Views: 144
Reputation: 43391
The problem is that while numbers in JavaScript have roughly 53-bit precision (they appear to be based on floating point doubles), the bitwise OR operates on only 32 bits.
Bitwise operators treat their operands as a sequence of 32 bits (zeroes and ones), rather than as decimal, hexadecimal, or octal numbers.
This means that when working with arithmetic, long
will get you the JavaScript-like arithmetic (with numbers such as yours), since Java int
s will overflow; but when working with bitwise operations, int
will get you the JavaScript-like results, since then both platforms are operating on 32-bit numbers.
Upvotes: 2
Reputation: 67340
You should use long
instead.
System.out.println(46022L*65535L); // = 3016051770
Java has ints and longs.
System.out.println(Integer.MAX_VALUE); // = 2147483647
System.out.println(Long.MAX_VALUE); // = 9,223,372,036,854,775,807
As for the language difference, I can only attribute it to different precisions between the languages. If you see this question, you'll see the largest number in JS is 9,007,199,254,740,992. That's a guess, it might be for another reason.
Upvotes: 2