Portrety Uliczne Nieznajomych - zobacz wyjątkową galerię portretów z warszawskich ulic
ZALOGUJ SIĘ
login:
hasło:
przypomnij hasło
załóż konto użytkownika
(i zobacz kilka porad gratis)
   
WYSZUKIWARKA I DZIAŁY
całe porady  tytuły
zaznacz działy do przeszukania
(brak wyboru = wszystkie działy)
PHP
MySQL >
PostgreSQL
SQLite
Perl
Java
XML
XSLT
XPath
WML
SVG
RegExp
Wyszukiwarki
Ochrona
VBScript
Google Plus
XHTML/CSS
JavaScript
Grafika
Flash
Photoshop
Windows
Linux
Bash
Apache
Procmail
E-biznes
Explorer
Opera
Firefox
Inne porady
   
KURSY, DOKUMENTACJE
Własne:
XHTML/CSS
JavaScript
ActionScript
WML, RSS, SSI
Pozostałe:
PHP
MySQL
Java API
więcej...
   
użytkowników online: 19
W CZYM MOGĘ POMÓC?


   
OPINIE UŻYTKOWNIKÓW
Na początku, kiedy zobaczyłem, że ktoś chce jakiejś opłaty za pomoc w tworzeniu stron ryknąłem śmiechem - potem przyszły problemy... i zaryzykowałem. Druga rzecz to: nie chciałem "kopiować". Ale prawda jest taka: są lepsi, bardziej doświadczeni i... czasem trzeba poprosić o pomoc, a jak poświęca się na to trzecią cześć życia, to nic dziwnego, że nie chce się swoich "sekretów" zdradzać za darmo. Skorzystałem z "algorytmy.pl" i naprawdę jestem z tego w 100% zadowolony, polecam - dla zawodowców (co się uczą) i amatorów (można skorzystać z gotowego rozwiązania).

Tomasz Czypicki
Cybernoxa

   
GALERIA FOTOGRAFII
   
PODRĘCZNIK PHP 5.x, 4.x, 3.x - częściowo spolszczony / źródło: www.php.net

[Spis] [A] [B] [C] [D] [E] [F] [G] [H] [I] [J] [K] [L] [M] [N] [O] [P] [Q] [R] [S] [T] [U] [V] [X] [W] [Z]

V. BCMath - arytmetyka liczb dużej precyzji

Wstęp

Dla potrzeb obliczeń arytmetycznych o dużej precyzji, PHP oferuje Kalkulator Binarny (ang. Binary Calculator). Kalkulator Binarny operuje na liczbach dowolnej wielkości i precyzji, zapisanych jako typ string.

Wymagania

Począwszy od wersji PHP 4.0.4, biblioteka libbcmath jest dostarczana razem z PHP. To rozszerzenie nie wymaga zatem żadnych zewnętrznych bibliotek.

Instalacja

These functions are only available if PHP was configured with --enable-bcmath. In PHP 3, these functions are only available if PHP was not configured with --disable-bcmath.

PHP w wersji dla systemów Windows posiada wbudowaną obsługę dla tego rozszerzenia. Nie trzeba ładować żadnych dodatkowych rozszerzeń aby korzystać z tych funkcji.

Konfiguracja czasu wykonywania

Na działanie tych funcji wpływają ustawienia zawarte w pliku php.ini.

Tabela 1. BC math configuration options

NameDefaultChangeableChangelog
bcmath.scale"0"PHP_INI_ALLAvailable since PHP 5.0.0.
Szczegóły i definicje dotyczące stałych PHP_INI_* znajdują się w rozdziale Dodatek H.

Oto krótkie wyjaśnienie dyrektyw konfiguracji.

bcmath.scale integer

Number of decimal digits for all bcmath functions. See also bcscale().

Typy zasobów

To rozszerzenie nie posiada żadnych rodzajów zasobów.

Stałe predefinopwane

To rozszerzenie nie posiada żadnych stałych.

