PHP:获取小数位数

时间:2010-03-12 02:17:10

标签: php decimal

在PHP中是否有一种直接的方法来确定(n)整数/双精度值中的小数位数? (即,不使用explode

18 个答案:

答案 0 :(得分:66)

$str = "1.23444";
print strlen(substr(strrchr($str, "."), 1));

答案 1 :(得分:11)

您可以尝试将其转换为int,从您的数字中减去该值,然后计算剩下的数量。

答案 2 :(得分:11)

function numberOfDecimals($value)
{
    if ((int)$value == $value)
    {
        return 0;
    }
    else if (! is_numeric($value))
    {
        // throw new Exception('numberOfDecimals: ' . $value . ' is not a number!');
        return false;
    }

    return strlen($value) - strrpos($value, '.') - 1;
}


/* test and proof */

function test($value)
{
    printf("Testing [%s] : %d decimals\n", $value, numberOfDecimals($value));
}

foreach(array(1, 1.1, 1.22, 123.456, 0, 1.0, '1.0', 'not a number') as $value)
{
    test($value);
}

输出:

Testing [1] : 0 decimals
Testing [1.1] : 1 decimals
Testing [1.22] : 2 decimals
Testing [123.456] : 3 decimals
Testing [0] : 0 decimals
Testing [1] : 0 decimals
Testing [1.0] : 0 decimals
Testing [not a number] : 0 decimals

答案 3 :(得分:3)

更少的代码:

$str = "1.1234567";
echo strpos(strrev($str), ".");

答案 4 :(得分:3)

我使用以下内容来确定返回的值是否有任何小数(实际的十进制值,而不仅仅是格式化为显示小数,如100.00):

if($mynum - floor($mynum)>0) {has decimals;} else {no decimals;} 

答案 5 :(得分:2)

类似的东西:

<?php

$floatNum = "120.340304";
$length = strlen($floatNum);

$pos = strpos($floatNum, "."); // zero-based counting.

$num_of_dec_places = ($length - $pos) - 1; // -1 to compensate for the zero-based count in strpos()

?>

这是程序性的,kludgy,我不建议在生产代码中使用它。但它应该让你开始。

答案 6 :(得分:2)

我需要一个适用于各种数字格式的解决方案,并提出了以下算法:

// Count the number of decimal places
$current = $value - floor($value);
for ($decimals = 0; ceil($current); $decimals++) {
    $current = ($value * pow(10, $decimals + 1)) - floor($value * pow(10, $decimals + 1));
}

// Count the total number of digits (includes decimal places)
$current = floor($value);
for ($digits = $decimals; $current; $digits++) {
    $current = floor($current / 10);
}

结果:

input:    1
decimals: 0
digits:   1

input:    100
decimals: 0
digits:   3

input:    0.04
decimals: 2
digits:   2

input:    10.004
decimals: 3
digits:   5

input:    10.0000001
decimals: 7
digits:   9

input:    1.2000000992884E-10
decimals: 24
digits:   24

input:    1.2000000992884e6
decimals: 7
digits:   14

答案 7 :(得分:2)

<?php

test(0);
test(1);
test(1.234567890);
test(-123.14);
test(1234567890);
test(12345.67890);

function test($f) {
    echo "f = $f\n";
    echo "i = ".getIntCount($f)."\n";
    echo "d = ".getDecCount($f)."\n";
    echo "\n";
}

function getIntCount($f) {
    if ($f === 0) {
        return 1;
    } elseif ($f < 0) {
        return getIntCount(-$f);
    } else {
        return floor(log10(floor($f))) + 1;
    }
}

function getDecCount($f) {
    $num = 0;
    while (true) {
        if ((string)$f === (string)round($f)) {
            break;
        }
        if (is_infinite($f)) {
            break;
        }

        $f *= 10;
        $num++;
    }
    return $num;
}

输出:

f = 0
i = 1
d = 0

f = 1
i = 1
d = 0

f = 1.23456789
i = 1
d = 8

f = -123.14
i = 3
d = 2

f = 1234567890
i = 10
d = 0

f = 12345.6789
i = 5
d = 4

答案 8 :(得分:1)

这是一个考虑尾随零的函数:

function get_precision($value) {
    if (!is_numeric($value)) { return false; }
    $decimal = $value - floor($value); //get the decimal portion of the number
    if ($decimal == 0) { return 0; } //if it's a whole number
    $precision = strlen($decimal) - 2; //-2 to account for "0."
    return $precision; 
}

答案 9 :(得分:1)

内部

整数没有十进制数字,因此答案始终为零。

双/浮动

双数或浮点数是近似值。所以他们没有定义的十进制数字。

一个小例子:

$number = 12.00000000012;
$frac = $number - (int)$number;

var_dump($number);
var_dump($frac);

输出:

float(12.00000000012)
float(1.2000000992884E-10)

你可以在这里看到两个问题,第二个数字是使用科学表示,它不完全是1.2E-10。

字符串

对于包含整数/浮点数的字符串,您可以搜索小数点:

$string = '12.00000000012';
$delimiterPosition = strrpos($string, '.');
var_dump(
  $delimiterPosition === FALSE ? 0 : strlen($string) - 1 - $delimiterPosition
);

输出:

int(11)

答案 10 :(得分:1)

这个怎么样?:

$iDecimals = strlen($sFull%1);

答案 11 :(得分:1)

解决方案

$num = "12.1234567";
print strlen(preg_replace("/.*\./", "", $num)); // 7

解释

模式&#34; 。* \。&#34;表示小数点前面的所有字符。

在这种情况下,它的字符串包含三个字符:&#34; 12。&#34;。

preg_replace 函数将这些字符转换为空字符串(第二个参数)。

在这种情况下,我们会收到以下字符串:&#34; 1234567 &#34;。

strlen 函数计算上述字符串中的字符数。

答案 12 :(得分:1)

如果您希望可读性为其他开发人员的利益(地区安全),请使用:

function countDecimalPlacesUsingStrrpos($stringValue){
    $locale_info = localeconv();
    $pos = strrpos($stringValue, $locale_info['decimal_point']);
    if ($pos !== false) {
        return strlen($stringValue) - ($pos + 1);
    }
    return 0;
}

请参阅localeconv

答案 13 :(得分:1)

$decnumber = strlen(strstr($yourstr,'.'))-1

答案 14 :(得分:0)

首先,我使用strpos函数找到了小数位,并将strpos位置值增加1以跳过小数位。

第二,我已经从我从point1获得的值中减去了整个字符串的长度。

第三,我使用substr函数来获取小数点后的所有数字。

第四,我使用strlen函数来获取小数位后的字符串长度。

这是执行上述步骤的代码:

     <?php
        $str="98.6754332";
        echo $str;
        echo "<br/>";
        echo substr( $str, -(strlen($str)-(strpos($str, '.')+1)) );
        echo "<br/>";
        echo strlen( substr( $str, -(strlen($str)-(strpos($str, '.')+1))) );
    ?>

答案 15 :(得分:0)

您应该始终注意不同的语言环境。欧洲语言环境对千位分隔符使用逗号,因此接受的答案将不起作用。修改后的解决方案请参见下文:

std::map<std::string, std::vector<std::function<void(Php::Namespace &)>>>

请参阅localeconv

答案 16 :(得分:0)

这将适用于任何数字,即使是科学计数法,其精度也可以达到小数点后100位。

$float = 0.0000005;

$working = number_format($float,100);
$working = rtrim($working,"0");
$working = explode(".",$working);
$working = $working[1];

$decmial_places = strlen($working);

结果:

7

Lengthy,但是没有复杂的条件。

答案 17 :(得分:-1)

$value = 182.949;

$count = strlen(abs($value - floor($value))) -2; //0.949 minus 2 places (0.)