You
need to handle integer numbers larger than
Long.MAX_VALUE
or
floating-point
values larger than Double.MAX_VALUE
.
Use the BigInteger
or
BigDecimal
values in package
java.math
:
// BigNums.java System.out.println("Here's Long.MAX_VALUE: " + Long.MAX_VALUE); BigInteger bInt = new BigInteger("3419229223372036854775807"); System.out.println("Here's a bigger number: " + bInt); System.out.println("Here it is as a double: " + bInt.doubleValue( ));
Note that the constructor takes the number as a string. Obviously you
couldn’t just type the numeric digits, since by definition
these classes are designed to represent numbers larger than will fit
in a Java long
.
Both BigInteger
and BigDecimal
objects are immutable; that is, once constructed,
they always represent a given number. That said, there are a number
of methods that return new objects that are mutations of the
original, such as negate( )
, which returns the negative of the
given BigInteger
or BigDecimal
.
There are also methods corresponding to most of the Java language
built-in operators defined on the base types
int
/long
and
float
/double
. The division
method makes you specify the rounding method; consult a book on
numerical analysis for details. Here is a simple
stack-based calculator using
BigDecimal
as its numeric data type:
import java.math.BigDecimal; import java.util.Stack; /** A trivial reverse-polish stack-based calculator for big numbers */ public class BigNumCalc { /** an array of Objects, simulating user input */ public static Object[] input = { new BigDecimal("3419229223372036854775807.23343"), new BigDecimal("2.0"), "*", "=", }; public static void main(String[] args) { Stack s = new Stack( ); for (int i = 0; i < input.length; i++) { Object o = input[i]; if (o instanceof BigDecimal) s.push(o); else if (o instanceof String) { switch (((String)o).charAt(0)) { case '+': s.push(((BigDecimal)s.pop()).add((BigDecimal)s.pop( ))); break; case '-': s.push(((BigDecimal)s.pop()).subtract((BigDecimal)s.pop( ))); break; case '*': s.push(((BigDecimal)s.pop()).multiply((BigDecimal)s.pop( ))); break; case '/': s.push(((BigDecimal)s.pop()).divide((BigDecimal)s.pop( ), BigDecimal.ROUND_UP)); break; case '=': System.out.println(s.pop( )); break; default: throw new IllegalStateException("Unknown OPERATOR popped"); } } else { throw new IllegalStateException("Syntax error in input"); } } } }
Running this produces the expected (very large) value:
> jikes +E -d . BigNumCalc.java > java BigNumCalc 6838458446744073709551614.466860 >
The current version has its inputs hardcoded,
but in real life you
can use regular expressions to
extract words or operators from an input stream (as in Section 4.8) or use the
StreamTokenizer
approach of the simple calculator (Section 9.13). The stack of numbers is maintained using a
java.util.Stack
(Section 7.16).
BigInteger
is mainly useful in
cryptographic and security
applications. Its method isProbablyPrime( )
can
create
prime pairs for public key
cryptography. BigDecimal
might
also be useful in
computing the size of the universe.
3.145.87.161