mpen
mpen

Reputation: 282825

How to format a number so that it has a specific number of digits?

e.g., lets say I want 3 digits, then:

1 -> 1.00
10 -> 10.0
100 -> 100
1000 -> 1000 // don't lop off any numbers, as they're all significant

I thought I could do this via:

number_format($n, max(0,$digits-strlen((string)intval($n))), null, '')

which works for all the above cases, but it fails for 99.99 (giving 100.0 instead of 100).

So I'm not quite sure how to do this. Counting the number of digits before the decimal place won't work because it may change after rounding.

N.B. when I say "digits" I mean the total number of digits, before and after the decimal place. Also note that this is not quite the same as "significant figures", as I count "1000" as "4 digits", which is "1 significant figure" and "0 decimal digits".

Upvotes: 0

Views: 208

Answers (2)

mpen
mpen

Reputation: 282825

I came up with something. Here's the gist of it:

function _whole_digit_count($n) {
    return strlen(abs((int)$n));
}

function _does_round_up($n, $d) {
    return _whole_digit_count(number_format($n, $d, null, '')) > _whole_digit_count($n);
}

function round_digits($size, $digits=3) {
     $wd = _whole_digit_count($size);
     $decimals = $digits - $wd;
     if($decimals > 0) {
        if(_does_round_up($size, $decimals)) {
            --$decimals;
        }
     }

     return number_format($size, $decimals, null, '')
}

Basically, we're using number_format here to do the rounding and add the 0s, but we first have to compute how many decimal places we want. We do that by subtracting off the number of digits to the left of the decimal place.

However, this may cause rounding up such that another digit is added to the whole number. In this scenario we have to subtract off an additional decimal place.

Upvotes: 0

narendra
narendra

Reputation: 1278

try below

number_format($n, max(0,$digits-strlen((string) ( (strlen(str_replace('.','',(string)$n))<=$digits) ? intval($n) : (max(round($n),intval($n))) ))), null, '');

php > $n=1;
php > print number_format($n, max(0,$digits-strlen((string) ( (strlen(str_replace('.','',(string)$n))<=$digits) ? intval($n) : (max(round($n),intval($n))) ))), null, '');
1.00
php > $n=10;
php > print number_format($n, max(0,$digits-strlen((string) ( (strlen(str_replace('.','',(string)$n))<=$digits) ? intval($n) : (max(round($n),intval($n))) ))), null, '');
10.0
php > $n=100;                                                                                                                                                           
php > print number_format($n, max(0,$digits-strlen((string) ( (strlen(str_replace('.','',(string)$n))<=$digits) ? intval($n) : (max(round($n),intval($n))) ))), null, '');
100
php > $n=1000;                                                                                                                                                          
php > print number_format($n, max(0,$digits-strlen((string) ( (strlen(str_replace('.','',(string)$n))<=$digits) ? intval($n) : (max(round($n),intval($n))) ))), null, '');
1000
php > $n=99.99;
php > print number_format($n, max(0,$digits-strlen((string) ( (strlen(str_replace('.','',(string)$n))<=$digits) ? intval($n) : (max(round($n),intval($n))) ))), null, '');
100
php > $n=99.9;
php > print number_format($n, max(0,$digits-strlen((string) ( (strlen(str_replace('.','',(string)$n))<=$digits) ? intval($n) : (max(round($n),intval($n))) ))), null, '');
99.9

Upvotes: 1

Related Questions