I am trying to convert a double value of 2147483648 to integer, After typecasting it, I get output as 2147483647, the number is reduced by 1. I know that this is happening because of overflow, but is there a way where I can convert it to int type without loosing its precision?
-
2unfortunately no. but consider using `long` if applicable. – Ousmane D. Dec 31 '17 at 00:47
-
A double can even be outside the range of a long, but in this case it would be fine – harold Dec 31 '17 at 01:13
4 Answers
As aforementioned in previous answers, you can use the long
primitive data type, or the BigInteger
reference type. Using integral data types rather than floating points would be better for representing integers exactly.
As a side note, since Java SE 8, one can use the Integer
class to use int for unsigned arithmetic. Per the Oracle doc - "Use the Integer class to use int data type as an unsigned integer". Unsigned integers have a greater maximum value than int. This question can be of use: Declaring an unsigned int in Java.
This is my first answer, hope you solved your problem! :)

- 303,325
- 100
- 852
- 1,154
I can think of 2 options.
Long
Unlike int
, which is a 32-bit signed integer data type, long
is a 64-bit signed integer data type. This means that the largest value it can store is 9223372036854775807
. The number that you are trying to store, 2147483648, is well inside that range.
BigInteger
This is a reference type that represents an "immutable arbitrary-precision integer". You can create a BigInteger
instance that represents 2147483648 by doing
new BigInteger("2147483648")
Learn more about it here: https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html

- 213,210
- 22
- 193
- 313
Max Values
The maximum integer, as indicated in the Integer class by the static final int MAX_VALUE
, is 2^31-1 (2,147,483,647). This value is the maximum integer as it is the largest 32-bit signed integer.
The maximum double, as indicated in the Double class by the static final int MAX_VALUE
, is (2-2^(-52))(2^1023). The double data type follows the double-precision 64-bit IEEE 754 floating point format to express a wide range of dynamic numerical values.
Narrowing Primitive Conversion
In you're observation, you have a double with a value 2,147,483,648 which you attempt to convert to an integer by type casting.
double d = 2147483648;
int i = (int) d;
Casting between primitive types allows your to convert the value of one primitive type to another. Converting from a double to an integer is known as a Narrowing Primitive Conversion, wherein you:
"may lose information about the overall magnitude of a numeric value and may also lose precision and range."
The narrowing conversion of a floating-point number to an int is as follows:
- If the floating-point number is NaN, the result is an int of 0.
- Otherwise, if the floating-point number is not an infinity, the floating-point number is rounded to an integer value V, rounding toward zero using IEEE 754 round-toward-zero mode. If this integer value can be represented as an int, then the result is V.
- Otherwise, one of the following two cases must be true: a. The value must be too small and the result is the smallest representable value of type int or b. The value must be too large and the result is the largest representable value of type int.
With the integer value of the double value larger than the Integer.MAX_VALUE, in order to allow for representation as an integer the value of Integer.MAX_VALUE is used.
Avoid Loss
To avoid the loss of precision you will need to either cast to a primitive type or a numeric Object wherein the maximum value is greater than 2147483648 (and resolution allows for accuracy to be maintained).
The long primitive type has a maximum value of 2^63-1 (9.223372e+18), which would be a good choice if you want to use numbers within the numeric integer space. Note that while the Long.MAX_VALUE is very large, Double.MAX_VALUE is MUCH larger due to the floating-point format.
double d = 2147483648;
long i = (long) d;

- 1,693
- 1
- 9
- 13
Converting from a double
to an int
will lose precision for numbers greater than Integer.MAX_VALUE
or less that Integer.MIN_VALUE
. There is no way to represent numbers outside that range as an int
. It is mathematically impossible.
Converting from a double
to an long
will also lose precision. This will occur for all integers outside of Long.MIN_VALUE
through Long.MAX_VALUE
. But a second problem is that double
itself is not able to represent all integers in that range ... so there will be loss of precision before the conversion1.
Moral:
Don't use floating point numbers if you need to represent integers precisely. Use an integral type (byte
, short
, char
, int
or long
) ... or BigInteger
.
1 - A double
is a 64 bit IEE floating point number, which has 52 bits of precision and a sign bit. By contrast, a long
has 64 bits of precision (including sign).

- 698,415
- 94
- 811
- 1,216