Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for PHP float usage

Tags:

php

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
?>
like image 579
Mike Avatar asked Mar 24 '13 16:03

Mike


People also ask

What is a float in PHP?

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.

What is the maximum precision of float in PHP?

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.

What are some of the best practices for using PHP?

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

How do you write a floating point string in PHP?

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.


1 Answers

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

like image 59
pinepain Avatar answered Nov 13 '22 13:11

pinepain