Java Double to Int: Cast, Round, and Overflow
java double to int: Learn how to convert a double to an int in Java: truncating casts, Math.round behavior, overflow saturation, NaN handling, and when each approach f...
Converting a double to an int in Java is a narrowing primitive conversion with precise, but often misunderstood, behavior. The direct cast (int) someDouble truncates the fractional part, so 3.99 becomes 3 and -3.99 becomes -3. That is not rounding, and it is not the only way to perform the java double to int conversion. Knowing what the cast does, when Math.round() is the better tool, and how out-of-range values behave will prevent a class of subtle bugs that usually surface in production.
The Basic Cast Truncates Toward Zero
The most direct conversion is the cast:
double price = 19.99; int whole = (int) price; // 19
The cast removes the fractional part entirely. For positive values the result is the largest integer not greater than the input; for negative values the result is the smallest integer not less than the input. In other words, truncation moves toward zero rather than toward negative infinity:
int a = (int) 19.99; // 19 int b = (int) -19.99; // -19, not -20
This distinction matters when the input can be negative. Math.floor(-19.99) returns -20.0, so if your calculation expects floor semantics, the cast will produce a different answer.
Rounding Instead of Truncation
When the fractional part should influence the result, use Math.round():
double value = 3.7; long rounded = Math.round(value); // 4 int result = (int) rounded;
Math.round(double) returns a long, so assigning the result to an int still requires a cast. The method is defined as floor(x + 0.5), which means it rounds half up toward positive infinity. Math.round(-3.5) is -3, while Math.round(-3.7) is -4. If your domain needs rounding half away from zero or banker's rounding, Math.round() alone will not match, and you will need explicit logic.
For floor and ceiling behavior, Math.floor() and Math.ceil() both return double, so they also need a cast:
int floor = (int) Math.floor(3.7); // 3 int ceil = (int) Math.ceil(3.2); // 4
Using Double.intValue() and Its Limitations
The wrapper class Double provides intValue(), which returns the same result as the cast:
Double boxed = 42.9; int result = boxed.intValue(); // 42
intValue() truncates toward zero, exactly like (int). It requires a Double instance, so for a primitive double you either trigger autoboxing or you already hold a boxed value. The cast is preferable for primitives: it is shorter, avoids the wrapper, and does not change behavior. intValue() is mainly useful when you are already working with a Double object, for example inside a generic method or when processing values from a collection.
What Happens on Overflow, NaN, and Infinity
The cast never throws, even when the value cannot be represented as an int. The Java Language Specification defines the behavior for narrowing floating-point conversions: a value too large saturates to Integer.MAX_VALUE, a value too small saturates to Integer.MIN_VALUE, and NaN becomes 0.
int tooBig = (int) 3e10; // 2147483647 int tooSmall = (int) -3e10; // -2147483648 int nan = (int) Double.NaN; // 0 int inf = (int) Double.POSITIVE_INFINITY; // 2147483647
This silent saturation is a frequent source of production bugs. If the double comes from user input, a calculation, or an external service, a value slightly above Integer.MAX_VALUE will quietly become 2147483647 instead of failing. When the input range is not guaranteed, check the value before converting:
if (value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE) { int result = (int) value; } else { // handle the out-of-range case explicitly }
Choosing the Right Conversion for Your Use Case
The correct approach depends on the semantics of the data, not on which method is shortest.
Use the plain cast when truncation is the intended behavior — for example, when a price in cents must drop the fractional part, or when a measured value is intentionally quantized downward. Use Math.round() when the nearest integer is required and half-up behavior matches the domain. Use Math.floor() or Math.ceil() when the direction of rounding is part of the contract, such as pagination math or capacity calculations.
When the double originates outside your control, range validation before the cast is more important than the choice of rounding method, because saturation and NaN conversion are silent. A helper method that documents the policy keeps the decision in one place:
public static int toIntChecked(double value) { if (Double.isNaN(value) || value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { throw new IllegalArgumentException("Value out of int range: " + value); } return (int) value; }
Performance and Maintainability Considerations
The cast is a single narrowing operation and costs essentially nothing. Math.round() adds a small amount of arithmetic, and Math.floor() and Math.ceil() are also cheap. None of these will be a measurable bottleneck unless they sit inside a very hot loop, and even then the surrounding work usually dominates. Premature optimization here is not justified.
The real cost is maintainability. Silent truncation and silent saturation both hide data problems. A value that should have been rounded, or a value that overflowed, produces a plausible-looking int and the error surfaces later, often as an off-by-one or a corrupted identifier. Choosing the conversion that matches the domain, and validating range when the input is untrusted, keeps the behavior explicit and the failure mode visible.