Doing exact real number arithmetic with PHP - php

What is fastest and most easy way of making basic arithmetic operations on strings representing real numbers in PHP? I have a string representing MySQL's DECIMAL value on which I want to operate and return the result to a database after that. I would like to avoid errors introduced by floating-point real number representation.
Is there some standard library like Python's decimal? Are there any FOSS libraries you can recommend?
Regards

You could use the BC math functions:
http://www.php.net/manual/en/ref.bc.php
Or the GMP functions, although they seem to be integer only.
http://www.php.net/manual/en/ref.gmp.php

You can use the bc_math extension, which works exactly how you ask (it's used for arbitrary precision numbers):
$num = '123.456';
$twoNum = bcadd($num, $num);

Related

Math operations precision in PHP 5, PHP 7

When developing calculator in PHP 5+, can programmer get results without thinking on errors of rounding and imprecise representation of decimal numbers?
I mean built-in perfect ways to get, for example, results with given accuracy.
Or each operation like $x = $y * $z + 0.77 must require to develop additional checks in algorithm like rounding (for avoiding errors)?
So errors or imprecision - is up to PHP built-in core or up to developer?
PHP 7 has 64-bit support, what is the improvement on this direction (accuracy of calculations)?
When developing calculator in PHP 5+, can programmer get results without thinking on errors of rounding and imprecise representation of decimal numbers?
Simple answer is No.
Doing arithmetics on decimal basis by using a binary machine like a computer can and will always produce some kind of error.
Many details are explained in this article, it's quite a complex subject.
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Simple example from the decimal world:
The fraction 1/3 can not be expressed as a finite floating point number in decimal notation. Often we try it by writing 0.333333333... but that's not 100% accurate.
Same applies to binary number arithmetics.
[Edit]
If you need a very high degree of precision than you should have a look at phps BC math functions http://php.net/manual/en/ref.bc.php
I don't think there's anything in PHP 7 that will change this. AS #maxhb points out, doing floating point arithmetic is inherently imprecise so you must mind rounding errors.
The 64-bit capability does not fundamentally change this.

How to store huge numbers in PHP

I need to convert a number from 36-th base into an integer. The original number length is about 10 characters which seem to be bigger then PHP's limits for integers.
In my case the original number looks like this: 9F02tq977. When converted I get the following result 8.46332972237E+12.
How can I store huge numbers in PHP?
Since BC Math doesn't work with arbitrary base numbers, you could try using GMP functions if you have them available.
http://www.php.net/manual/en/ref.gmp.php
Otherwise you'll probably have to rewrite your algorithm and write your own arbitrary precision arithemtic implementation of the validation algorithm.
Use a math library like BC Math for big numbers :)
http://be2.php.net/manual/en/book.bc.php

How to parse long value in php?

Need something like intVal() but for bigger numbers, for example: 100001416147426.
Is there a function like this in php? Can't find it.
You should use BC Math, it is designed to numbers of any size with PHP.
The BC Math extensions offers several mathematic functions like:
bcadd Add two arbitrary precision numbers
bccomp — Compare two arbitrary precision numbers
bcsqrt Get the square root of an arbitrary precision number
...
On the PHP documentation site there is a small code example by Charles to round a long number!
consider
$x = (double) "100001416147426";
var_dump($x);
output:
float(1.0000141614743E+14)
coding standard in the past (since C) has been to follow the number with an L/l
$x = 100001416147426L;
This cue's the parser to allocate 64 bits in order to read the number out of the script to compile.
But unless you are running the php x64 this will be useless. Other wise you will have to build it out of a big_number component. Once in a x64 environment intval will automatically expand to a long when exceeding a 32-bit int.

PHP Integer Problem

When I print this number in php 137582392964679 I get this as the output 1.37582392965E+14
All I am doing is a simple
print 137582392964679;
Anyone know why it's doing this? It's as if it's converting to an exponential number automatically. Someone said it's because I'm on a 32 bit machine. If that's the case how can I get around this problem?
Thanks
Check the const PHP_INT_MAX. You're likely over the max, which is typically around 2 billion for a 32bit system.
The maximum number you can store in a signed integer on a 32-bit machine is 2147483647. You can store numbers larger than this in a float but you risk losing some precision.
If that's the case how can I get around this problem?
You probably want to use a big number library. Try GMP:
$sum = gmp_add("123456789012345", "76543210987655");
echo gmp_strval($sum) . "\n";
Result:
200000000000000
Another alternative you could use is BC Math.
If you don't need to do any calculations with these numbers, but just store tham correctly, then store them as strings rather than integers.
I am on a 64 bit machine and it does the same thing. You might want to try using: print number_format(137582392964679);
That number is too big to fit into a 32-bit integer, so yes, it is converting to a floating point type automatically. How to get around it depends on the requirements of your system. If you aren't going to do any arithmetic then just store it as a string. If precision isn't overly important then you could leave it as a float and format it using printf. If precision is important and you can upgrade to 64-bit that should fix it, if you can't upgrade and you need an integer then you could look into using the BC Math PHP extension.
The manual clearly says:
If PHP encounters a number beyond the
bounds of the integer type, it will
be interpreted as a float instead.
Also your number cannot be represented accurately because of inherent floating point limitations, hence it is being approximated.

How much precision for a bcmath PHP library?

I'm writing a PHP library that has a Number class that uses the bcmath extension for arbitrary precision.
I have two questions:
How much slower is bcmath compared to using the built-in int and float types?
bcmath has an optional scale argument (that defaults to 3 digits). For an general purpose Number class that anyone could use, what would be a good level of precision? How do languages like Perl (that have arbitrary precision numbers) deal with scale?
I would decide what range of numbers you need to support. The built in values will be faster than any value that requires calculation and conversion to/from some other format.
Built in integers are good until 32 bits on any system, some systems support 64 bit values. You can check what your system supports by checking the value of the constant PHP_INT_MAX and determine if you want to carry the overhead of the math library after that. For systems with 32 bit integers, anything above 32 bits will be converted to a float automatically. This isn't an issue unless you are using built in functions for things like round, printf, modulus etc.
I was bit by this using modulus to divide traffic coming to my site as well as with formatting integers using %d in sprintf: http://af-design.com/blog/2009/10/28/php-64-bit-integer-modulus-almost/

Categories