我必须验证浮点数是否最多有两位数。
我已经尝试了很多方法,但是所有方法都失败了。
其中最后一个是:
//fails for 2638655.99
private function hasMoreThanTwoDecimals(string $number): bool
{
$number = abs($number);
$intPart = floor($number);
$floatPart = $number - $intPart;
return (strlen($floatPart) > 4);
}
OR
//fails for 36.62
private function hasMoreThanTwoDecimals(string $number): bool
{
return $number * 100 - floor($number * 100) > 0.00001;
}
您使用了哪些其他方法?
答案 0 :(得分:0)
您可以.
使用$num = 2638655.99;
echo strlen(explode('.',$num)[1]); // Echo 2
分隔符explode,然后返回第二部分的长度:
__inline__
答案 1 :(得分:0)
您无法确定float
数据类型的确切小数位数,因为内部表示形式为二进制。在二进制文件中,fx。 0.1无法准确表示。这就是为什么循环总是应该有整数增量。
for ($i = -1; $i < 1; $i += 0.1) {
if ($i == 0) {
echo "Zero is here!";
}
}
永远不会说&#34;零在这里!&#34;因为二进制舍入问题。
您已经尝试使用epsilon(一个非常小的值)进行缩放(这里是您的函数的重构版本):
private function hasMoreThanTwoDecimals(string $number): bool
{
$epsilon = 0.00001;
return fmod($number * 100, 1.0) > $epsilon;
}
但是某些值失败了。在这种情况下,您需要增加epsilon值。
更精确的方法是避免使用float
并使用字符串表示。这是您的最佳选择,因为 - 根据您的功能签名 - 您的数字已经表示为字符串。
private function hasMoreThanTwoDecimals(string $number): bool
{
return bcmod(bcmul($number, '100'), '1.0') != 0;
}
这需要将BCMath模块包含在PHP中。支持BCMath和其他解决方案的包是brick/math。
但是,如果您真的需要探测数字而不进行计算,则可以通过模式匹配获得所需的结果。
private function hasMoreThanTwoDecimals(string $number): bool
{
// Trailing 0 does not add to number of decimals
$number = $rtrim($number, '0');
return preg_match('~\.\d\d\d~', $number);
}
答案 2 :(得分:-3)
您可以使用number_format
number_format($number, 2, '.', '');