## PHP - Find the number of zeros in a decimal number

Let's say we have 0.00045. I want to find a way to count the number of "significant" zeros after the decimal point (3 in this case). I've been trying to implement `strpos`

or `substr`

, but I'm getting stuck.

Other exs....

3.006405: Should return "2" 0.0000062: Should return "5" 9.0100000008: Should return "1"

Any ideas?

strspn($num, "0", strpos($num, ".")+1)

`strspn`

finds the length of a sequence of zeroes. `strpos`

finds the position of the decimal point, and we start from 1 position past that.

However, this doesn't work for `0.0000062`

because it gets converted to scientific notation when converted to a string: `6.200000e-6`

. When the number ends with `e-<exponent>`

, the number of zeroes is `<exponent>-1`

. You can check for this with a regular expression.

**number_format - Manual,** If its length is smaller than number of decimals, add trailing zeros, otherwise It corresponds "PHP Warning: Wrong parameter count for number_format()",� Input :1234567 Output :01234567 Input :1234 Output :00001234. There are many ways to pad leading zeros in string format. But in case of string the best way to achieve the task is by using sprintf function and also you can use substr () function. sprintf () function.

I've decided to investigate some different possibilities in handling this task.

I must say that Barmar's solution is easy to read and well suited for floating point numbers that do not suffer from impacts of scientific notation.

As a thought experiment, I've decided to craft a couple of regular expressions to do the same job. (*The regex approaches will still hold up even if you pass an integer value to them.)

- With
`preg_match_all()`

, I am using the "continue" metacharacter (`\G`

) to match the first`.0`

then zero or more`0`

that immediately follow. - With
`preg_match()`

, I can more simply match the dot, then "forget it" with`\K`

(restart the fullstring match), then match 1 or more zeros from that position. Unfortunately this requires the additional call of`str_len()`

. I generally only favor`preg_`

calls when it results in fewer function calls than non-regex approaches.

Inspired by https://codereview.stackexchange.com/q/219601/141885, I wanted to write a function to count the zeros after the decimal point using only arithmetic (guess & check). **While it doesn't suffer from scientific notation like the others, it is imperfect and there are limits to floats/integers on different operating systems / versions / environments / yatta-yatta (I don't pretend to know all of the ins-and-outs, but I am aware that there are differences).** Go ahead and try some of these approaches with your project data and feel free to leave comments about what works and doesn't work. ...and if you know know *why* I invite you to educate me :)

