Skip to content
This repository has been archived by the owner on Jan 6, 2020. It is now read-only.

Why is 14 the magic precision number? #13

Open
ramsey opened this issue Nov 23, 2017 · 3 comments
Open

Why is 14 the magic precision number? #13

ramsey opened this issue Nov 23, 2017 · 3 comments
Labels

Comments

@ramsey
Copy link
Owner

ramsey commented Nov 23, 2017

Originally posted at moontoast#9, @lhfeng asks:

why is the 14 is the magic precision number?

@ramsey
Copy link
Owner Author

ramsey commented Nov 23, 2017

I admit that the code comment "14 is the magic precision number" is very mysterious. I should probably update that with more explanation.

According to the PHP manual page for the float type:

The size of a float is platform-dependent, although a maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (the 64 bit IEEE format).

So, the default floating-point precision in PHP is 14 (unless this is changed in php.ini).

Consider the following (using psysh):

>>> ceil(23.000000000000000999)
=> 23.0
>>> ceil(23.000000000000001999)
=> 24.0

The two places where this is used in BigNumber is in the ceil() and floor() methods. In order to ensure that BigNumber properly handles the rounding according to PHP's default rules, I need to use a precision of 14. If I were to use a precision less than 14, then BigNumber would calculate the ceil() of 23.000000000000001999 as 23.0, which is incorrect.

@lhfeng
Copy link

lhfeng commented Apr 19, 2018

I have another problem.
1/3 * 0.15 result is 0.05 in Calculator,
image

but ,
$bn = new \Moontoast\Math\BigNumber(1,2);
$bn->divide(3)->multiply(0.15);
result is 0.04
how to do it the result is 0.05 in Moontoast\Math.

@ramsey
Copy link
Owner Author

ramsey commented Apr 19, 2018

This library uses bcmath, and this is an unfortunate problem with any kind of arbitrary precision arithmetic.

I recommend reading http://floating-point-gui.de/ for more information on what's going on.

This should illustrate the problem, though:

>>> $value = bcdiv(1, 3, 2);
=> "0.33"
>>> bcmul($value, 0.15, 2);
=> "0.04"
>>> $value = bcdiv(1, 3, 50);
=> "0.33333333333333333333333333333333333333333333333333"
>>> bcmul($value, 0.15, 50);
=> "0.04999999999999999999999999999999999999999999999999"

@ramsey ramsey pinned this issue Jan 5, 2020
Repository owner locked as resolved and limited conversation to collaborators Jan 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants