E
E
eluzive2019-03-13 00:09:15
Python
eluzive, 2019-03-13 00:09:15

Why different Java and Python output values?

Java code:

class WTF {
    public static void main(String[] args) {
    	long output_1 = generate(400732734464L, -74, 12);
    	long output_2 = generate(1641401281110016L, 100, 14);

    	System.out.println(String.valueOf(output_1));
    	System.out.println(String.valueOf(output_2));
    }

    public static long generate(long val1, int val2, int val3) {
    	long l;
    	l = val1 + (val2 & 255) << val3;
    	return l;
    }
}

Outputs:
1641401281110016
8445974515998588928

Python code:
def generate(val1, val2, val3):
  i = int()
  i = val1 + (val2 & 255) << val3
  return i 

output_1 = generate(400732734464, -74, 12);
output_2 = generate(1641401281110016, 100, 14);

print(output_1)
print(output_2)

Outputs:
1641401281110016
26892718589708140544

Why different result in the last examples?
UPDATE:
I will add more php and ruby.
PHP:
$output = 1641401281110016 + (100 & 255) << 14;

echo $output;
//8445974515998588928

ruby:
output = 1641401281110016 + (100 & 255) << 14;
puts output;
//26892718589708140544

I don't even know what to think

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vamp, 2019-03-13
@eluzive

The reason is that the second method call evaluates to a value that does not fit into the long data type. That is, there is a classic integer overflow. In java and php, high bits that do not fit in long are simply discarded. Python and ruby ​​support bignum arithmetic at the language level, so the result is different. That is, the numbers can be arbitrarily large without the danger of overflow. In php, this is also possible using the bcmath or gmp module. In java, the BigInteger class provides similar arithmetic:

import java.math.BigInteger;

public class A {
    public static void main(String[] args) {
        BigInteger output_1 = generate(400732734464L, -74, 12);
        BigInteger output_2 = generate(1641401281110016L, 100, 14);

        System.out.println(output_1);
        System.out.println(output_2);
    }

    public static BigInteger generate(long val1, int val2, int val3) {
        return BigInteger.valueOf(val2 & 255)
            .add(BigInteger.valueOf(val1))
            .shiftLeft(val3);
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question