Java Math
Use named numeric operations with a clear purpose. Choose a rounding policy, preserve unrounded calculations, and test the assumptions behind a number before making it look neat in a report.
Before you start: complete Java Strings and be comfortable with numeric conversion. Each example is a complete Main.java program in the existing Java 21 runner. Predict the result, run it, then change one input.
What you will be able to do
- Call Math methods and choose suitable result types.
- Distinguish truncation, round, floor, and ceil, including negative inputs.
- Calculate a distance while keeping units and display precision explicit.
- Avoid rounding or truncating intermediate results too early.
- Recognize domain errors, overflow, and the limits of clamping.
- Generate a small bounded random integer and test its range rather than a fixed draw.
Math gives a calculation a precise name
You already know arithmetic operators. The Math class adds named operations such as choosing the smaller value, finding a square root, or rounding upward. A call such as Math.min(12, 8) supplies two arguments and returns 8. It does not change either input variable or automatically print anything.
These methods are static, so you call them through Math rather than constructing a Math object. Math belongs to java.lang and is available without an import. Parentheses contain the arguments, and a comma separates two arguments. Read the method name and its inputs together before deciding what result you expect.
Choose a result type deliberately. Math.min with two int arguments returns int; sqrt and pow work with double values; round(double) returns long. A number printed without a fractional part is not automatically an int. The types and policies matter more than the surface appearance of the output.
min and max select values; they do not validate a request
Math.min returns the smaller argument, while Math.max returns the larger. For a proposed allocation, choosing the smaller of twelve requested seats and eight available seats gives eight. The program below also limits a remaining-count estimate to zero at the lower end instead of displaying a negative number.
That lower bound is a deliberate display rule, not proof that twelve reservations succeeded. Clamping can conceal an over-capacity request if you use it instead of validation. A real reservation system must reject or explicitly resolve the excess request and make its state change safely. This example only calculates proposed values from fixed numbers.
Change requestedSeats to 5: the proposal becomes 5 and the remaining estimate becomes 3. A negative request can still flow through these methods, demonstrating why min and max are not input validation. Define the allowed domain separately. Java 21 also has Math.clamp, but the two-argument selectors are enough to learn the distinction here.
Main.java · Choose the smaller capacity and a lower bound
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Proposed seats: 8
Remaining lower-bound estimate: 0
abs removes direction, so decide whether direction matters
Math.abs computes an absolute value. If a learner practised 26.5 minutes against a 30-minute target, actual minus target is -3.5. That sign tells you the result is below target. Taking the absolute value gives a magnitude of 3.5 and deliberately discards the distinction between below and above.
Use an absolute difference for questions such as how far apart two measurements are. Keep the signed difference when a report must distinguish a shortfall from an excess. The example prints both so the meaning is visible. Changing actualMinutes to 33.5 reverses the sign but leaves the absolute difference unchanged.
The operation still obeys its numeric type's limits. Ordinary abs of Integer.MIN_VALUE remains negative because its positive magnitude cannot fit int. Subtracting two int values can also overflow before abs sees the result. Choose adequate types or checked operations rather than assuming the word absolute guarantees a safe nonnegative business count.
Main.java · Measure a difference without its direction
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Signed difference: -3.5
Absolute difference: 3.5
Use pow, sqrt, and PI with meaningful units
Math.pow(base, exponent) computes a power and returns double. Math.sqrt(value) computes a square root. For a simple square, side * side is often clearer than a general power call. Do not use ^ for exponentiation in Java: with integer operands it means bitwise exclusive OR, a different operation.
Math.PI is a named double approximation of pi, not a method call. A circle of radius two units has area PI times radius times radius, approximately 12.57 square units at two displayed decimal places. Keep the distinction between radius units and squared area units in your explanation.
Floating-point calculations and formatting remain separate. The stored area has more digits than the printed line. Printing two decimal places does not rewrite it into an exact decimal value. Also, sqrt accepts a double but is only real-valued for nonnegative finite inputs; the domain section below shows what happens when that assumption is violated.
Main.java · Powers, roots, and a circle measurement
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Three squared: 9.0
Square root of 81: 9.0
Circle area: 12.57
Truncation, nearest, floor, and ceiling answer different questions
An in-range cast from double to int truncates toward zero. Math.floor returns an integer-valued double toward negative infinity, and Math.ceil returns an integer-valued double toward positive infinity. For -2.5, truncation gives -2, floor gives -3.0, and ceiling gives -2.0. Upward and downward refer to the number line, not to distance from zero.
Math.round(double) returns the nearest long, with ties toward positive infinity. Thus round(2.5) gives 3 while round(-2.5) gives -2. It is not an all-purpose half-away-from-zero rule. The float overload returns int instead, so read the argument type and documented result type before assigning the answer.
Choose the policy from the task. Counting vehicles may require a ceiling; reporting whole elapsed minutes may intentionally truncate. Formatting a measurement to two places is another operation again. For exact decimal or money rounding, choose an appropriate representation and explicit business policy instead of assuming Math.round(value * 100) solves every precision problem.
Main.java · Compare four whole-number policies
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Truncated: -2
Rounded: -2
Floor: -3.0
Ceiling: -2.0
Positive tie rounded: 3
Round up a fractional requirement, not an already-truncated quotient
Seventeen learners with four seats per van require 4.25 vans mathematically, which means five whole vans if every learner must have a seat. Math.ceil gives the upward whole-number result. The program first converts an operand to double so division preserves that fractional requirement.
Math.ceil(learners / seatsPerVan) would receive the int quotient 4 and return 4.0, which is too late to recover the lost fraction. The final cast to int in this example is justified only because the chosen nonnegative input is small, seatsPerVan is positive, and the result fits int. It is not a general validation strategy for arbitrary input.
Test sixteen learners, seventeen learners, and zero learners with the same positive capacity. The answers should be four, five, and zero. Java 21 also provides Math.ceilDiv for an integer ceiling quotient; it avoids the floating-point route when that operation fits the task. Both approaches still require a valid denominator and suitable range assumptions.
Main.java · Round up a positive count of vehicles
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Unrounded ratio: 4.25
Vans needed: 5
Check the vehicle-count boundaries
Sixteen learners require four vans, seventeen require five, and zero require zero under the exercise's assumptions. The exact multiple is important: a policy that blindly adds one after division would overcount there.
Calculate a distance before formatting it
For two points on a flat coordinate grid, subtract their x coordinates to get dx and their y coordinates to get dy. Math.hypot(dx, dy) calculates the straight-line distance corresponding to the square root of dx squared plus dy squared, while avoiding some intermediate overflow and underflow issues of the naive formula.
The points below differ by three kilometres horizontally and four kilometres vertically, giving five kilometres of straight-line distance. These coordinates are already in the same local flat distance units. This is not a latitude/longitude formula, a road-route service, or a guarantee of actual travel distance.
Keep the unrounded distance for later calculations and round only where the report's rule requires it. Reversing the start and end changes the signs of dx and dy, not the distance. Identical points give zero. Test these properties alongside a known three-four-five example rather than trusting a single attractive output.
Main.java · Compute the straight-line distance
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Horizontal change (km): 3.0
Vertical change (km): 4.0
Straight-line distance (km): 5.0
A numerical method can return NaN or infinity
Math.sqrt(-1.0) returns NaN, meaning not a number in this real-valued floating-point calculation. A very large power can overflow double to positive infinity. These outcomes do not necessarily throw an exception, so a program can reach its print statement with a result that is unsuitable for the intended report.
Double.isNaN checks specifically for NaN. Double.isFinite checks that a value is neither infinity nor NaN. Do not detect NaN with value == Double.NaN, because NaN does not compare equal even to itself. These predicates report facts; conditions and input-handling code are still needed to decide what to reject or display.
Domain validation and numerical range checks are separate. A finite negative weight may still be invalid for your application, and a valid positive input may still create a non-finite intermediate calculation. Our lab uses small fixed finite values. Later input and control-flow lessons will put these assumptions into explicit acceptance and rejection paths.
Main.java · A domain error may return NaN, not throw
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Negative square root: NaN
Root is NaN: true
Enormous result: Infinity
Enormous result is finite: false
Exact integer methods report overflow instead of wrapping
Math.addExact, subtractExact, and multiplyExact perform integer arithmetic and throw ArithmeticException when the mathematical result cannot fit the chosen int or long result type. The example uses multiplyExact with int arguments and a product of two billion, which still fits int.
Change itemsPerPack to 50,000 and the product becomes too large for int. The checked method now reports an overflow instead of returning a misleading wrapped value. Passing long operands can select a wider operation, but even long has limits. The Exact suffix refers to checked representability, not a universal solution for all arithmetic problems.
The final output also demonstrates the minimum-int abs edge case. Java provides absExact if you need an exception when that positive magnitude cannot fit. These methods still allow negative values that fit their types and do not implement business validation. Handle a reported failure intentionally rather than replacing a checked operation with an unchecked one simply to keep execution going.
Main.java · Ask for an overflow report
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Checked total: 2000000000
Ordinary abs at int minimum: -2147483648
Random values need a range contract, not one expected draw
Math.random returns a pseudorandom double greater than or equal to 0.0 and less than 1.0. For this small die-like exercise, multiplying by six gives a value from zero up to but not including six. Truncating that nonnegative value gives an integer from zero to five; adding one shifts it into the desired one-through-six range.
The parentheses are essential. Casting Math.random to int before multiplying would always give zero, because every sample is below one. The example prints both the varying draw and a boolean checking the range. Its displayed output is one possible example, not a promise that your run produces four or that every run differs from the last.
Test the transformation with fixed samples such as 0.0, 0.5, and a value just below 1.0. They should map to 1, 4, and 6. Sampling a few runs cannot prove a random generator's fairness. For ordinary bounded integers, generator APIs such as Random.nextInt are often clearer; for secrets or security tokens, use a suitable secure generator rather than Math.random. This example is only practice output.
Main.java · Generate one die-like practice value
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Die roll: 4
In range: true
Test the transformation without unpredictable input
Temporarily replace Math.random() with 0.0, then 0.5, then 0.999999999. The rolls should be 1, 4, and 6. These fixed tests check the mapping boundaries; they do not test the statistical quality of the generator.
Repair the calculation before choosing the output
The starter calculates four vans for seventeen learners with four seats per van, and labels -3 as the upward-rounded form of -2.5. Both lines compile but use the wrong policy. Repair the division type and the rounding method without changing the inputs.
Main.java · Repair the rounding rules
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Reveal the explained repair
Convert an operand before division so ceil sees 4.25 rather than the already-truncated 4. Use ceil, not floor, when upward means toward positive infinity. The van cast is suitable for these small known inputs; a general input workflow would still need to enforce capacity and result-range requirements.
Main.java · Repaired rounding rules
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Vans: 5
Upward value: -2.0
Independent lab: a walking-session estimate
Build a local walking-session estimate on a flat kilometre grid. Calculate the unrounded distance, estimate travel minutes, and round upward only for the whole-minute planning field. This is an educational estimate, not real navigation, a booking, or a health recommendation.
- Use double startX = 0.0, startY = 0.0, endX = 2.0, and endY = 2.0, all in kilometres on a local flat grid.
- Use double speedKmPerHour = 4.0 and targetMinutes = 45.0. Treat the fixed speed as positive and all inputs as finite for this exercise.
- Calculate distanceKm with Math.hypot(endX - startX, endY - startY), then estimatedMinutes as distanceKm / speedKmPerHour * 60. Keep those values unrounded.
- Calculate plannedMinutes as Math.ceil(estimatedMinutes), and differenceMinutes as Math.abs(estimatedMinutes - targetMinutes).
- Print distance, estimated minutes, planned minutes, and absolute target difference using Locale.ROOT. Use two decimal places except for plannedMinutes, displayed with zero decimal places.
- Do not round distance before estimating time. Test identical points, a known three-four-five distance, and reversed endpoints.
Use this output contract, but do not use its rounded distance as an intermediate input:
Distance (km): 2.83
Estimated minutes: 42.43
Planned whole minutes: 43
Absolute target difference: 2.57
Main.java · Build your route estimate
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Show hints without revealing the solution
Subtract coordinates before calling hypot. Distance divided by speed gives hours; multiply by 60 to get minutes. Use ceil for the planned whole-minute field and abs for the target difference. Keep all four fields as double and let printf choose the display precision.
Reveal the explained lab solution
Main.java · Route estimate solution
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
The distance is approximately 2.828427 km, not the displayed 2.83 used as a fresh calculation input. The unrounded time is about 42.426407 minutes, so the planning field rounds upward to 43. The absolute difference from the 45-minute target is about 2.573593. These are estimates from explicit units and assumptions; formatting does not make the stored values exact decimals.
Test changes and boundaries
Reset between experiments and explain which fields should stay the same.
- Set both end coordinates to 0.0: distance and estimate are 0.00, planned minutes 0, and absolute target difference 45.00.
- Set endX to 3.0 and endY to 4.0: distance is 5.00, estimate 75.00, planned minutes 75, and absolute target difference 30.00.
- Reverse the original endpoints: use start coordinates 2.0, 2.0 and end coordinates 0.0, 0.0. The original report should be unchanged.
- Set speedKmPerHour to 8.0: distance stays 2.83, estimate becomes 21.21, planned minutes 22, and absolute target difference 23.79.
- Set speedKmPerHour to 0.0 with the original nonzero distance: the estimate becomes Infinity. Explain why a real workflow must reject nonpositive speed before using this formula.
Common mistakes and what to inspect
Separate a wrong rounding policy, an input outside the method's domain, a numeric range problem, and a purely presentational difference. They need different fixes.
ceil still gives too few vehicles
Check whether integer division already discarded the fraction before ceil received it. Convert an operand before division or choose a suitable integer ceiling-division operation with valid inputs.
Negative rounding goes the wrong direction
Floor moves toward negative infinity, ceil toward positive infinity, and an in-range cast truncates toward zero. Math.round uses nearest with ties toward positive infinity. These policies are not interchangeable.
^ produces a strange power result
In Java, ^ is not exponentiation. Use Math.pow for a general power or multiplication for a simple square. With integer operands, ^ performs bitwise exclusive OR.
A result is NaN or Infinity
Inspect domain assumptions, denominator, and intermediate magnitudes. Use Double.isNaN or Double.isFinite to inspect results. The absence of an exception does not prove the calculation is suitable.
Exact arithmetic throws ArithmeticException
The checked result does not fit its integer type. Choose adequate operand types or handle the rejected calculation. Do not discard the checked behavior merely to hide a genuine range problem.
The final estimate drifts after rounding
Avoid feeding rounded display values back into the next calculation unless the task explicitly requires intermediate rounding. Keep the original numeric result and apply formatting at the output boundary.
Frequently asked questions
Do I need to import Math or create new Math()?
No. Math is in java.lang, and its utility methods are static. Call Math.sqrt or Math.max directly. Learn to read the arguments and returned type rather than creating an unnecessary object.
Does Math.round(double) return int?
No. The double overload returns long; the float overload returns int. Floor and ceil return double even when their results are whole-number-valued. Choose the destination type based on the method signature and range requirements.
Is Math.random suitable for passwords or tokens?
No. This lesson uses it for a small practice draw. Security-sensitive randomness needs a suitable secure generator and an appropriate design. A range check on a die-like value does not establish security or fairness.
Does formatting to two places round the stored variable?
No. It creates a formatted output representation. The underlying double retains its numeric value. Avoid treating a displayed estimate as a replacement for the unrounded calculation input.
Is Math.hypot a map distance or travel-time service?
No. Here it computes a straight-line distance from differences in a flat grid whose axes use the same units. Latitude/longitude, roads, terrain, and real travel conditions need different models and data.
A calculation needs a domain, units, and a policy
Math methods make numeric intentions explicit, but do not remove type limits or validate business inputs. Keep units consistent, preserve intermediate values, choose rounding deliberately, and inspect non-finite results where the calculation can produce them.
Before moving on, explain why the lab prints 2.83 km but calculates time from a more precise distance. Then explain the negative rounding example and why random output needs a range check. Next is Java User Input with Scanner.
Can you choose the operation and explain its limits?
Answer all six questions and read the reasoning. Results are temporary on this page and do not save course progress.
References and related learning
The calculation scenarios, examples, explanations, and exercises are original SovranCode material. These official references support the API and language rules.
- Java 21 Math API: operations, rounding, and numerical contracts
- Java 21 Math API: random
- Java 21 Double API: isFinite and isNaN
- Java 21 specification: numerical operations and type promotion
Review conversion timing · Review numeric formatting · Java course roadmap.
Last updated: