PHP: BCMath Arbitrary Precision 수학 함수 - Manual
PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links | my php.net 
search for in the  
<aspell_suggestbcadd>
view the version of this page
Last updated: Wed, 29 Jan 2003

IV. BCMath Arbitrary Precision 수학 함수

이 함수는 PHP 컴파일 설정시 --enable-bcmath 옵션이 주어졌을 경우에만 사용 가능합니다.

참고: 라이센스가 바뀔때까지 BCMATH 라이브러리는 PHP 소스 배포판에 포함되지 않고 따로 배포됩니다. tar-gzip형식의 BCMATH라이브러리를 다음의 url에서 다운 받을수 있습니다: . 더 자세한 정보를 원하면 PHP 배포판에서 README.BCMATH 를 읽어보세요. (역자주: PHP 4.0.4버전 이후부터는 BCMATH 라이브러리 라이센스가 LGPL로 바뀌어서 PHP소스 배포판에 포함되어 있습니다.)

차례
bcadd -- 두 arbitrary precision number를 더하기
bccomp -- 두 arbitrary precision number 비교
bcdiv -- arbitrary precision number 나누기
bcmod --  arbitrary precision number의 나머지 구하기
bcmul -- 두arbitrary precision number 곱하기
bcpow --  arbitrary precision number를 제곱하기
bcpowmod --  Raise an arbitrary precision number to another, reduced by a specified modulus.
bcscale --  모든 bc 수학함수의 기본 scale 파라미터 지정.
bcsqrt --  arbitray precision number의 제곱근 구하기
bcsub --  한 arbitrary precision number에서 다른 arbitrary precision number를 빼기


User Contributed Notes
BCMath Arbitrary Precision 수학 함수
add a note add a note
raarts at netland dot nl
06-Apr-2001 11:23

The README.BCMATH currently reads:

As of PHP 4.0.4, the BC math library routines are bundled in the
standard PHP distribution.  There is no need to install any additional
files.

Thanks goes to Phil Nelson, for releasing the BC math library routines
under the LGPL.

benjcarson at digitaljunkies ca
07-Jul-2002 11: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...

benjcarson at digitaljunkies dot ca
08-Jul-2002 12: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);
}

pulstar at mail dot com
20-Sep-2002 03: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.

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

Here some examples of the previous post:

a) Converting bases:

Converting from decimal to binary:
$x=192;
$y=dec2base($x,2);

From binary to decimal:
$x=1100101001;
$y=base2dec($x,2);

Decimal to octal:
$x=192;
$y=dec2base($x,8);

Octal to decimal:
$x=18107362;
$y=base2dec($x,8);

Decimal to hexadecimal:
$x=139245;
$y=dec2base($x,16);

Hexadecimal to decimal:
$x="e0f13d";
$y=base2dec($x,16);
// note: you must use smallcaps unless you specify another digits. Example:
// $x="E0F13D";
// $y=base2dec($x,16,"0123456789ABCDEF");

Decimal to base32:
$x=92109743;
$y=dec2base($x,32);

Decimal to base64:
$x=92109743;
$y=dec2base($x,64);

Decimal to base256:
$x=92109743;
$y=dec2base($x,256);

As you can see, you can use any value from 2 to 256 as a valid base. The size of the number ($x) doesn't matter, because BCMath is very powerful.

You can use these functions to convert a string to a value that can be passed by an URL. Example:

$string="*Here Anything+Exactly-As#You$Want@, using&any%characters(";
$decimal=base2dec($string,256);
$base64=dec2base($decimal,64);
<a href="script.php?var=<?php echo $base64 ?>">Click me</a>

You can pass the content of the $base64 var by an URL. It only will have letters, numbers, the "_" and "-". After you get it from the URL, you must do the inverse way to get the original string again:

$decimal=base2dec($var,64);
$string=dec2base($decimal,256);
echo $string;

b) "Compressing" data:

Converting an e-mail address to another base:
$digits="@0123456789abcdefghijklmnopqrstuvwxyz-.";
// these are the 39 characters used by e-mail addresses
$email="[email protected]";
$base64=decbase(basedec($email,64),39,$digits);
$base256=decbase(basedec($email,256),39,$digits);

$restored_email=decbase(basedec($base64,39,$digits),64);
$restored_email2=decbase(basedec($base256,39,$digits),256);

// $base64 is the equivalent of the email address in a base64 value, which can be passed by an URL and is shorter than the original e-mail address in ASCII.
// $base256 is the same in a base256 value, which can be stored in a database and is even shorter than $base64.
By this method you can compress informations that do not use the all 256 characters, such as names, addresses, etc. You must figure which characters these informations will use and use it as your digits.
To compress and "encrypt" you only need to scramble the digits used.

As these functions can be used for some kind of encryption too, you only need to use another sort of digits, scrambled any way you want. Just remember to use the same sequence of digits for reconversion, or you will get another thing. Here an example:

$digits="z6QgkmR1ZP irK9Ws?lbNCjnYwht.vyaJx5IM78-fODdUFHucpoS,2GEX403eALVTBq"; // 67 characters that can be used in names, for example
$data="This is my string. Can you See, what I want to do?";
$encrypted=decbase(basedec($data,256),67,$digits);
$decrypted=decbase(basedec($encrypted,67,$digits),256);

Well, I didn't tested my examples above, but the functions works for sure (I did spend a whole night working on it)...  :-)

pulstar at mail dot com
20-Sep-2002 02: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

oliver at summertime dot net
01-Mar-2003 05: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
16-Apr-2003 12: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.
add a note add a note

<aspell_suggestbcadd>
 Last updated: Wed, 29 Jan 2003
show source | credits | mirror sites 
Copyright © 2001-2003 The PHP Group
All rights reserved.
This mirror generously provided by: /
Last updated: Thu May 22 21:11:29 2003 CEST