1

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.

SchweeDubulus
  • 51
  • 1
  • 5
  • http://floating-point-gui.de/ –  May 20 '18 at 22:10
  • Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) –  May 20 '18 at 22:11
  • It's similar but I'm specifically asking more about why/how PHP prints out the rounded variable when it's actually not rounded, and if there is any way to work with the two different values. – SchweeDubulus May 20 '18 at 22:13
  • show where `$measure` comes from? – Alex May 20 '18 at 22:13
  • $measure starts at 1 before the loop begins then another double is added for each iteration. The value added on is typically 1/3, 1/6, etc. – SchweeDubulus May 20 '18 at 22:16

2 Answers2

1

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.

LSerni
  • 55,617
  • 10
  • 65
  • 107
1

Nice question. I didn't know about this bug/feature/problem in php before.

Here is my approach how to resolve it:

https://ideone.com/JgDDvo

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.

Alex
  • 16,739
  • 1
  • 28
  • 51