I've read the Floating-Point guide about using the float type in PHP. The answer is using the BC Math extension. Using strings can represent the float as an exact type and prevent float and integer issues.
Meanwhile I haven't found any good examples on Github and this site working with the BC math extension. What is a clean way to force PHP to use strings, how to evaluate them?
Especially what is the best way to use the BC Math extension with MySQL DECIMAL data types?
My example test with PHP 5.4.10, the right answer is: 0.2999999999996
<?php
bcscale(13);
$a = '0.3';
$b = '0.0000000000004';
echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.2999999999996
echo '<hr />';
$a = "0.3";
$b = "0.0000000000004";
echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.2999999999996
echo '<hr />';
$a = 0.3;
$b = 0.0000000000004;
echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.3000000000000
echo '<hr />';
$a = '0.3';
$b = '0.0000000000004' + 0;
echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.3000000000000
echo '<hr />';
$a = (string) 0.3;
$b = (string) 0.0000000000004;
echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.3000000000000
echo '<hr />';
$a = strval(0.3);
$b = strval(0.0000000000004);
echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.3000000000000
?>
A float is a number with a decimal point and can be extended to exponential form. Float is also called a floating-point number. Various ways to represent float values are 3.14, 4.75, 5.88E+20, etc. If the values are very large and contain decimals in PHP, it automatically converts the type to float.
Float is also called a floating-point number. Various ways to represent float values are 3.14, 4.75, 5.88E+20, etc. If the values are very large and contain decimals in PHP, it automatically converts the type to float. The float has a maximum precision of about 14 digits.
PHP Best Practices A short, practical guide for common and confusing PHP tasks Last revised & maintainers Introduction What PHP version are we using? Storing passwords PHP and MySQL PHP tags Auto-loading classes Single vs. double quotes define() vs. const Caching PHP opcode PHP and Memcached PHP and regex Serving PHP Sending email
Floating point values have a limited precision. Hence a value might not have the same string representation after any processing. That also includes writing a floating point value in your script and directly printing it without any mathematical operations. $str = strtr($str,',','.'); Beware of NaN and strings in PHP.
The best way is not to use BC Math but start using GMP. Just have a look on benchmark. GMP is up to 30 times faster then BC Math.
I use DECIMAL(12, 0) AND DECIMAL(27,0) and php start suck apr. at 10^19 and greater. Demo:
//PHP Version 5.3.10, FreeBSD 8.2-RELEASE amd64
$a = pow(10, 18);
var_dump($a, $a > ($a - 1), ($a - 1) > $a, ($a - 1) == $a, ($a - 1) === $a);
// int(1000000000000000000)
// bool(true)
// bool(false)
// bool(false)
// bool(false)
$a = pow(10, 19);
var_dump($a, $a > ($a - 1), ($a - 1) > $a, ($a - 1) == $a, ($a - 1) === $a);
// double(1.0E+19)
// bool(false)
// bool(false)
// bool(true)
// bool(true)
I made Decimal
class, here is simple implementation. Later you can implement the same interface but with native php math operations or with BC math or whatever you want. Yupp, there will be overhead for functions calls and objects creation, but we write code that other developers can read, aren't we?
P.S. Guys from PHP Secure Communications has their own implementation - Math_BigInteger, which cover all potential need, but is too heavy for my tasks.
Update: since PHP 5.6 GMP implemented internal operators overloading, so gmp resources may be used as regular numbers (mostly).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With