Why do these two similar codes give different results?

I have been experimenting with Python as a beggar in the last few hours. I wrote a recursive function that returns recurse (x) as x! in Python and Java to compare them. The two parts of the code are identical, but for some reason Python works, but Java does not. In Python, I wrote:

x = int(raw_input("Enter: ")) def recurse(num): if num != 0: num = num * recurse(num-1) else: return 1 return num print recurse(x) 

If the variable num is multiplied by num-1, until it reaches 0, and prints the result. In Java, the code is very similar, only longer:

 public class Default { static Scanner input = new Scanner(System.in); public static void main(String[] args){ System.out.print("Enter: "); int x = input.nextInt(); System.out.print(recurse(x)); } public static int recurse(int num){ if(num != 0){ num = num * recurse(num - 1); } else { return 1; } return num; } 

}

If I enter 25, the Python code returns 1.5511x10E25, which is the correct answer, but the Java code returns 2,076,180,480, which is not the correct answer, and I'm not sure why.

Both codes work on the same process:

  • Make sure num is zero
  • If num is not equal to zero
    • num = num times recursion num - 1
  • If num is zero
    • Returns 1, ending this recursion call stack and calling each returned number to start the multiplication
  • return num

There are no brackets in python; I thought I somehow changed the situation, so I removed the brackets from the Java code, but that did not change. Changing the logical (num! = 0) to (num> 0) did not change anything. Adding an if statement to else provided more context, but the value was the same anyway.

Printing num values ​​at each point gives an idea of ​​how the function goes wrong:

Python:

 1 2 6 24 120 720 5040 40320 362880 3628800 39916800 479001600 6227020800 87178291200 1307674368000 20922789888000 355687428096000 6402373705728000 121645100408832000 2432902008176640000 51090942171709440000 1124000727777607680000 25852016738884976640000 620448401733239439360000 15511210043330985984000000 15511210043330985984000000 

Constant increase. In Java:

  1 2 6 24 120 720 5040 40320 362880 3628800 39916800 479001600 1932053504 1278945280 2004310016 2004189184 -288522240 -898433024 109641728 -2102132736 -1195114496 -522715136 862453760 -775946240 2076180480 2076180480 

Steady growth. In fact, num returns negative numbers, as if the function returns negative numbers, even if the number should not go below zero.

Both Python and Java codes work on the same procedure, but they return completely different values. Why is this happening?

+7
source share
6 answers

Two words - integer overflow

Not being an expert in python, I assume that he can expand the size of an integer type to suit his needs.

In Java, however, the size of the int type is fixed at 32 bits, and since the int signed, we actually only have 31 bits to represent positive numbers. As soon as the number you have assigned is greater than the maximum, it overflows the int (namely, there is no room for representing an integer).

While in C the behavior in this case is undefined, in Java it is well defined and it just takes at least 4 bytes of result.

For example:

 System.out.println(Integer.MAX_VALUE + 1); // Integer.MAX_VALUE = 0x7fffffff 

leads to:

 -2147483648 // 0x7fffffff + 1 = 0x800000000 

Edit

To make this clearer, here is another example. The following code:

 int a = 0x12345678; int b = 0x12345678; System.out.println("a*b as int multiplication (overflown) [DECIMAL]: " + (a*b)); System.out.println("a*b as int multiplication (overflown) [HEX]: 0x" + Integer.toHexString(a*b)); System.out.println("a*b as long multiplication (overflown) [DECIMAL]: " + ((long)a*b)); System.out.println("a*b as long multiplication (overflown) [HEX]: 0x" + Long.toHexString((long)a*b)); 

outputs:

 a*b as int multiplication (overflown) [DECIMAL]: 502585408 a*b as int multiplication (overflown) [HEX]: 0x1df4d840 a*b as long multiplication (overflown) [DECIMAL]: 93281312872650816 a*b as long multiplication (overflown) [HEX]: 0x14b66dc1df4d840 

And you can see that the second output is at least 4 bytes from 4 outputs

+11
source

Unlike Java, Python has built-in support for long integers of unlimited precision. In Java, an integer is limited to 32 bits and will be overflow .

+2
source

As others have already written, you get an overflow; numbers just won't fit into the java data view view. Python has a built-in bignum feature regarding where there is no java.

Try a few smaller values ​​and you will see that the java code is working fine.

+1
source

Java int range

Int 4 bytes signed (two additions). -2,147,483,648 to 2,147,483,647. Like all numeric types, ints can be added to other numeric types (byte, short, long, float, double). When flush losses are performed (for example, int by byte), the conversion is performed modulo a length of a smaller type.

Here int range is limited

+1
source

The problem is very simple.
coz in java the maximum limit of an integer 2147483647 u can print it using System.out.println(Integer.MAX_VALUE); and minimum System.out.println(Integer.MIN_VALUE);

0
source

Because in the java version, you store the number as an int , which I believe is 32-bit. Consider the largest (unsigned) number that you can save with two bits in binary format: 11, which is the number 3 in decimal value. The largest number that can be stored in binary format is 1111, which is the number 15 in decimal value. A 32-bit (signed) number cannot store anything more than 2,147,483,647. When you try to keep a number larger than this, it suddenly wraps around and starts counting from negative numbers. This is called overflow.

If you want to try to save large numbers, try for a long time.

0
source

All Articles