Most inputs to the program work fine but when i use large numbers e.g. 20 the value is incorrect. Is there a way I could convert the decimal numbers and output them as binary? Thank you.
int n = Comp122.getInt("What number would you like to make a factorial?");
int factorial = 1;
for (int i = 1 ; i<=n ; i++) {
factorial*=i;
System.out.println(factorial);
}
You’re encountering integer overflow at 13!, which exceeds the largest number that an int can hold, which is 231 (about 2.1 x 109).
You can change the type of your variable from int to long, which can hold 263 (about 1.9 x 1019), but that too will exceed its limit at 20!
To handle arbitrarily large numbers, use the BigInteger class as your variable type. Your code would then something like:
BigInteger factorial = BigInteger.ONE;
for (int i = 2; i < n; i++) {
factorial = factorial.multiply(néw BigInteger(i + ""));
}
By the way, to output an integer as binary or hex:
System.out.println(Integer.toBinaryString(n));
System.out.println(Integer.toHexString(n));
n! becomes very big and probably Integer cannot hold it as Integer has a limitation of 2,147,483,647.
That's not the problem of output, but rather you hit an overflow.
If you have a infinite range of input that could potentially fit in a BigInteger, you could try BigInteger. Otherwise, probably you'd like to use some unlimited data structure such as String. And do the calculation digit by digit.
Something like: https://www.geeksforgeeks.org/multiply-large-numbers-represented-as-strings/
20 the value is incorrect?
value of 20! = 2,432,902,008,176,640,000.
In java, an integer can properly handle any positive value less than 2,147,483,648.
int | 4 bytes | Stores whole numbers from -2,147,483,648 to 2,147,483,647
So, using int you can not handle this type of big value.
long datatype can be used for factorials only for n <= 20.
For larger values of n, we can use the BigInteger class from the java.math package, which can hold values up to 2^Integer.MAX_VALUE:
Related
In Java, create a do-while loop that starts at 2, and displays the number squared on each line while the number is less than 1,000,000. And this is what I have:
int k = 2;
do {
System.out.println(k);
k *= k;
} while(k < 1000000);
The problem is the output, somehow it is getting stuck at 0 and infinitely looping through 0 to print those out? I don't believe it is due to the fact that the number is out of int range, since a 32 bit number's range is around +/- 2 billion... But when I switch up the data type of k to be long everything works fine... Why is this?
It really is due to int. The sequence produced this way is
2
4
16
256
65536
0
And then it remains zero. Note that it never rises above 1000000.
With a long, the number after 65536 would be 4294967296 (which does not fit in an int, but does fit in a long), so it stops.
This is perhaps more obvious in hexadecimal, the sequence then reads (with sufficiently long integers)
2
4
0x10
0x100
0x10000
0x100000000
An int can only keep the lowest 8 hexadecimal digits, so 0x100000000 becomes 0.
Your code to print squares should be
int k = 2;
do {
System.out.println(k*k);
k++;
}while(k < 1000000);
As you are storing the result in same variable, your output is growing exponentially
We tried just for fun to create a for loop like below. We assumed that the number we get would be very high but we got 0. Why is it 0 and not something big?
We even tried it with a long because we thought it might be bigger than a int.
Thanks in advance.
private static void calculate() {
int currentSolution = 1;
for (int i = 1; i < 100; i++) {
currentSolution *= i;
}
System.out.println(currentSolution);
}
Your int is wrapping round to -2147483648 when it reaches +2147483647.
By an amazing coincidence1, a multiplication by zero is introduced into your product.
See for yourself: write
if (currentSolution == 0){
// What is the value of i?
}
You'll need a BigInteger to evaluate 100!.
1 Really it's not that amazing: it's just that 100! has 232 as a factor.
Your for loop calculates the factorial of 100, i.e. 1 * 2 * 3 * ... * 99 * 100, also written as 100! which equals 9.332621544×10157
The range of int is -2,147,483,648 to 2,147,483,647 and the range of long is -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, so with a number that is 10157 you've hit multiplication overflow long before you even get close to the end of the for loop.
The overflow eventually results in all bits eventually zeroing out, thus producing the result 0.
Your datatypes are too small, even if you use long, so you cannot do this calculation with basic types. So you get an overflow, where the values become negative, and at some point 0. Therefore, the result is still zero after every loop.
You can see that by printing the currentSolution in the loop.
In order to get the correct solution, try using BigInteger:
public static void calculate() {
BigInteger currentSolution = BigInteger.valueOf(1);
for (int i = 1; i < 100; i++) {
currentSolution = currentSolution.multiply(BigInteger.valueOf(i));
}
System.out.println(currentSolution);
}
This outputs the correct solution: 933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000
You re basically calculating 100!, which is approximately 9.3e+157, whereas a long maximum value is 2^64 -1 so approximately 1.8e+19.
It cant fit, thats why you have 0.
Why is the following code is not giving expected output even though it works for some small inputs? Here I am expecting the sum of all integers in the range between "a" and "b". Is the logic used wrong or are some other things wrong?
class RangeSum {
public static void main(String args[] ){
// BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long i = Long.valueOf("99");
long j = Long.valueOf("1000000000000");
long ans = 0L;
/*if(i<0 || i>Math.pow(10, 18)){
//throw new Exception("Wroong Input.");
}
if(i<0 || i>Math.pow(10, 18)){
//throw new Exception("Wroong Input.");
}*/
if (j>i){
long sumTill_j = (j*(j+1))/2;
long sumTill_i = ((i-1)*i)/2;
ans = sumTill_j - sumTill_i;
System.out.println(ans);
}else{
long sumTill_i = (i*(i+1))/2;
long sumTill_j = ((j-1)*j)/2;
ans = sumTill_i - sumTill_j;
System.out.println(ans);
}
}
}
The largest possible number that you can represent in a long is 263 - 1, which is about 9.2 x 1018. If your calculation exceeds that, then the calculation will overflow without any exceptions being thrown and you will get the wrong answer.
In your case:
1,000,000,000,000 * (1,000,000,000,000 + 1) / 2
is about 5 x 1023 if my mental arithmetic is correct. That will overflow.
Solution: use BigInteger.
This is the result of integer overflow. What this means is, even though you're using the largest primitive you can (long), the value you're trying to calculate exceeds the maximum representable value.
A long can only store a value that is 263-1, which is around 9 quintillion, or 9.22 * 1018. The value that you're trying to generate from your sum exceeds that value with a difference of around 499 sextillion.
Don't fret; you can still calculate this insanely large value, but you have to make a few changes, notably, you can no longer use long. Move to BigInteger instead.
You can't use any of the primitive operators instead, but you can call functions which you would expect to be available, such as add, subtract, multiply, and divide.
Here is the first part of the code converted to use it; I leave the other half as an exercise for the reader.
BigInteger i = BigInteger.valueOf(99L);
BigInteger j = BigInteger.valueOf(1000000000000L);
BigInteger ans = BigInteger.ZERO;
if (j.compareTo(i) > 0) {
BigInteger sumTill_j = (j.multiply(j.add(BigInteger.ONE))).divide(BigInteger.valueOf(2L));
BigInteger sumTill_i = ((i.subtract(BigInteger.ONE)).multiply(i)).divide(BigInteger.valueOf(2L));
ans = sumTill_j.subtract(sumTill_i);
System.out.println(ans);
}
1000000000000 = 0xE8D4A51000 which needs at least 40 bits to store. Therefore multiplying j by j+1 needs an 80-bit type to store. The result is overflowing long type as it has only 64 bits. If you really want to do that the only way is using a bigint type like BigInteger
Btw why don't just use 99L and 1000000000000L? Calling valueOf is just redundant and slow
long i = Long.valueOf("99");
long j = Long.valueOf("1000000000000");
In short: j * (j + 1) gets overflow when j = 1,000,000,000,000.
Java's signed long has 64 bits, which has 2^63 - 1 or 9,223,372,036,854,775,807 as the maximum value.
Your integers are too high in value. Try using another type of integer instead, as it will help those larger values. Here is a good website that explains BigInteger in detail: http://www.tutorialspoint.com/java/math/java_math_biginteger.htm
public static void main(String[]args){
int A[]={2,4,6,9,5,4,5,7,12,15,21,32,45,5,6,7,12};
int multi= 1;
for (int i=0; i<A.length; i++) {
multi *= A[i];
}
System.out.println("The product of the numbers in the array is " + multi );
//I keep getting a negative value but when I shorten the array
//to a few numbers I don't have any problems.
}
That's called overflow.
An integer overflow occurs when an arithmetic operation attempts to create a numeric value that is too large to be represented within the available storage space. [Wikipedia - Integer Overflow]
ints can represent a maximum of (2^32)-1. Your multiplication gives a result that is higher than that value, so it generates overflow.
Change multi type to long and you won't have this problem (but only for that particular case: if you exceed the maximum value representable by a long, you'll have that problem again)
As said, changing the type to long will only postpone the problem, you can solve it by using a BigInteger, which can handle arbitrary-precision integers.
But use it only if you really have to. If you know that your app will do calculations without exceeding the long max representable value, then use a long, as the BigInteger is not a primitive and will be much slower than a long.
Start by declaring multi as a long. When a value exceeds Integer.MAX_VALUE i 'overflows' and becomes negative. The maximum integer value is just more than 2 billion, so it happens quite soon.
You encounter a negative value, it is because the multi value exceeds the Max value of Integer (2^31 -1).
You need to make the change as follows:
From
int multi= 1;
To
long multi= 1;
try this
public static void main(String[]args){
int A[]={2,4,6,9,5,4,5,7,12,15,21,32,45,5,6,7,12};
long multi= 1;
for (int i=0; i<A.length; i++) {
multi *= A[i];
}
System.out.println("The product of the numbers in the array is " + multi );
//I keep getting a negative value but when I shorten the array
//to a few numbers I don't have any problems.
}
I thought of writing a program to evaluate factorial of a given integer.
Following basics I wrote the below code in java :
long fact(int num){
if(num == 1)
return 1;
else
return num*fact(num-1);
}
But then I realized that for many integer input the result may not be what is desired and hence for testing directly gave input as 100.
My doubt was true as Result I got was "0"(cause result might be out of range of long).
So,I am just curious and eager to know as how may I make my program work for inputs<=150.
I would appreciate any valid solution in C programming language or Java.
BigInteger is your class. It can store integers of seemingly any size.
static BigInteger fact(BigInteger num) {
if (num.equals(BigInteger.ONE))
return BigInteger.ONE;
else
return num.multiply(fact(num.subtract(BigInteger.ONE)));
}
If you're not after a naive approach of factorial computation, you should do some research into the problem. Here's a good overview of some algorithms for computing factorials: http://www.luschny.de/math/factorial/conclusions.html
But like the other answers suggest, your current problem is that you need to use a large number implementation (e.g. BigInt) instead of fixed size integers.
In C Language, you can use array to store factorial of large number.
my reference: Calculate the factorial of an arbitrarily large number, showing all the digits. it very helpful post.
I made small changes in code to convert into C.
int max = 5000;
void factorial(int arr[], int n){//factorial in array
if (!n) return;
int carry = 0;
int i=max-1;
for (i=max-1; i>=0; --i){
arr[i] = (arr[i] * n) + carry;
carry = arr[i]/10;
arr[i] %= 10;
}
factorial(arr,n-1);
}
void display(int arr[]){// to print array
int ctr = 0;
int i=0;
for (i=0; i<max; i++){
if (!ctr && arr[i])
ctr = 1;
if(ctr)
printf("%d", arr[i]);
}
}
int main(){
int *arr = calloc(max, sizeof(int));
arr[max-1] = 1;
int num = 100;
printf("factorial of %d is: ",num);
factorial(arr,num);
display(arr);
free(arr);
return 0;
}
And its working for 100! see: here Codepad
I would like to give you links of two more useful posts.
1) How to handle arbitrarily large integers suggests GPU MP
2) C++ program to calculate large factorials
In java you have the BigInteger that can store arbitrary big integers. Unfortunately there is no equivelent in C. You either have to use a third-party library or to implement big integers on your own. Typical approach for this is to have a dynammically-allocated array that stores each of the digits of the given number in some numeric system(usually base more than 10 is chosen so that you reduce the total number of digits you need).
A decimal (base 10) digit takes about 3.3 bits (exactly: log(10)/log(2)). 100! is something like 158 digits long, so you need 158 * 3.3 = 520 bits.
There is certainly no built in type in C that will do this. You need some form of special library if you want every digit in the factorial calculation to be "present".
Using double would give you an approximate result (this assumes that double is a 64-bit floating point value that is IEEE-754 compatible, or with similar range - the IEEE-754 double format will give about 16 decimal digits (52 bits of precision, divided by the log(10)/log(2) like above). I believe there are more than 16 digits in this value, so you won't get an exact value, but it will calculate some number that is within a 10 or more digits.