men som sagt bliver tallet alt for stor til at kunne rummes i php's 32bit heltals variabler, de fleste af tallene vlil nok blive skrevet som floatingpoint tal med en eksponent.
Jo det er muligt. men så skal du selv definere en mulitplikation-funktion der virker på strenge snarere end på php's int variabler. det er et rimeligt stort arbejde.
Jeg lavede engan en 'vilkårligt stort tal'-regner i Java, den kan du få en kopi af hvis du vil. Jeg gider ikke selv genprogrammere den i php :-))
class testBigNumber { public static void main ( String[] args ) { BigNumber tal = new BigNumber( 2 ); BigNumber tal2; for (int i=1; i<=64; i++ ) { tal2 = tal.mult( tal ); System.out.println( tal +" + " +tal +" = " +tal2 ); System.out.println(); tal = tal2; } } } // end of class testBigNumber
// the class BigNumber add, subtract and multiply very large signed numbers class BigNumber implements Cloneable {
public BigNumber( ) { // make a BigNumber vith the value zero value = null; sign = true; } // end of constructor BigNumber
public BigNumber( long val ) { // make a BigNumber vith the value given sign = ( val >= 0 ); if ( sign ) { value = (val==0) ? null : new Segment( val ); } else { value = Segment.add( new Segment( -(val+1) ), null, 1 ); } } // end of constructor BigNumber
public BigNumber( String nrStr ) { // convert String to BigNumber if ( nrStr.charAt(0) == '-' ) { sign = false; value = new Segment( nrStr.substring( 1 ) ); } else { sign = true; value = new Segment( nrStr ); } value.normalize(); // remove leading 0-segments } // end of constructor BigNumber
private BigNumber( boolean sgn, Segment val ) { this.sign = sgn; this.value = val; } // end of constructor BigNumber
public BigNumber add( long val ) { return this.add( new BigNumber( val ) ); } // end of method add
public BigNumber add( BigNumber other ) { if ( sign == other.sign ) { return new BigNumber( sign, Segment.add( value, other.value, 0 ) ); } switch ( Segment.compareTwo( value, other.value ) ) { case 1: return new BigNumber( sign, Segment.sub( value, other.value, 0 ) ); case 0: return new BigNumber(); default: return new BigNumber( other.sign, Segment.sub( other.value, value, 0 ) ); } } // end of method add
public BigNumber sub( long val ) { return this.sub( new BigNumber( val ) ); } // end of method sub
public BigNumber sub( BigNumber other ) { other.sign = ! other.sign; BigNumber res = this.add( other ); other.sign = ! other.sign; return res; } // end of method sub
public BigNumber mult( long val ) { return this.mult( new BigNumber( val ) ); } // end of method mult
public BigNumber mult( BigNumber other ) { if ( Segment.compareTwo( other.value, null ) == 0 || Segment.compareTwo( value, null ) == 0 ) { return new BigNumber(); } return new BigNumber( (sign==other.sign), Segment.mult( value, other.value ) ); } // end of method mult
public BigNumber div( long val ) { if ( val == 0 ) throw new Error( "division by zero" ); return this.div( new BigNumber( val ) ); } // end of method div
public BigNumber div( BigNumber other ) { if ( other.value == null ) throw new Error( "division by zero" ); if ( this.compareTo( other ) < 0 ) { return new BigNumber(); } return new BigNumber( (sign==other.sign), Segment.div( value, other.value ) ); } // end of method div
public String toString () { // convert BigNumber to String return (sign?"":"-") +( (value==null) ? "0" : value.toString() ); } // end of method toString()
public int compareTo( BigNumber other ) { int temp = Segment.compareTwo( this.value, other.value ); return (temp==0) ? 0 : ((temp==1)?sign:other.sign) ? temp : -temp; } // end of method compareto
public Object clone ( ) { return new BigNumber ( sign, (value==null)?null:(Segment)value.clone() ); } // end of function clone
} // end of class BigNumber
// The class Segment store an absolute integer value of arbitrary size class Segment implements Cloneable {
private static final int SMAX = 1000000000; private static final int SMIN = 0;
Segment nxtSeg; int number;
Segment () { number = 0; nxtSeg = null; } // end of constructor Segment
Segment( long nr ) { // assert nr >= SMIN if ( nr < SMAX ) { number = (int)nr; nxtSeg = null; } else { number = (int)(nr % SMAX); nxtSeg = new Segment( nr / SMAX ); } } // end of constructor Segment
private Segment( long nr, Segment next ) { // assert nr >= SMIN, nr < SMAX number = (int)nr; nxtSeg = next; } // end of constructor Segment
Segment( String nrStr ) { int temp = nrStr.length() -9; number = Integer.parseInt( nrStr.substring( (temp<0)?0:temp ), 10 ); nxtSeg = (temp<=0)?null:new Segment( nrStr.substring(0,temp) ); } // end of constructor Segment
private static Segment nSeg( long val, Segment next ) { // assert val >= SMIN, nr < SMAX if ( val == 0 && next == null ) return null; return new Segment( val, next ); } // end of method add
static Segment add( Segment op1, Segment op2, int carry ) { if ( op1 == null && op2 == null && carry == 0 ) return null; int sum = simVal(op1) +simVal(op2) +carry; if ( sum < SMAX ) return nSeg( sum, add( simSeg(op1), simSeg(op2), 0 ) ); return nSeg( sum-SMAX, add( simSeg(op1), simSeg(op2), 1 ) ); } // end of method add
static Segment sub( Segment op1, Segment op2, int borrow ) { // assert: 0 < compareTwo(op1,op2) if ( op1 == null && op2 == null && borrow == 0 ) return null; int diff = simVal(op1) -(simVal(op2) +borrow); if ( diff >= SMIN ) return nSeg( diff, sub( simSeg(op1), simSeg(op2), 0 ) ); return nSeg( diff+SMAX, sub( simSeg(op1), simSeg(op2), 1 ) ); } // end of method sub
// local multiply and accumulate function used only by mult( Segment, Segment ); private void multAdd( long nr, Segment op2, long carry ) { // assert nr >= SMIN, nr < SMAX long val = this.number +(nr * simVal(op2)) +carry; this.number = (int)(val % SMAX); carry = val / SMAX; if ( carry == 0 && simSeg(op2) == null ) return; if ( nxtSeg == null ) nxtSeg = new Segment(); this.nxtSeg.multAdd( nr, simSeg(op2), carry ); } // end of method multAdd
static Segment mult( Segment op1, Segment op2 ) { if ( op1 == null ) return null; Segment op0 = new Segment(); if ( op1.nxtSeg != null ) op0.nxtSeg = mult( op1.nxtSeg, op2 ); if ( op1.number != 0 ) op0.multAdd( op1.number, op2, 0 ); return op0; } // end of method mult
static Segment div( Segment op1, Segment op2 ) { return new Segment(); } // end of method div
Segment normalize() { if ( nxtSeg != null ) nxtSeg = nxtSeg.normalize(); return ( nxtSeg == null && number == 0 ) ? null: this; } // end of method normalize
public String toString() { if ( this.nxtSeg == null ) return Integer.toString( number, 10 ); String temp = "00000000" + number; return this.nxtSeg.toString() +temp.substring( temp.length()-9 ); } // end of method toString
Segment getSeg () { // extend with preceding 0's as needed return ( nxtSeg == null ) ? new Segment() : nxtSeg; } // end of method getSeg
static Segment simSeg( Segment ptr ) { return (ptr==null)?null:ptr.nxtSeg; } // end of method simSeg
static int simVal( Segment ptr ) { return (ptr==null)?0:ptr.number; } // end of method simVal
static int compareTwo( Segment op1, Segment op2 ) { // compare Segment lists if ( op1 == op2 ) return 0; int temp = compareTwo( simSeg(op1), simSeg(op2) ); if ( temp != 0 ) return temp; if ( simVal(op1) > simVal(op2) ) return 1; if ( simVal(op1) < simVal(op2) ) return -1; return 0; } // end of method compareTwo
public Object clone ( ) { return new Segment( number, (nxtSeg==null)?null:(Segment)nxtSeg.clone() ); } // end of function clone
} // end of local class Segment;
Men jeg testede lige. den kan heller ikke komme hele vejen :( den går i stakoverflow før den når de 64. I det mindste vil den give dig et indtryk at at de tal blive STORE.
mvh JakobA
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.