1

php function round not working correctly. I have number 0.9950. I put code:

$num = round("0.9950", 2);

And I get 1.0? Why?? Why I can't get 0.99?

Jadasdas
  • 869
  • 4
  • 19
  • 39

3 Answers3

2

You can add a third parameter to the function to make it do what you need. You have to choose from one of the following :

  • PHP_ROUND_HALF_UP
  • PHP_ROUND_HALF_DOWN
  • PHP_ROUND_HALF_EVEN
  • PHP_ROUND_HALF_ODD

This constants are easy enough to understand, so just use the adapted one :) In your example, to get 0.99, you'll need to use :

<?php echo round("0.9950", 2, PHP_ROUND_HALF_DOWN); ?>

DEMO

Rafik Tighilt
  • 2,071
  • 1
  • 15
  • 27
  • 2
    ...but something which looks like half in decimal may not be once converted to binary - see https://stackoverflow.com/questions/21895756/why-are-floating-point-numbers-inaccurate/21895757#21895757 – symcbean Jan 21 '18 at 16:18
  • Thank you for the information, I'm investigating the topic, but this code seems to handle some "known" floating numbers that can't be represented in binary (0.1, 0.2, 0.7 etc...) AND their additions (rounding 0.1 + 0.2 for example). – Rafik Tighilt Jan 21 '18 at 17:34
  • PHP did some tricks here: `ini_set('precision', 17); echo round("0.9950", 2, PHP_ROUND_HALF_DOWN); //0.98999999999999999 ` – Lebecca Aug 11 '21 at 03:42
0

When you round 0.9950 to two decimal places, you get 1.00 because this is how rounding works. If you want an operation which would result in 0.99 then perhaps you are looking for floating point truncation. One option to truncate a floating point number to two decimal places is to multiply by 100, cast to integer, then divide again by 100:

$num = "0.9950";
$output = (int)(100*$num) / 100;
echo $output;

0.99

This trick works because after the first step 0.9950 becomes 99.50, which, when cast to integer becomes just 99, discarding everything after the second decimal place in the original number. Then, we divide again by 100 to restore the original number, minus what we want truncated.

Demo

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • You could also use `floor()` instead of casting. – Nigel Ren Jan 21 '18 at 15:41
  • In my [answer](https://stackoverflow.com/a/61913718/9583480), I'm only looking at the first two digits after decimal point, but casting didn't always behave as expected. – s3c May 20 '20 at 13:01
0

Just tested in PHP Sandbox... PHP seems funny sometimes.

<?php
    $n = 16.90;
    echo (100*$n)%100, "\n"; // 89
    echo (int)(100*$n)%100, "\n"; // 89
    echo 100*($n - (int)($n)), "\n"; // 90
    echo (int)(100*($n - (int)($n))), "\n"; // 89
    echo round(100*($n - (int)($n))), "\n"; // 90
s3c
  • 1,481
  • 19
  • 28