Nick
Nick

Reputation: 241

Factorial Calculation Issue

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

Answers (3)

Dimitris
Dimitris

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

Nongthonbam Tonthoi
Nongthonbam Tonthoi

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

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

Related Questions