PHP截止小数

What's a correct way to round (or cut) a PHP float after 3 characters, not counting 0's?

Example:
0.12345 => 0.123
0.012345 => 0.0123
0.0001239 => 0.000124

You can use regex to capture the zeros and dots separated from digits and handle them separately.

$arr = [0.12345,0.012345,0.0001239];

Foreach($arr as $val){
    Preg_match("/([0\.]+)([0-9]+)/", $val, $match);
    Echo $match[1]. Substr(round("0.".$match[2],3),2,3)."
";
}

https://3v4l.org/DZFV4

The regex works by first capture group is grabbing 0 and dots greedy, so any dots or zeros in sequence is captured.
Then the second group captures 0-9, but since the first group is greedy this can't start with 0.
So second group has to start with 1-9 then any 0-9 digits.

You can do this using number_format() and first write function which counts zeroes after point:

function countPrecision($n){
    $p = 0;
    $n = substr($n, 2);
    foreach(str_split($n) as $i)
    {
        if($i == '0')
            $p += 1;
        else
            break;
    }
        return $p;
}

$n = 0.12345; //your number
$p = countPrecision($n) + 3

echo number_format((float) $n, $p, '.', ''); 

You would need something custom to detect the number of zeros made of this PHP - Find the number of zeros in a decimal number and round http://php.net/manual/en/function.round.php

$num1 = 0.12345;
$num2 = 0.012345;
$num3  = 0.0001239;

echo "<br/><br/> Three zero places rounding number 1 : " .  threeZeroPlaceRounding($num1); 
echo "<br/><br/> Three zero places rounding number 2 : " .  threeZeroPlaceRounding($num2); 
echo "<br/><br/> Three zero places rounding number 3 : " .  threeZeroPlaceRounding($num3); 

function threeZeroPlaceRounding($number)
{
    $numzeros = strspn($number, "0", strpos($number, ".")+1);
    $numbplus = $number + 1;

    return round($numbplus, $numzeros + 3) - 1;
}

Output is

Three zero places rounding number 1 : 0.123

Three zero places rounding number 2 : 0.0123

Three zero places rounding number 3 : 0.00012400000000001

Notice i cant do much about rounding for the third number being a little weird

You could use some increase rate which depend how much zeros you have after . and before first number. Instead round you could use substr if you need only cut after 3 character.

$arr = [0.12345, 0.012345, 0.0001239];

$outputArr = [];
foreach ($arr as $arrValue) {
  $zeroCount = strspn($arrValue, "0", strpos($arrValue, ".")+1);
  $increaseRate = pow(10, $zeroCount);

  $outputArr[] = (float)(round($arrValue*$increaseRate, 3)/$increaseRate);
}

print_r($outputArr);