1

I use bcmath for my calculations and I want to round some numbers to n decimal places. Now, I know enough to avoid floats, but what I'm wondering is if the following example is safe and/or if there are better ways to do it?

$number = '123.456'; // number to round as string
$roundedNumber = (string) round($number, 2); // round and cast
// calculations using bcmath continue here...

I think it is, I've ran some experiments and so far it always returned expected result but I'd like second opinion as I'm not 100% positive that in some particular case casting string to float and then float back to string will not output undesired result.

Or is there a better way to do this?

EDIT: before you answer:

bc* functions do not round when third parameter is specified, they just trim the output.

number_format does not allow selection of rounding mode, so it's out

EDIT: What do I consider safe?

Given the number as string and rounding mode, will the function always output correct/expected result and not be affected by casting to float? I guess that what I'm being afraid of is following: I provide number say 12.345 as string to round function, it gets casted as float and then my number isn't 12.345 anymore, it may be 12.345xxxx because we all know how float can be represented internally. I'm afraid of that affecting the rounding output. I believe there will be no harm when I cast to 12.345 to string, it will always be '12.345', not '12.345....' right?

  • Define "safe". What are the possible conditions under which this has to work? If you're using `bcmath` everywhere, then why not write your own `round()` routine that works purely with strings? For instance: https://stackoverflow.com/a/1653826/3986005 – KIKO Software Jun 29 '19 at 17:11
  • Possible duplicate of [How to ceil, floor and round bcmath numbers?](https://stackoverflow.com/questions/1642614/how-to-ceil-floor-and-round-bcmath-numbers) – Charlotte Dunois Jun 29 '19 at 17:15
  • None of the solutions posted in the question both of you linked does not account for rounding mode. I'd like to keep it simple and use what already exists unless I absolutely need to write my own implementation. I'll edit the question to define safe. – scrnjakovic Jun 29 '19 at 17:24
  • 1
    You're right, casting to floats is not "safe". You could adapt the `bcround()` function, I refered to, to any rounding mode you want, even all of them. – KIKO Software Jun 29 '19 at 18:19

0 Answers0