|
|
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 |
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 |
| |