Finally, there are many posts on StackOverflow (here's one) that recommend using the standard php library BCMath.

Code: (Demo)

function mathematical_zeros_after_dot($float) { $float = abs($float); // remove any signs $float -= (int)$float; // remove whole numbers from float if ($float == 0) { return "Rendered as 0"; } $max = 20; for ($x = 0; $x < $max; ++$x) { // for loop with a hard limit to avoid infinite loop $float *= 10; if ($float >= 1) { return $x; } } return "$max {exceeded}"; } $floats = [ 25.000000000022, // 10 0.0000062, // 5 0.020320, // 1 .505000, // 0 0, // 0 .000507, // 3 -.002009, // 2 1000, // 0 0.00, // 0 1 // 0 -1.0000000000004000004, // 12 981.0000000000000000000004000004 // 21 ]; foreach ($floats as $float) { echo "(Math) {$float} has " , mathematical_zeros_after_dot($float) , " zero(s)\n"; echo "Barmar {$float} has " , strspn($float, "0", strpos($float, ".")+1) , " zero(s)\n"; echo "(PMA) {$float} has " , preg_match_all('~(?:\.|\G(?!^))0~', $float) , " zero(s)\n"; echo "(PA) {$float} has " , (preg_match('~\.\K0+~', $float, $match) ? strlen($match[0]) : 0) , " zero(s)\n"; }

Output:

(Math) 25.000000000022 has 10 zero(s) Barmar 25.000000000022 has 10 zero(s) (PMA) 25.000000000022 has 10 zero(s) (PA) 25.000000000022 has 10 zero(s) (Math) 6.2E-6 has 5 zero(s) Barmar 6.2E-6 has 0 zero(s) (PMA) 6.2E-6 has 0 zero(s) (PA) 6.2E-6 has 0 zero(s) (Math) 0.02032 has 1 zero(s) Barmar 0.02032 has 1 zero(s) (PMA) 0.02032 has 1 zero(s) (PA) 0.02032 has 1 zero(s) (Math) 0.505 has 0 zero(s) Barmar 0.505 has 0 zero(s) (PMA) 0.505 has 0 zero(s) (PA) 0.505 has 0 zero(s) (Math) 0 has Rendered as 0 zero(s) Barmar 0 has 0 zero(s) (PMA) 0 has 0 zero(s) (PA) 0 has 0 zero(s) (Math) 0.000507 has 3 zero(s) Barmar 0.000507 has 3 zero(s) (PMA) 0.000507 has 3 zero(s) (PA) 0.000507 has 3 zero(s) (Math) -0.002009 has 2 zero(s) Barmar -0.002009 has 2 zero(s) (PMA) -0.002009 has 2 zero(s) (PA) -0.002009 has 2 zero(s) (Math) 1000 has Rendered as 0 zero(s) Barmar 1000 has 3 zero(s) (PMA) 1000 has 0 zero(s) (PA) 1000 has 0 zero(s) (Math) 0 has Rendered as 0 zero(s) Barmar 0 has 0 zero(s) (PMA) 0 has 0 zero(s) (PA) 0 has 0 zero(s) (Math) -3.9990233346998E-13 has 12 zero(s) Barmar -3.9990233346998E-13 has 0 zero(s) (PMA) -3.9990233346998E-13 has 0 zero(s) (PA) -3.9990233346998E-13 has 0 zero(s) (Math) 981 has Rendered as 0 zero(s) Barmar 981 has 0 zero(s) (PMA) 981 has 0 zero(s) (PA) 981 has 0 zero(s)

**Floating point numbers - Manual,** Floating point numbers (also known as "floats", "doubles", or "real numbers") me to sum a collection of floats and ensure that they equal zero before commiting a get the number of decimal places to the right of the decimal point (or 0 if there � Version Description; 7.2.0: number_format() was changed to not being able to return -0, previously -0 could be returned for cases like where number would be -0.01.

Match the first consecutive zeroes in the mantissa:

$number = 123.0000000240003; preg_match("/^(0+)/", explode('.', $number)[1], $matches); echo strlen($matches[0]); // echoes 7

**is_numeric - Manual,** is_numeric — Finds whether a variable is a number or a numeric string sign, any number of digits, optional decimal part and optional exponential part. If you want detect integer of float values, which presents as pure int or float, and Note that strings with leading zeros containing only digits also return true on check� In PHP numbers with a leading zero are interpreted differently and may yield unexpected results. For example: $num = 0123; // is considered an octal number (that equals 83 decimal) $num = 0x123; // is considered a hexadecimal number (that equals 291 decimal) $num = 0b111; // is considered a binary number (that equals 7 decimal) If you want to ensure that a prefixed zero sticks to a number without losing its "natural" meaning, then you could try some of the ways documented below.

**php remove trailing zeros of a decimal number – web-profile,** php remove trailing zeros of a decimal number. Method to remove or strip trailing zeros of a decimal number: <?php function� Just to add on top of what wtf8_decode said; Negative numbers would not have leading zeros, and they are not positive numbers. i.e. 08 would be written as such as a date, or something which expects a positive double digit number (Bank Account sort code etc).

**Leading zero,** A leading zero is any 0 digit that comes before the first nonzero digit in a number string in Therefore, the usual decimal notation of integers does not use leading zeros The count leading zeros operation efficiently determines the number of Many other programming languages, such as Python, Perl, Ruby, PHP, and the� Specifies the number of decimal digits to round to. Default is 0: mode: Optional. Specifies a constant to specify the rounding mode: PHP_ROUND_HALF_UP - Default. Rounds number up to precision decimal, when it is half way there. Rounds 1.5 to 2 and -1.5 to -2; PHP_ROUND_HALF_DOWN - Round number down to precision decimal places, when it is half

Returns the rounded value of val to specified precision (number of digits after the decimal point).precision can also be negative or zero (default).. Note: PHP doesn't handle strings like "12,300.2" correctly by default.

##### Comments

- Try
`strspn()`

to find the length of the sequence of zeroes. - Okay so significant 0's, will probably involve using a loop. I would try converting the decimal to a string, iterating through it with a loop and use a bunch of if statements to check the various significant figure rules. If all if statements work out, just have a counter and increment it.
- Is it right after the decimal point? Do they have to be consecutive?