Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Format number to N significant digits in PHP

Tags:

php

I would like to format (round) float (double) numbers to lets say 2 significant digits for example like this:

1        => 1
11       => 11
111      => 110
119      => 120
0.11     => 0.11
0.00011  => 0.00011
0.000111 => 0.00011

So the arbitrary precision remains same

I expect there is some nice function for it already built in, but could not find any so far

I was pointed to How to round down to the nearest significant figure in php, which is close but doesn't work for N significant digits and I'm not sure what it does with 0.000XXX numbers

like image 678
Pavel Niedoba Avatar asked Jun 03 '16 15:06

Pavel Niedoba


2 Answers

To get a number rounded to n significant figures you need to find the size of the number in powers of ten, and subtract that from n.

This works fine for simple rounding:

function sigFig($value, $digits)
{
    if ($value == 0) {
        $decimalPlaces = $digits - 1;
    } elseif ($value < 0) {
        $decimalPlaces = $digits - floor(log10($value * -1)) - 1;
    } else {
        $decimalPlaces = $digits - floor(log10($value)) - 1;
    }

    $answer = round($value, $decimalPlaces);
    return $answer;
}

This will give the following:
0.0001234567 returns 0.0001235
123456.7 returns 123500

However a value such as 10 to four significant figures should strictly be represented as 10.00 to signify the precision to which the value is known.

If this is the desired output you can use the following:

function sigFig($value, $digits)
{
    if ($value == 0) {
        $decimalPlaces = $digits - 1;
    } elseif ($value < 0) {
        $decimalPlaces = $digits - floor(log10($value * -1)) - 1;
    } else {
        $decimalPlaces = $digits - floor(log10($value)) - 1;
    }

    $answer = ($decimalPlaces > 0) ?
        number_format($value, $decimalPlaces) : round($value, $decimalPlaces);
    return $answer;
}

Now 1 is displayed as 1.000

like image 101
Adam Milward Avatar answered Oct 21 '22 03:10

Adam Milward


With little modification to possible duplicate, answer by Todd Chaffee:

public static function roundRate($rate, $digits)
{
    $mod = pow(10, intval(round(log10($rate))));
    $mod = $mod / pow(10, $digits);
    $answer = ((int)($rate / $mod)) * $mod;
    return $answer;
}
like image 1
Pavel Niedoba Avatar answered Oct 21 '22 05:10

Pavel Niedoba