Primitive type | Size in memory | Range of values |
---|---|---|
byte | 8 bit | -128 to 127 |
short | 16 bit | to -32768 to 32767 |
char | 16 bit | from 0 to 65536 |
int | 32 bits | from -2147483648 to 2147483647 |
long | 64 bits | from -9223372036854775808 to 9223372036854775807 |
float | 32 bits | from (2 to the power -149) to ((2-2 to the power -23)*2 to the power 127) |
double | 64 bits | from (-2 to the power of 63) to ((2 to the power of 63) - 1) |
boolean | 8 (when used in arrays), 32 (when used in non-arrays) | true or false |
BigInteger
is BigDecimal
practically unlimited. What are these classes used for? First of all, for calculations with extremely high accuracy requirements. There are, for example, programs in which human life can depend on the accuracy of calculations (software for airplanes and rockets or for medical equipment). Therefore, if even the 150th decimal place plays an important role, BigDecimal
it is the best choice. In addition, quite often these objects are used in the world of finance, where the accuracy of calculations down to the smallest values is also extremely important. How to work with objects BigInteger
and BigDecimal
what is important to remember about them? Objects of these classes are created like this:
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigDecimal decimal = new BigDecimal("123.444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444");
System.out.println(decimal);
}
}
Passing a string as a parameter is only one of the possible constructors. Here we use strings because our numbers exceed the maximum values long
and double
, and somehow we need to explain to the compiler exactly what number we want to get :) Just pass the number 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111111 will not work: Java will try to “fit” the passed number into one of primitive data types, but it won’t fit into any of them. Therefore, using a string to pass the desired number is a good option. Both classes can automatically extract numeric values from passed strings. Another important point to remember when working with large number classes is that their objects are immutable ( Immutable
) . You are already well acquainted with the principle of immutability through the example of a class String
and wrapper classes for primitives (Integer, Long and others).
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
integer.add(BigInteger.valueOf(33333333));
System.out.println(integer);
}
}
Console output:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Our numbers haven't changed, as you'd expect. For the addition operation to succeed, you must create a new object and assign the result of the addition to it.
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigInteger result = integer.add(BigInteger.valueOf(33333333));
System.out.println(result);
}
}
Console output:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Now everything works as it should :) By the way, did you notice how unusual the addition operation looks?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
This is another important point. Large number classes do not use the +-*/ operators in their operation, but instead provide a set of methods. Let's take a look at the main ones (you can, as always, find a complete list of methods in the Oracle documentation: here and here ).
-
methods for performing arithmetic operations:
add()
,subtract()
,multiply()
,divide()
. Used for addition, subtraction, multiplication and division operations respectively. -
doubleValue()
,intValue()
,floatValue()
,longValue()
etc. - Used to convert a large number to a Java primitive type. Be careful when using them and remember the difference in capacity!import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); long result = integer.longValue(); System.out.println(result); } }
Console output:
8198552921648689607
-
min()
andmax()
- allow you to find the minimum and maximum value of two large numbers passed.
Please note: methods are not static!import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); BigInteger integer2 = new BigInteger("222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"); System.out.println(integer.max(integer2)); } }
Console output:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
BigDecimal rounding control
This topic is included in a separate section, since rounding large numbers and adjusting it is not such a simple thing. You can set the number of decimal places for a numberBigDecimal
using the setScale()
. For example, we want to set the precision of the number 111.5555555555 to three decimal places. However, we will not be able to pass the number 3 as an argument to the method setScale()
and thus solve our problem. As mentioned above, BigDecimal
these are numbers for calculations with increased accuracy. In its current form, our number has 10 decimal places. We want to discard 7 of them and leave only 3. Therefore, in addition to the number 3, we must pass the rounding mode as a parameter . There are 8 rounding modes in total BigDecimal
. Quite a lot! But if you need to really fine-tune the accuracy of calculations in the program, you will have everything you need for this. So, here are the 8 rounding modes available in BigDecimal
:
-
ROUND_CEILING
- rounding up111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN
- discharge discarding111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR
- rounding down111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP
— rounding up if the number after the decimal point >= .50.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN
— rounding up if the number after the decimal point > .50.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN
— rounding will depend on the number to the left of the decimal point. If the number on the left is even, then rounding will be done downward. If the number to the left of the decimal point is odd, it will be rounded up.2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
The number to the left of the decimal point - 2 - is even. Rounding occurs down. Since we require 0 decimal places, the result will be 2.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
The number to the left of the decimal point - 3 - is odd. Rounding occurs upward. Since we require 0 decimal places, the result will be 4.
-
ROUND_UNNECCESSARY
— used in cases where the rounding mode needs to be passed to some method, but the number does not need rounding. If you try to round a number when the ROUND_UNNECCESSARY mode is set, an ArithmeticException is thrown.3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP
- rounding up.111.5551 -> setScale(3, ROUND_UP) -> 111.556
Comparison of large numbers
This question is also important. You already remember that the method is used to compare objects in Javaequals()
. It is either provided by the language itself (in the case of Java's built-in classes) or overridden by the programmer. But in the case of class objects, it is not recommended BigDecimal
to use the method equals()
for comparison. The reason for this is that the BigDecimal.equals()
two-number method returns true only if the two numbers have the same value and scaleequals()
: Let's compare the behavior of the y Double
and y methods BigDecimal
:
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
Double a = 1.5;
Double b = 1.50;
System.out.println(a.equals(b));
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.equals(y));
}
}
Console output:
true
false
As you can see, the numbers 1.5 and 1.50 in the case of c BigDecimal
turned out to be unequal! This happened precisely because of the specifics of the method equals()
in the class BigDecimal
. For a more correct comparison of the two, BigDecimal
it is better to use the method compareTo()
:
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.compareTo(y));
}
}
Console output:
0
The method compareTo()
returned 0, which means equal to 1.5 and 1.50. This is the result we were counting on! :) This concludes our lesson for today. It's time to get back to tasks! :)
GO TO FULL VERSION