Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Hardcorowa matma i php
Forum PHP.pl > Forum > PHP
NuLL
Hej,

Mam do rozwiazana dwa dziwne problemy w php i nie mam pojecia jak je ugrysc. W php jest kalkulator binarny a ja nie moge go uzysc.

1) 8 do potegi 10000 blink.gif
2) Dodawanie swoch 1000 cyfrowych liczb aarambo.gif

Bede wdzieczny za pomoc w dowolnym wypadku winksmiley.jpg Nie mam zielonego pojecia jak ugrysc ten cokolwiek dziwny jak na php problem. Liczby w drugim sa wczytywanie jako stringi znak po znaku. Kombinowalem z tablicami ale jakos slabo to szlo.

Any ideas ?
mike
Cytat(NuLL @ 2006-03-06 22:44:25)
2) Dodawanie swoch 1000 cyfrowych liczb  aarambo.gif

  1. <?php
  2.  
  3. //$str1 = '12345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    91234567891234567891234567891';
  4. //$str2 = '12345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    912345678912345678912345678912345678912345678912345678912345678912345678912345678
    91234567891234567891234567891';
  5.  
  6. $str1 = '99999';
  7. $str2 = '88888';
  8.  
  9. $arrResult  = array();
  10.  
  11. $int1Count = strlen( $str1 ); // długość pierwszej liczby
  12. $int2Count = strlen( $str2 ); // długość drugiej liczby
  13.  
  14. // ilośc iteracji w pętli
  15. $intLoopCount = ( $int1Count > $int2Count ) ? $int1Count : $int2Count;
  16.  
  17. $arrResult = array_fill( 0, $intLoopCount + 1, 0 );
  18.  
  19. for( $i = ( $intLoopCount - 1 ), $j = 0; $i >= 0 ; $i--, $j++ )
  20. {
  21. $int1 = ( isset( $str1{$i} ) ) ? intval( $str1{$i} ) : 0;
  22. $int2 = ( isset( $str2{$i} ) ) ? intval( $str2{$i} ) : 0;
  23.  
  24. $intSum = $int1 + $int2;
  25.  
  26. $arrResult[ $j ] = $arrResult[ $j ] + ( $intSum % 10 );
  27.  
  28. if( $intSum >= 10 )
  29. {
  30. $arrResult[ $j + 1 ] = floor( $intSum / 10 );
  31. }
  32. }
  33.  
  34. $arrResult = array_reverse( $arrResult );
  35.  
  36. if( $arrResult[ 0 ] == 0 )
  37. {
  38. unset( $arrResult[ 0 ] );
  39. }
  40.  
  41. echo implode( '', $arrResult );
  42.  
  43. //print_r( $arrResult );
  44.  
  45. ?>


Nie wątpię, że można w kilku miejscach zoptymalizować, ale już mi sie nie chciało, bo pól na pół z palca pisane biggrin.gif
~NuLL wybacz obfitośc komentarzy tongue.gif
NuLL
Dzieki za wskazowke smile.gif
dr_bonzo
I tak bylem szybszy tongue.gif (NuLL wie tongue.gif)

  1. <pre>
  2. <?php
  3.  
  4. class BigNumberAdder
  5. {
  6.     public function add( $num_X, $num_Y )
  7.     {
  8.         $length = $num_X->getLength();
  9.         $sum = BigNumber::createZero( $length + 1 ); // bo moze wystapic przeniesienie z ost pozycji: 9999 + 9999 --> 19998
  10.         
  11.         $carry = 0;
  12.         $partialSum = 0;
  13.         
  14.         // cyfry Xa i Yka
  15.         $x = 0;
  16.         $y = 0;
  17.         $s = 0; // cyfra sumy
  18.         // od ostatniej cyfry (najmniej znaczacej -- od jednosci)
  19.         for ( $i = $length - 1; $i >= 0; $i-- )
  20.         {
  21.             $x = $num_X->getDigit( $i );
  22.             $y = $num_Y->getDigit( $i );
  23.             $partialSum = $x + $y + $carry;
  24.             
  25.             print( "$x + $y + $carry =  $partialSum | C = $carry , S = $s<br />" );
  26.             
  27.             $carry = (int)( $partialSum / 10 );
  28.             $s = $partialSum % 10;
  29.             $sum->setdigit( $i + 1, $s );
  30.         }
  31.         
  32.         $sum->setDigit( 0, $carry );
  33.         return $sum;
  34.     }
  35. }
  36.  
  37. class BigNumber
  38. {
  39.     private $digits = array();
  40.     private $length = 0; 
  41.     
  42.     private function __construct()
  43.     {
  44.     }
  45.     
  46.     // tylko N pierwszych cyft jest akceptowanych
  47.     // '1245' --> array( 1,2,4,5)
  48.     static public function createFromString( $strNumber )
  49.     {
  50.         $number = new BigNumber();
  51.         
  52.         $number->length = strlen( $strNumber );
  53.         
  54.         for ( $i = 0; $i < $number->length; $i++ )
  55.         {
  56.             $number->digits[ $i ] = intval( $strNumber{$i} );
  57.         }
  58.         
  59.         return $number;
  60.     }
  61.     
  62.     static public function createZero( $length )
  63.     {
  64.         $number = new BigNumber();
  65.         $number->digits = array_fill( 0, $length, 0 );
  66.         $number->length = $length;
  67.         
  68.         return $number;
  69.     }
  70.     
  71.     public function __toString()
  72.     {
  73.         return implode( '', $this->digits );
  74.     }
  75.     
  76.     public function getLength()
  77.     {
  78.         return $this->length;
  79.     }
  80.     
  81.     public function getDigit( $i )
  82.     {
  83.         return $this->digits[ $i ];
  84.     }
  85.     
  86.     public function setDigit( $i, $digit )
  87.     {
  88.         $this->digits[ $i ] = $digit;
  89.     }
  90. }
  91.  
  92. $num_1 = BigNumber::createFromString( '1245' );
  93. $num_2 = BigNumber::createFromString( '9768' );
  94. //$num_2 = BigNumber::createZero( 4 );
  95.  
  96. $adder = new BigNumberAdder();
  97. $sum = $adder->add( $num_1, $num_2 );
  98.  
  99.  
  100. echo $num_1;
  101. echo " + ";
  102. echo $num_2;
  103. echo " = ";
  104. echo( $sum );
  105. ?></pre>


------------
edit 1:
1) 8 do potegi 10000 blink.gif

8^10000 = (2^3)^10000 = 2^30000 czyli binarnie
100...000 // 30k zer, a zeby to zapisac dziesietnie to trzeba... podniesc 8 do 10000 potegi tongue.gif
Ew mozesz napisac multiplikator podobnie do addera, operujacy na stringu --> tablicy intow
L_Devil
Cytat(L_Devil @ 2006-03-08 19:12:06)
Mój Boże... po cóż tak komplikować, skoro php ma obsługę duuużych liczb winksmiley.jpg bcmath

Nagłówek w manualu: V. BCMath - arytmetyka liczb dużej precyzji
To co innego niż duże liczby.

Tu nie chodzi o licznie iluś miejsc za przecinkiem, tylko przed przecinkiem.
Jak wiesz(?) integer jest ograniczony, a my teo chcemy się pozbyć tongue.gif


Ale BCmath operuje na stringach nie na intach (zapisanych jako typ string.) i może zawierać nawet bardzo duże liczby (co sprawdzałem dokonując obliczeń na liczbach zawierających po 100cyfr. Bez przecinka.)
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.