Spis treści
bcadd -- Dodaje dwie liczby o dużej precyzji
bccomp -- Porównuje dwie liczby o dużej precyzji
bcdiv -- Dzieli dwie liczby o dużej precyzji
bcmod --  Dzieli w module liczbę o dużej precyzji
bcmul -- Mnoży dwie liczby o dużej precyzji
bcpow --  Podnosi liczbę o dużej precyzji do potęgi
bcpowmod --  Raise an arbitrary precision number to another, reduced by a specified modulus
bcscale --  Ustala domyślną precyzję obliczeń BCMath
bcsqrt --  Wyciąga pierwiastek kwadratowy z liczby o dużej precyzji
bcsub --  Odejmuje jedną liczbę o dużej precyzji od drugiej



User Contributed Notes

stonehew ut gm a il det com
25-Nov-2004 06:31

Like any other bc function, you can't trust the last couple of digits, but everything else seems to check out.  If you want to use this for anything important, you may want to verify this against other sources of pi before use.  This function calculates 100 decimal places of pi in 329 iterations -- not exactly fast (each iteration calls the factorial function, from below, twice), so I try to avoid calling it more than once.

<?
//arbitrary precision pi approximator
//author tom boothby
//free for any use

function bcpi() {
  
$r=2;
  
$i=0;
  
$or=0;

   while(
bccomp($or,$r)) {
      
$i++;
      
$or=$r;
      
$r = bcadd($r,bcdiv(bcmul(bcpow(bcfact($i),2),
                      
bcpow(2,$i+1)),bcfact(2*$i+1)));
   }

   return
$r;
}

?>


stonehew et g m a i l dut com
24-Nov-2004 08:20

I hacked these taylor expansions up to make diagrams for some physics homework.  I don't think you'll be wanting to do any real science with PHP... but what the hell, why not?  I plan to implement either a spigot algorithm or something similar to generate pi in the near future.

<?
// arbitrary precision sin and cosine functions
// author tom boothby
// free for any use

function bcfact($n) {
  
$r = $n--;
   while(
$n>1) $r=bcmul($r,$n--);
   return
$r;
}

function
bcsin($a) {
  
$or= $a;
  
$r = bcsub($a,bcdiv(bcpow($a,3),6));
  
$i = 2;
   while(
bccomp($or,$r)) {
      
$or=$r;
       switch(
$i%2) {
         case
0$r = bcadd($r,bcdiv(bcpow($a,$i*2+1),bcfact($i*2+1))); break;
         default:
$r = bcsub($r,bcdiv(bcpow($a,$i*2+1),bcfact($i*2+1))); break;
       }
      
$i++;
   }
   return
$r;
}

function
bccos($a) {
  
$or= $a;
  
$r = bcsub(1,bcdiv(bcpow($a,2),2));
  
$i = 2;
   while(
bccomp($or,$r)) {
      
$or=$r;
       switch(
$i%2) {
         case
0$r = bcadd($r,bcdiv(bcpow($a,$i*2),bcfact($i*2))); break;
         default:
$r = bcsub($r,bcdiv(bcpow($a,$i*2),bcfact($i*2))); break;
       }
      
$i++;
   }
   return
$r;
}

?>


Diabolos at GMail dot com
28-Oct-2004 08:42

Here's a function to compute the natural exponential function in arbitrary precision using the basic bcMath arithmetic operations.

EXAMPLE:
To compute the exponential function of 1.7 to 36 decimals:

$y = bcExp("1.7", 36);

The result:
4.331733759839529271053448625299468628

would be returned in variable $y

NOTE:
In practice, the last couple of digits may be inaccurate due to small rounding errors.  If you require a specific degree of precision, always compute 3-4 decimals beyond the required precision.

The program code for the natural exponential function is:
******************************************

  Function bcExp($xArg, $NumDecimals)

