# BigInteger: Wert per Methode zuweisen



## BlueDolphin (26. Mrz 2006)

Hey,

ich möchte meiner BigInteger-Variable als Wert das Ergebnis meiner Methode zuweisen.
Leider klappt es nicht so wie ich dachte bzw. ich steige bei BigInteger nicht so richtig durch.
Kann man nur die vordefinierten Methoden verwenden?
Hier mal mein Quellcode:


```
static BigInteger fak( int n ) {
    
    	BigInteger big = BigInteger.ONE;

    	if ( n == 0 || n == 1 ) {
  
      	return big;
      	}

    	if ( n > 1 ) {
      		
      		for ( int i = 1; i <= n; i++ ) {
        		
        		big = big.multiply( BigInteger.valueOf(i) );
        		
        	}
		}
    	return big;
  	}
```


```
BigInteger n = new BigInteger((new BufferedReader(new InputStreamReader(System.in))).readLine());
BigInteger erg = new BigInteger(fak(n)); //hier klemmt es
```

Ich habs auch schonmal so probiert, aber hat auch nicht geklappt:


```
BigInteger erg = new BigInteger("0");
erg = new BigInteger(fak(n));
```

Danke schonmal

LG, Susi


----------



## 0xdeadbeef (26. Mrz 2006)

Das Problem dürfte sein, daß BigInteger keinen Konstruktor hat, dem man wieder BigInteger übergeben kann.
Allerdings ist mir auch nicht ganz klar, warum Du nicht einfach eine direkte Zuweisung benutzt:

```
BigInteger erg = fak(n);
```
Hab's jetzt nicht ausprobiert, aber sollte doch tun, oder?

Ansonsten gibt es IMHO nur einen Trick, eine BigInteger-Variable zu "klonen", nämlich die Konvertierung in einen String, den man dann wieder dem Konstruktor übergeben kann:

```
BigInteger a = BigInteger.ZERO;
BigInteger b = new BigInteger(a.toString());
```
Leider haben ja BigInteger und BigDecimal keine "clone()"-Methode.

Nebenbei: "BigInteger("0")" ist unnötig, weil es ja die "final static"-Deklaration von 0 (ZERO) und 1 (ONE) gibt.


----------



## BlueDolphin (26. Mrz 2006)

hm... 


```
BigInteger erg = fak(n);
```

...funktioniert   

nun muss ich nur noch die Methode auf BigInteger umstricken, aber das werd ich schon hinkriegen  :### ...danke


----------



## 0xdeadbeef (27. Mrz 2006)

Falls Du damit meinst, daß Du den Parameter auf BigInteger ausweiten möchtest: das ist kaum sinnvoll. Bereits die Fakultät des größten positiven 64bit-Integerzahl (long) ist so riesig groß, daß man sie weder berechnen noch darstellen möchte. Mach also aus dem int ein long und das sollte reichen. Die Berechnung großer Zahlen dauert dann mit diesem Algorithmus eh schon ewig.
Ein dramatisch schnellerer Algorithmus ist übrigens dieser hier:


```
class Factorial {

    private BigInteger f;
    private long N;

    private final BigInteger swing(long n) {
        long nN = this.N;
        long s = nN - 1 + ((n - nN + 1) % 4);
        boolean oddN = (nN & 1) != 1;

        for (; nN <= s; nN++) {
            if (oddN = !oddN)
                f = f.multiply(BigInteger.valueOf(nN));
            else
                f = (f.shiftLeft(2)).divide(BigInteger.valueOf(nN));
        }

        if (oddN)
            for (; nN <= n; nN += 4) {
                long m = ((nN + 1) * (nN + 3)) << 1;
                long d = (nN * (nN + 2)) >> 3;

                f = f.multiply(BigInteger.valueOf(m)).divide(BigInteger.valueOf(d));
            }
        else
            for (; nN <= n; nN += 4) {
                long m = (nN * (nN + 2)) << 1;
                long d = ((nN + 1) * (nN + 3)) >> 3;

                f = f.multiply(BigInteger.valueOf(m)).divide(BigInteger.valueOf(d));
            }
        this.N = nN;
        return f;
    }

    private final BigInteger recFactorial(int n) {
        if (n < 2)
            return BigInteger.ONE;
        BigInteger result = recFactorial(n / 2);
        return result.multiply(result).multiply(swing(n));
    }

    BigInteger factorial(int n) {        
        N = 1;
        f = BigInteger.ONE;
        return recFactorial(n);
    }
}
```


----------

