19

I get a number from database and this number might be either float or int.

I need to set the decimal precision of the number to 3, which makes the number not longer than (regarding decimals) 5.020 or 1518845.756.

Using PHP

round($number, $precision)

I see a problem:

It rounds the number. I need a function to only cut the decimals short, without changing their values which round( ) seems not to follow.

Nick
  • 1,334
  • 10
  • 14
Mostafa Talebi
  • 8,825
  • 16
  • 61
  • 105

5 Answers5

36

You can use number_format() to achieve this:

echo number_format((float) $number, $precision, '.', ''); 

This would convert 1518845.756789 to 1518845.757.

But if you just want to cut off the number of decimal places short to 3, and not round, then you can do the following:

$number = intval($number * ($p = pow(10, $precision))) / $p;

It may look intimidating at first, but the concept is really simple. You have a number, you multiply it by 103 (it becomes 1518845756.789), cast it to an integer so everything after the 3 decimal places is removed (becomes 1518845756), and then divide the result by 103 (becomes 1518845.756).

Demo

Amal Murali
  • 75,622
  • 18
  • 128
  • 150
  • 1
    This doesn't work if `intval($number * ($p …))` cannot be represented as an integer. For example: `$number = 10000000; $precision = 3;` results in `1410065.408` on a 32 bit machine. – Nisse Engström Aug 08 '16 at 22:38
  • @NisseEngström I don't know what are you doing, since you start with an integer and you end with nonsense... – arod Jan 18 '17 at 18:24
  • 2
    @arod: That's *my* point. If *number* × *multiplier* is too large to be represented as an integer, then you end up with nonsense. On a 64-bit machine, you need larger numbers and precision to end up with nonsense values. – Nisse Engström Jan 18 '17 at 18:37
  • @NisseEngström: First solution is more preferable in such cases. Don't georgecj11's solution below have the same problem? – Amal Murali Jan 21 '17 at 14:12
15

Its sound like floor with decimals. So you can try something like

floor($number*1000)/1000
georgecj11
  • 1,600
  • 15
  • 22
3

If I understand correctly, you would not want rounding to occur and you would want the precision to be 3.

So the idea is to use number_format() for a precision of 4 and then remove the last digit:

$number = '1518845.756789';
$precision = 3;

echo substr(number_format($number, $precision+1, '.', ''), 0, -1);

Will display:

1518845.756

rather than:

1518845.757

Links : number_format() , substr()

Amal Murali
  • 75,622
  • 18
  • 128
  • 150
Uours
  • 2,517
  • 1
  • 16
  • 21
  • 1
    This will not work if the 4th decimal is a `9` and the 5th decimal causes it to roll over. Try it with `$number = '0.00096'` for example. – Nisse Engström Aug 08 '16 at 22:14
2

See this answer for more details.

function numberPrecision($number, $decimals = 0)
{
    $negation = ($number < 0) ? (-1) : 1;
    $coefficient = pow(10, $decimals);
    return $negation * floor((string)(abs($number) * $coefficient)) / $coefficient;
}
Dima
  • 311
  • 2
  • 5
0
$num=5.1239;
$testnum=intval($num*1000)/1000;
echo $testnum; //return 5.123
taras
  • 6,566
  • 10
  • 39
  • 50
Pavla
  • 11
  • 1