skip to Main Content

I want to convert numbers like below in php

EX1: 0.00004123456 => 0.00004 
EX2: 0.000000004123456 => 0.000000004
EX3: 2.04123456 => 2.04
EX4: 2.44123456 => 2.4

I did not get results from the round() and more solutions

2

Answers


  1. Let’s do it as we would manually. Convert to string. Find a . and then the first non 0 char. substr then turn to number back.

    <?php
    
    
    $number = 0.0001432323;
    $number2 = 14.323232;
    $number3 = -6.098;
    $number4 = -6.09;
    $number5 = 12;
    
    
    function rounder($number)
    {
        $str = (string) $number;
        $index_dot = strpos($str, ".");
        if ($index_dot === false) {
            return $number;
        }
    
        // find first non zero after the dot_index
        $index_first_non_zero = false;
        for ($i = $index_dot + 1; $i < strlen($str); $i++) {
            if ($str[$i] != "0") {
                $index_first_non_zero = $i;
                break;
            }
        }
        if ($index_first_non_zero === false) {
            return $number;
        }
        return (float) substr($number, 0, $index_first_non_zero + 1);
    }
    
    echo rounder($number) . "n";
    echo rounder($number2) . "n";
    echo rounder($number3) . "n";
    echo rounder($number4) . "n";
    echo rounder($number5) . "n";
    

    Output:

    0.0001
    14.3
    -6.09
    -6.09
    12
    
    Login or Signup to reply.
  2. You can do it with a regex.

    function trimToFirst($number) {
        // this is done to handle the cases of scientific notation
        // which can mess up the logic with very small or very large
        // numbers
        $strNum = sprintf('%f',$number);
        preg_match('/^-?d+.?d*?([1-9].*?|0$)/',$strNum,$matches);
        
        if(empty($matches)) {
            return $number;
        } else {
            return (float)$matches[0];
        }
    }
    
    $numArr = [15, -7.130, 2.07014430, 0.00004123456, 0.0123456, 2.04123456, 2.44123456, .051, 0, -0, 0.000000];
    
    foreach($numArr as $originalNumber) {
        $number = trimToFirst($originalNumber);
        if (strpos($number, '.') !== false) {
            // convert the number to a string format without scientific notation
            // and trim trailing zeroes
            echo rtrim(sprintf('%f', $number), '0');
        } else {
            // an integer, leave it as it is
            echo $number;
        }
        
        echo PHP_EOL;
    }
    

    Which outputs:

    15
    -7.1
    2.07
    0.00004
    0.01
    2.04
    2.4
    0.05
    0
    0
    0
    

    Test it here.


    Explanation

    The regular expression which was used functions like this (as explained in this regex101.com snippet ):

    • ^ asserts position at start of a line
    • - matches the dash character
    • ? matches the previous dash between zero and one times. This is done to handle cases when there are both positive and negative integers
    • d matches a digit (equivalent to [0-9])
    • + matches the previous token between one and unlimited times, as many times as possible,
    • . matches the decimal point
    • ? matches the previous decimal point between zero and one times. This is used to handle cases when there are integers and decimal numbers
    • d as before, this matches a digit
    • *? matches the previous token between zero and unlimited times, as few times as possible, expanding as needed (lazy)
    • ( and ) are used to denote our capturing group and all the possible alternatives
    • [1-9].*? – this is the first alternative. We’re matching all the digits that can come after a decimal point, which are not zero
    • 0$ – this is the second alternative. It’s for handling cases when a number is a zero only number
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search