0

We all know that dealing with float point numbers may meet troubles like this:

echo intval(0.58*100);//57

And using bcmath functions will help:

echo bcmul('0.58', '100', 2);//58.00

php manual:

//Multiply the left_operand by the right_operand.
string bcmul(string $left_operand , string $right_operand [, int $scale = 0 ])

But why will this work?
I noticed that the first two parameters should be string, I wonder if this is because these functions deal with numbers in string way?

Piyush Gupta
  • 2,181
  • 3
  • 13
  • 28
luoyu2015
  • 1
  • 2
  • The string type is only used to prevent that the language parser creates values of a numeric type. That way the actual computation function gets unmodified values. And obviously it _is_ possible to do correct mathematical computations on a computer. The trick simply is to prevent loosing precision during the input phase. – arkascha Mar 11 '16 at 11:20
  • Thank you but I don't understand the second half of your answer,how to prevent losing precision during the input phase?The input float point number may can not be expressed in finite length binary number,but truncate it obviously will lose precision...@arkascha – luoyu2015 Mar 14 '16 at 13:17
  • Since you hand over the values as strings, not as numeric types, you can have any precision you want, since no conversion is done. If you want you can for example hand over a string that holds the number Pi with 1000000 digits, no problem. Then it is up to the bcmath library internally to make use of that. But the trick is _not_ to create a floating point value which php (and any other language) normally would do when handing over such number as numeric type as opposed to a string. – arkascha Mar 14 '16 at 13:48
  • I think I know it now, bcmath function know the precision at once when the number is given and handle them in this precision,so of course it will not lose precision.Thank you so much.@arkascha – luoyu2015 Mar 14 '16 at 15:09

1 Answers1

1

The numbers used with bcmath should be represented as strings because if you use native php number formats like integer or float then you simply can not express all values.

Simplest example ist type integer. Integers are limited to a maximum value as defined by the constant PHP_INT_MAX. If you would try to write down any number bigger than that php would not be able to represent that exact number. This is due to the fact that php uses a pre defined amount of memory to store integers.

See this example:

echo PHP_INT_MAX;
echo "\n";
echo PHP_INT_MAX + 1;

Output is:

9223372036854775807
9.2233720368548E+18

As you can see the second value is not 9223372036854775808 which would be correct but some other (similar) value.

maxhb
  • 8,554
  • 9
  • 29
  • 53
  • Thanks for answering.I know the string problem now ,but I still don't know why the bcmath function will not lose precesion? – luoyu2015 Mar 14 '16 at 12:57
  • PHP uses fixed sizes for it's build in number types (integer/float). bcmatch is a library that does not use predefined amounts of memory for number representation. In other words: It behaves different because IT IS different. – maxhb Mar 14 '16 at 13:49
  • After reading your and arkascha's answer I think I get it , the key is use bcmath itself's memory to storage the input numbers, so it can handle ARBITRARY precision numbers. – luoyu2015 Mar 14 '16 at 15:14