{
   $x = Trim($xArg);

   $PrevSum  = $x - 1;
   $CurrTerm = 1;
   $CurrSum  = bcAdd("1", $x, $NumDecimals);
   $n        = 1;

   While (bcComp($CurrSum, $PrevSum, $NumDecimals))

  {
   $PrevSum  = $CurrSum;
   $CurrTerm = bcDiv(bcMul($CurrTerm, $x, $NumDecimals), $n + 1, $NumDecimals);
   $CurrSum  = bcAdd($CurrSum, $CurrTerm, $NumDecimals);

   $n++;
  }

   Return $CurrSum;
}


robert at scabserver dot com
03-Jun-2004 06:58

I spent some time looking for how to generate a large random number, in the end I've settled for reading directly from /dev/urandom

I know this is a *nix only solution, but I figured that it might come in handy to someone else.

The value $size is the size in bits, it could be simplified greatly if you want the size in bytes, but bits was more helpful to what I needed.

<?php
function bcrand($size)
{
  
$filename = "/dev/urandom";
  
$handle = fopen($filename, "r");
  
$bin_urand = fread($handle, ceil($size/8.0));
  
fclose($handle);
  
$mask = (($size % 8 < 5) ? '0' : '') . dechex(bindec(str_repeat('1', $size % 8))) . str_repeat('FF', floor($size/8));
  
$binmask = pack("H*", $mask);
  
$binrand = $binmask & $bin_urand;
  
$hexnumber = unpack("H*", $binrand);
  
$hexnumber = $hexnumber[''];
  
$numlength = strlen($hexnumber);
  
$decnumber = 0;
   for(
$x = 1; $x <= $numlength; $x++)
   {
      
$place = $numlength - $x;
      
$operand = hexdec(substr($hexnumber,$place,1));
      
$exponent = bcpow(16,$x-1);
      
$decValue = bcmul($operand, $exponent);
      
$decnumber = bcadd($decValue, $decnumber);
   }
   return
$decnumber;
}
?>


pulstar at mail dot com
16-Apr-2003 02:12

A little comment for the simplified example above: you can do base converting without BCMath functions using only math operators, but you will not able to manage very large values or work with strings to compress or scramble data. If you have BCMath installed in your system it worth use it for this.


oliver at summertime dot net
01-Mar-2003 07:12

A simplier Version of the Script above:

function dec2base($dec, $digits) {
 $value = "";
 $base  = strlen($digits);
 while($dec>$base-1) {
  $rest = $dec % $base;
  $dec  = $dec / $base;
  $value = $digits[$rest].$value;
 }
 $value = $digits[intval($dec)].$value;
 return (string) $value;
}

function base2dec($value, $digits) {
 $value = strtoupper($value);
 $base  = strlen($digits);
 $size  = strlen($value);
 $dec  = '0';
 for ($loop = 0; $loop<$size; $loop++) {
  $element = strpos($digits,$value[$loop]);
  $power  = pow($base,$size-$loop-1);
  $dec    += $element * $power;
 }
 return (string) $dec;
}

$digits = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
echo dec2base('1000', $digits);


pulstar at mail dot com
20-Sep-2002 04:23

A found a little fix to do in my base2dec() function:
The line "if($base<37) $value=strtolower($value);" should be removed if you want to specify another digits for your base conversions. Change it this way:

if(!$digits) {
$digits=digits($base);
if($base<37) {
$value=strtolower($value);
}
}

Another example using these functions is to generate a key for a session, to name temporary files or something else:

srand((double) microtime()*1000000);
$id=uniqid(rand(10,999));
$mykey=dec2base(base2dec($id,16),64);

$mykey is a base64 value, which is a good key for passing thru an URL and also is shorter than a MD5 string (it will be allways 11 chars long). If you need something more secure, just scramble the 64 digits in the digits() function.

Well, I hope you enjoy it.

Regards,
Edemilson Lima


pulstar at mail dot com
20-Sep-2002 05:27

A good use for BCMath functions:
The functions below can convert a number in any base (from 2 to 256) to its decimal value and vice-versa.

