There is nothing special about dividing two ints in Java. Unless one of the two special cases handled:
- Division by zero. (JVMS requires the virtual machine to throw
ArithmeticException) - Division overflow (
Integer.MIN_VALUE / -1, JVMS requires the result to be equal toInteger.MIN_VALUE) (This question is about this case exclusively).
From Chapter 6. The Java Virtual Machine Instruction Set. idiv:
There is one special case that does not satisfy this rule: if the dividend is the negative integer of largest possible magnitude for the
inttype, and the divisor is-1, then overflow occurs, and the result is equal to the dividend. Despite the overflow, no exception is thrown in this case.
On my computer (x86_64) native division produces a SIGFPE error.
When I compile the following C code:
#include <limits.h>
#include <stdio.h>
int divide(int a, int b) {
int r = a / b;
printf("%d / %d = %d\n", a, b, a / b);
return r;
}
int main() {
divide(INT_MIN, -1);
return 0;
}
I get the result (on x86):
tmp $ gcc division.c
tmp $ ./a.out
Floating point exception (core dumped)
Exactly the same code compiled on ARM (aarch64) produces:
-2147483648 / -1 = -2147483648
So it seems that on x86 the Hotspot VM is required to do extra work to handle this case.
- What does the virtual machine do in this case to not lose performance too much in compiled code?
- Does it exploit the signal handling possibilities in POSIX systems? If so what does it use on Windows?