zzy
zzy

Reputation: 1793

How to convert the var in js into java?

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

Answers (2)

yshavit
yshavit

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 ints 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

Daniel Kaplan
Daniel Kaplan

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

Related Questions