// convert a decimal value to any other base value
function dec2base($dec,$base,$digits=FALSE) {
   if($base<2 or $base>256) die("Invalid Base: ".$base);
   bcscale(0);
   $value="";
   if(!$digits) $digits=digits($base);
   while($dec>$base-1) {
       $rest=bcmod($dec,$base);
       $dec=bcdiv($dec,$base);
       $value=$digits[$rest].$value;
   }
   $value=$digits[intval($dec)].$value;
   return (string) $value;
}

// convert another base value to its decimal value
function base2dec($value,$base,$digits=FALSE) {
   if($base<2 or $base>256) die("Invalid Base: ".$base);
   bcscale(0);
   if($base<37) $value=strtolower($value);
   if(!$digits) $digits=digits($base);
   $size=strlen($value);
   $dec="0";
   for($loop=0;$loop<$size;$loop++) {
       $element=strpos($digits,$value[$loop]);
       $power=bcpow($base,$size-$loop-1);
       $dec=bcadd($dec,bcmul($element,$power));
   }
   return (string) $dec;
}

function digits($base) {
   if($base>64) {
       $digits="";
       for($loop=0;$loop<256;$loop++) {
           $digits.=chr($loop);
       }
   } else {
       $digits ="0123456789abcdefghijklmnopqrstuvwxyz";
       $digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
   }
   $digits=substr($digits,0,$base);
   return (string) $digits;
}

The purpose of digits() function above is to supply the characters that will be used as digits for the base you want. NOTE: You can use any characters for that when you convert to another base, but when you convert again to the decimal base, you need to use the same characters or you will get another unexpected result.


benjcarson at digitaljunkies dot ca
08-Jul-2002 02:00

In addition to my last note, here are  a quick pair of functions to convert exponential notation values into bcmath-style number strings:

// exp2int converts numbers in the
// form "1.5e4" into strings
function exp2int($exp) {
  list($mantissa, $exponent) = spliti("e", $exp);
  list($int, $dec) = split("\.", $mantissa);
  bcscale ($dec);
  return bcmul($mantissa, bcpow("10", $exponent));
}

// float2exp converts floats into exponential notation
function float2exp($num) {

  if (0 == $num) { return "0E1";}
  list($int, $dec) = split("\.", $num);

  // Extract sign
  if ($int[0] == "+" || $int[0] == "-") {
   $sign = substr($int, 0,1);
   $int = substr($int, 1);
  }

  if (strlen($int) <= 1) {  // abs($num) is less than 1
   $i=0;
   for ($i=0; $dec[$i]=='0' && $i < strlen($dec); $i++);
     $exp = -$i-1;     
     $mantissa = substr($dec,$i,1).".".substr($dec,$i+1);                             
   } else { // abs($num) is greater than 1
   $i=0;
   for ($i=0; $int[$i]=='0' && $i < strlen($int); $i++);
     $exp = strlen($int)-1 - $i;
     $mantissa = substr($int,$i,1).".".substr($int,$i+1).$dec;
   }

  return ($sign . $mantissa . "E" . $exp);
}


benjcarson at digitaljunkies ca
08-Jul-2002 01:17

Note that bcmath doesn't seem to handle numbers in exponential notation (i.e. "1e4"), although PHP considers such a value a number.

example:

$exp1 = "1E5";
$exp2 = "2E4";
$ans1 = bcadd($exp1, $exp2, 3);
$ans2 = $exp1 + exp2;
echo("bcadd: $exp1 + $exp2 = $ans1");
echo("php: $exp1 + $exp2 = $ans2");

// Output:
bcadd: 1E5 + 2E4 = 0.000
php: 1E5 + 2E4 = 120000

Just a gotcha if you're using passing PHP numbers into bcmath functions...


 

 
  © 1996-2012 & Reporter.plmiejscao serwisieabonamentwarunki korzystaniaRSSkontakt