-1

I'm trying to round a float to the nearest quarter, with three decimal places, but I can't seem to do it in PHP. Here's what I've got so far:

$longitude = 145.6360003;
echo floor($longitude * 4) / 4;

I get 145.5 back, but the value I'm looking for is 145.625. I also tried this snippet from the php.net comments but still nothing.

How do I trim a number to 3 decimal places, then round to the nearest quarter, preserving the three decimal places?

DrFrankly
  • 61
  • 3
  • 8
  • i understood you want to use a round function for making a number in 3 decimal figure, but how can you change `145.6360003` to `145.625`?? It should be `145.636`. – Murad Hasan Apr 24 '16 at 12:26
  • @FrayneKonok Because, as the question states, he wants the nearest quarter - but what he's really asking is the nearest eight. – MatsLindh Apr 24 '16 at 12:28
  • oops....my eyes goes away. – Murad Hasan Apr 24 '16 at 12:30
  • 1
    I'm not clear what it means to "round to a quarter" if there are three decimal places - a quarter to three decimal places would be 0.250. Do you mean round to the nearest 40th (0.025)? – IMSoP Apr 24 '16 at 12:31

1 Answers1

1

.125 isn't the nearest quarter, it's the nearest eighth.

Your example is correct, if you want the nearest quarter, it's 145.5. If you want the nearest eighth, that would be 145.625:

>>> math.floor(lon * 8) / 8
145.625

or in PHP:

$longitude = 145.6360003;
echo floor($longitude * 8) / 8;

You should also consider having round($result, 3) as the last step because of the inherent inaccuracy of floating point numbers.

IMSoP
  • 89,526
  • 13
  • 117
  • 169
MatsLindh
  • 49,529
  • 4
  • 53
  • 84
  • sir, If the number is `1231.245` then what will be the result??? I think it has to`1231.250`. – Murad Hasan Apr 24 '16 at 12:41
  • Makes perfect sense when you explain it that way. Thanks for the explanation and tip about rounding :) – DrFrankly Apr 24 '16 at 13:54
  • Or did you want `floor($longitude * 40) / 40;`, the next-lowest quarter after the first decimal digit? -- In the example above, do you want to round to `1231.125` (8) or to `1231.225` (40)? – Lutz Lehmann Apr 24 '16 at 13:55
  • @MatsLindh: Actually, while you're generally correct about the "inherent inaccuracy" of floating point numbers, this question is an exceptional case: while most questions ask for rounding to the tenth, hundredth, or another decimal place, this question asks for rounding to the nearest quarter, a binary decimal place which binary floating-point number implementations (like the one used in PHP) are well suited for. – Peter O. Apr 24 '16 at 21:06
  • @MatsLindh: Moreover, due to the intended application domain of the numbers (they're latitudes and longitudes), there is almost no practical risk of inaccuracy (besides the inaccuracy in measuring the coordinates themselves). – Peter O. Apr 24 '16 at 21:10
  • @PeterO. Sure - the inaccuracy is relevant for display only - to avoid suddenly having "0000000001" as the trailing value for a floating point number. And yes - the 1/8 is an exceptional case. Which is why the "safe" way should be chosen regardless, to avoid any sudden surprises later (if it's changed, manipulated in other ways, a different ratio is introduced, or if the future maintainer (or this maintainer) doesn't understand why 1/8 is exceptional). – MatsLindh Apr 24 '16 at 22:25
  • @LutzL: I wound up fiddling and used 40, as it provided more "inaccuracy" for my purposes. My PHP script takes lat / long pairs (from a mobile app), makes them accurate to about 1300 feet and stores the results, plus a count, so I can make a heatmap of popular travel destinations. Cheers for the 40 hint :) – DrFrankly Apr 25 '16 at 13:55