【发布时间】:2011-01-26 16:03:56
【问题描述】:
有没有一种直接的方法来确定 PHP 中 a(n) 整数/双精度值的小数位数? (即不使用explode)
【问题讨论】:
有没有一种直接的方法来确定 PHP 中 a(n) 整数/双精度值的小数位数? (即不使用explode)
【问题讨论】:
您可以尝试将其转换为 int,从您的数字中减去它,然后计算剩下的内容。
【讨论】:
echo strlen($num-(int)$num)-2;
$decimals = ( (int) $num != $num ) ? (strlen($num) - strpos($num, '.')) - 1 : 0; 也适用于负数。
(3.005 - 3).toString().length 得到了 20。我希望在任何编程语言中都有这种行为?
类似:
<?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()
?>
这是程序性的,笨拙的,我不建议在生产代码中使用它。但它应该让你开始。
【讨论】:
$str = "1.23444";
print strlen(substr(strrchr($str, "."), 1));
【讨论】:
var_dump((string)(0.00000000000012)); 输出string(7) "1.2E-13"
$str = rtrim(number_format($value, 14 - log10($value)), '0');。 14是基于PHP中浮点数的最大精度;如果您首先对浮点数进行一些数学运算,则可能需要减少一点(特别是如果它是通过减去两个较大的数字获得的)。
$decnumber = strlen(strstr($yourstr,'.'))-1
【讨论】:
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
【讨论】:
$variable = (float)1.0; 不起作用)
$localconv = localeconv(); return strlen($value) - strrpos($value, $localconv['decimal_point']) - 1;
我使用以下内容来确定返回值是否有小数(实际的十进制值,而不仅仅是格式化为显示小数,如 100.00):
if($mynum - floor($mynum)>0) {has decimals;} else {no decimals;}
【讨论】:
这个怎么样?
$iDecimals = strlen($sFull%1);
【讨论】:
$sFull = 3.1459287; echo $sFull%1; 结果:0。所以:没有。
<?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
【讨论】:
$value = 182.949;
$count = strlen(abs($value - floor($value))) -2; //0.949 minus 2 places (0.)
【讨论】:
这是一个考虑尾随零的函数:
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;
}
【讨论】:
整数没有小数位,所以答案总是零。
双数或浮点数是近似值。所以它们没有定义的小数位数。
一个小例子:
$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)
【讨论】:
我需要一个适用于各种数字格式的解决方案,并提出了以下算法:
// 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
【讨论】:
首先,我使用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))) );
?>
【讨论】:
$num = "12.1234555";
print strlen(preg_replace("/.*\./", "", $num)); // 7
模式.*\.表示小数点前的所有字符都带有它。
在这种情况下,它是包含三个字符的字符串:12.
preg_replace 函数将这些缓存的字符转换为空字符串""(第二个参数)。
在这种情况下,我们得到这个字符串:1234555
strlen函数统计保留字符串的字符数。
【讨论】:
strlen(preg_replace('/[\d]+[\.]?/', '', $finalValue, 1))
您应该始终注意不同的语言环境。欧洲语言环境使用逗号作为千位分隔符,因此接受的答案不起作用。修改后的解决方案见下文:
function countDecimalsUsingStrchr($stringValue){
$locale_info = localeconv();
return strlen(substr(strrchr($stringValue, $locale_info['decimal_point']), 1));
}
【讨论】:
如果为了其他开发者的利益而想要可读性,语言环境安全,请使用:
function countDecimalPlacesUsingStrrpos($stringValue){
$locale_info = localeconv();
$pos = strrpos($stringValue, $locale_info['decimal_point']);
if ($pos !== false) {
return strlen($stringValue) - ($pos + 1);
}
return 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
冗长但没有复杂的条件。
【讨论】:
更少的代码:
$str = "1.1234567";
echo (int) strpos(strrev($str), ".");
【讨论】:
strpos 将返回 false 而不是 0