Reputation: 61
I have a double $measure and for every beat in my 'song' I add another double. When $measure increments by a whole integer, I want to print this new measure out.
It seems like PHP wants to round these values to make the double look nice for me. Here is an example printout I get:
Measure: 17 Floor: 16 Rounded: 16
from the code:
echo "Measure: " . floatval($measure) . "Floor: " . floor($measure) . " Rounded: " . $roundMeasure . " ";
It seems as though $measure actually contains 16.99999999 or some similar value. Is there any way to read it's actual contents? And better yet, is there any way to use PHP's rounding system so I can just grab the 17? Thanks.
Upvotes: 1
Views: 57
Reputation: 17289
Nice question. I didn't know about this bug/feature/problem in php before.
Here is my approach how to resolve it:
echo "Measure: "
. floor($measure).'.'
. sprintf("%04d",floor(($measure*10000)-floor($measure)*10000)) ."\n";
You can change 1000 to any precision you need.
And keep in mind this trick will work for positive values. You need to adapt it if you can have negative values as well.
Upvotes: 1
Reputation: 57398
better yet, is there any way to use PHP's rounding system so I can just grab the 17
Usually you would use fixed point arithmetic, for example using 64ths, and then convert in output.
Or you could check whether the measure has incremented of a value differing from its floor() by less than, say, 0.00001.
In general you should never rely on a floating point value having an "exact" value - chances are it won't.
As a stopgap, you can maybe change the precision in php.ini:
; The number of significant digits displayed in floating point numbers.
; http://php.net/precision
precision = 17
Otherwise you may move to BCMath:
For arbitrary precision mathematics PHP offers the Binary Calculator which supports numbers of any size and precision up to 2147483647 (or 0x7FFFFFFF) decimals, if there is sufficient memory, represented as strings.
Upvotes: 1