in python with a simple loop you can calculate, let's say 600! it's a very very big number but python can easily take care of it in a fraction of a second.even it's more than 200 digit long.
in java in the other hand you are bound to 64bit literals (long data type). so the machine will return 0.
is there any way to overcome this?
You can use the Java BigInteger class.
And a simple example:
import java.math.BigInteger;
BigInteger k = BigInteger.valueOf(10000L);
k = k.pow(10000);
//k is now 10000^10000
System.out.println(k.toString());
It's important to know that the class is immutable. You can also look into the similar BigDecimal class for arbitrary precision signed decimal numbers.
Related
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?
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
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.
You can use E notation to write the scientific notation:
double a = 6.022e23;
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");
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.
So I'm trying to do a relatively simple program, but I am running into java's integer limits. The number is 471.5 billion. A friend suggested that I multiply 481.5 by 1000 a couple times in order to output the correct number. When I do this, the output is just 481 times 1000, no matter what I do.
As well, if I multiply by 1000 more than twice, It gives really odd numbers.
Here is the code
int debt1
debt1 = 481.5;
system.out.println(debt1 * 1000 * 1000 * 1000);
Are you sure your code even compiles correctly?
Your variable is defined as an int but you try to assign a double value to it.
If you change your variable type to double, it can hold the value 481.5 that you try to assign to it.
But in any case, if you want to deal with REALLY big numbers like 481.500.000.000, you should use BigInteger
Notice though that with BigInteger, you won't be able to simply write numbers in your IDE (since no built in java types can handle numbers this big). As the documentation says, you can create BigIntegers by either using a string representation of a number or by specifying the number in a couple more ways.
For a simple example take a look at this:
import java.math.BigInteger;
class Example {
public static void main(String[] args) {
BigInteger debt = new BigInteger("481500000000");
debt = debt.add(new BigInteger("12312"));
System.out.println(debt.toString());
}
}
I am wondering how to represent 5400000000,5400000001,5400000002,.... in java
(how to represent 5 billion in java)
java ints only hold 2^32-1,
java longs hold 2^64-1,..but i am having a problem representing 5400000000,5400000001,5400000002,....and doubles aren't helping either.
can someone plz provide insight how to represent large values like this (IN JAVA) without having to do multiplication on strings
because Long max = Long(5462205000); just isnt doing it for me.
thx in advance
Your 64-bit integer type can easily hold numbers like 5 billion. Even the signed version can hold values up to 9223372036854775807. Slow bigint libraries not necessary.
To specify these in code you need to use what's called a 'long int literal', which means adding an L to the end of the number. Example:
long x = 5000000000L;
Put an L at the end, e.g.
5400000001L
^
so the compiler knows it's a long
You're having a syntax issue. This will fix your issue nicely:
Long max = new Long(5462205000L);
You need to add the L suffix to indicate this as a Long, otherwise the Java compiler is assuming you're entering an Integer, and this # (anything beyond 2,147,483,647) falls beyond the range of an Integer.
I'm doing some large integer computing, and I need to raise a BigInteger to the power of another BigInteger. The .pow() method does what I want, but takes an int value as an argument. The .modPow method takes a BigInteger as an argument, but I do not want an answer congruent to the value I'm trying to compute.
My BigInteger exponent is too large to be represented as an int, can someone suggest a way to work around this limitation?
You shouldn't try to calculate the power of an extremely large number with another extremely large number. The resulting number would use huge amounts of memory. If you calculate a.pow(b) it will have approximately log(a)*b digits. If b is too large to fit in an integer then for even quite small values of a the result will have several billion digits.
Try to rethink what you are trying to achieve and how to achieve it without doing this operation.
The practical solution is to convert the exponent from a BigInteger to an int.
If you cannot do this because the exponent is too large, your algorithm is unimplementable. The resulting number would almost certainly be too large to represent as a BigInteger. (A BigInteger uses an array of bytes to represent the number, and the maximum size of a Java array is 2**31 - 1 elements no matter how large the heap is.) And even if you implemented a "BiggerInteger" class that would represent the number, you would soon be pushing the limits of the physical memory size of your machine. (And the time taken to do calculate N.pow(M) would be ... NP-tricky ... O((MlogN)^M) I think).
Of course, if the number you are taking the power of is 0, 1 or -1, then the result will easily fit in a BigInteger. But in those cases, there are better ways to calculate the power :-).
You can't find the the value of "Java BigInteger to-the-power BigInteger" because according to JavaDoc "BigInteger must support values in the range -2^Integer.MAX_VALUE (exclusive) to +2^Integer.MAX_VALUE (exclusive) and may support values outside of that range."
So, Java BigInteger does not support anything above 2^Integer.MAX_VALUE. Tha's why pow method does not take any argument above int.
Hope this answer helps.
Assuming we've already accepted the fact that we shouldn't do this for the reasons outlined in all of the previous answers, here's a working solution that can be used for testing purposes only:
Exponent greater than or equal to 0
BigInteger pow(BigInteger base, BigInteger exponent) {
BigInteger result = BigInteger.ONE;
for (BigInteger i = BigInteger.ZERO; i.compareTo(exponent) != 0; i = i.add(BigInteger.ONE)) {
result = result.multiply(base);
}
return result;
}
This will work for both positive and negative bases. You might want to handle 0 to the power of 0 according to your needs, since that's technically undefined.
Exponent can be both positive or negative
BigDecimal allIntegersPow(BigInteger base, BigInteger exponent) {
if (BigInteger.ZERO.compareTo(exponent) > 0) {
return BigDecimal.ONE.divide(new BigDecimal(pow(base, exponent.negate())), 2, RoundingMode.HALF_UP);
}
return new BigDecimal(pow(base, exponent));
}
This uses the first method to return a BigDecimal with 2 decimal places, you can define the scale and rounding mode as per your needs.
Again, you should not do this in a real-life, production-level system.
When I try to find the value of a BigInteger data type for 223,000, I am not able to see the value.
However, for calculations up to 222,000, I could display the BigInteger value without any problems.
Is there any solution or reason for this?
I tried the following in order to make a BigInteger representation of 2^23000:
BigInteger bi = new BigInteger("2");
bi = bi.pow(23000);
System.out.println(bi);
And the number displayed was a very large number spanning 6925 digits. (I won't paste it here as it will span over 100 lines.)
This is with Java 6 SE version 1.6.0_12 in Windows XP.
According the API Specification, BigInteger is an arbitrary-precision integer value which means it should be able to cope with very large integer values.
It works fine for me on GNU/Linux. What do you mean you can't "display" it? What's your code and what error/problem do you get?
this limit for BigInteger is around 2^16 billion, though it has been noted that some functions don't behave correctly after about 2^2 billion.
My guess is that your console or IDE has problems displaying very long lines.
Do you need the whole thing? There is also a BigInteger.modpow(power, modulus) method which raises the integer value to the specified power and returning result % modulus -- commonly used in cryptography. This is also MUCH faster when dealing with very large exponents.