Reputation: 241
I've created an android app that calculates the factorial of an input number. My code is:
void factorial(int x){
if(x>=0){
BigInteger res= new BigInteger("1");
for(int i=x; i>1; i--){
res = res.multiply(BigInteger.valueOf(i));
}
TextView text = (TextView)findViewById(R.id.resultTextView);
text.setText(res.toString());
}
}
It works but when I try calculating factorial 80.000 and more the app stucks for a moment and then exits, reloading the graphical 'desktop' inteface of android. The same piece of code run by a pc creates no problems. How can I fix my app to calculate those values rather than terminate itself?
Thank's in advance.
Upvotes: 0
Views: 444
Reputation: 589
Calculating factorials lead to very big numbers very fast. The factorial of 100 is 9.332621544 E+157. Your factorial is 3.097722251 E+357506! Although BigInteger theoretically has no limitations, I will suggest you to read the answer in this question. Also BigInteger is an immutable class, so creating new ones in every loop is really heavy on your memory. Your code seems correct, but when you deal with factorials most of the times you fall into memory problems.
Upvotes: 1
Reputation: 12953
Try this:
private class FactCalculator extends AsyncTask<Void, Void, BigInteger> {
int number = 0;
public FactCalculator(int i) {
this.number =i;
}
@Override
protected BigInteger doInBackground(final Void... params){
try{
if(number>=0) {
BigInteger res = new BigInteger("1");
for (int i = number; i > 1; i--) {
res = res.multiply(BigInteger.valueOf(i));
}
return res;
}
} catch(Exception e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(final BigInteger result) {
if (result != null) {
TextView text = (TextView)findViewById(R.id.resultTextView);
text.setText(result.toString());
}
}
}
Call it like:
new FactCalculator(80000).execute();
Note:- As others have pointed out in the comments it may be because the value is too large, there may be memory issues or to hold in a String
or in the TextView
,
Upvotes: 2
Reputation: 386
you can put your method in handler
Handler handler=new Handler();
handler.post(new Runnable(){
@Override
public void run() {
if(x>=0){
................
}
handler.postDelayed(this,500);
}
});
Upvotes: 0