Reputation: 580
I'm developing a chemistry app, and I need to include the Avogadro's number:
(602200000000000000000000
)
I don't really know if I can use scientific notation to represent it as 6.022 x 10x23
(can't put the exponent).
I first used double
, then long
and now, I used java.math.BigInteger
.
But it still says it's too big, what can I do or should this is just to much for a system?
Upvotes: 4
Views: 6886
Reputation: 492
Most probably you are using long
to initialize BigInteger. Since long
can represent 64-bit numbers, your number would be too big to fit in to long
. Using String
would help.
Upvotes: 0
Reputation: 718678
First of all, you need to check your physics / chemistry text book.
Avogadro's number is not 602,200,000,000,000,000,000,000. It is approximately 6.022 x 1023. The key word is "approximately". As of 2019, the precise value is 6.02214076×1023 mol−1
(In 2015 when I originally wrote this reply, the current best approximation for Avogadro's number was 6.022140857(74)×1023 mol−1, and the relative error was +/- 1.2×10–8. In 2019, the SI redefined the mole / Avogadro's number to be the precise value above. Source: Wikipedia)
My original (2015) answer was that since the number only needed 8 decimal digits precision, the Java double
type was an appropriate type to represent it. Hence, I recommended:
final double AVOGADROS_CONSTANT = 6.02214076E23;
Clearly, neither int
or long
can represent this number. A float
could, but not with enough precision (assuming we use the best available measured value).
Now (post 2019) the BigInteger
is the simplest correct representation.
Now to your apparent problems with declaring the constant as (variously) an double
, a long
and a BigInteger
.
I expect you did something like this:
double a = 602200000000000000000000;
and so on. That isn't going to work, but the reason it won't work needs to be explained. The problem is that the number is being supplied as an int
literal. An int
cannot be that big. The largest possible int
value is 231 - 1 ... which is a little bit bigger than 2 x 109.
That is what the Java compiler was complaining about. The literal is too big to be an int
.
It is too big for long
literal as well. (Do the math.)
But it is not too big for a double
literal ... provided that you write it correctly.
The solution using BigInteger(String)
works because it side-steps the problem of representing the number as a numeric literal by using a string instead, and parsing it at runtime. That's OK from the perspective of the language, but (IMO) wrong because the extra precision is an illusion.
Upvotes: 10
Reputation: 55589
The problem is with how you're trying to create it (most likely), not because it can't fit.
If you have just a number literal in your code (even if you try to assign it to a double
or long
), this is first treated as an integer (before being converted to the type it needs to be), and the number you have can't fit into an integer.
// Even though this number can fit into a long, it won't compile, because it's first treated
// as an integer.
long l = 123456788901234;
To create a long, you can add L
to your number, so 602200000000000000000000L
, although it won't fit into a long either - the max value is 263-1.
To create a double, you can add .0
to your number, so 602200000000000000000000.0
(or 6.022e23
as Guffa suggested), although you should not use this if you want precise values, as you may lose some accuracy because of the way it stores the value.
To create a BigInteger
, you can use the constructor taking a string parameter:
new BigInteger("602200000000000000000000");
Upvotes: 4
Reputation: 700152
You can use E notation to write the scientific notation:
double a = 6.022e23;
Upvotes: 6
Reputation: 3898
Pass it to the BigInteger constructor as a String
, and it works just fine.
BigInteger a = new BigInteger("602200000000000000000000");
a = a.multiply(new BigInteger("2"));
System.out.println(a);
Output: 1204400000000000000000000
Upvotes: 13