由于科学记数法,如何将 PHP 中小数位数未知的小浮点数相乘而不得到零?
How to multiply small floats with unkown number of decimal places in PHP withouth getting zero because of scientific notation?
我试图在 PHP 中乘以一些小数字,但 bcmul 返回零,因为浮点值正在转换为科学记数法。
我试过对小的float值使用sprintf('%.32f',$value)
,但是由于不知道小数位数,所以四舍五入不对,乘法时会出现四舍五入的错误。
此外,我无法使用 strpos('e',$value)
来确定它是否是科学记数法数字,因为即使我将它转换为带有 (string)$value
[=15 的字符串,它也找不到它=]
下面是一些示例代码:
$value = (float)'7.4e-5'; // This number comes from an API like this
$value2 = (float)3.65; // Another number from API
echo bcmul($value,$value2); // 0
默认情况下 bc-functions 舍入为 0 位小数。您可以使用 bcscale 或更改 php.ini.
中的 bcmath.scale
值来更改此行为
好的,我找到了解决它的方法,所以,下面是如何乘以非常小的浮点数而不需要为数字设置明确的比例:
function getDecimalPlaces($value) {
// first we get how many decimal places the small number has
// this code was gotten on another Whosebug answer
$current = $value - floor($value);
for ($decimals = 0; ceil($current); $decimals++) {
$current = ($value * pow(10, $decimals + 1)) - floor($value * pow(10, $decimals + 1));
}
return $decimals;
}
function multiplySmallNumbers($value, $smallvalue) {
$decimals = getDecimalPlaces($smallvalue); // Then we get number of decimals on it
$smallvalue = sprintf('%.'.$decimals.'f',$smallvalue ); // Since bcmul uses the float values as strings, we get the number as a string with the correct number of zeroes
return (bcmul($value,$smallvalue));
}
我试图在 PHP 中乘以一些小数字,但 bcmul 返回零,因为浮点值正在转换为科学记数法。
我试过对小的float值使用sprintf('%.32f',$value)
,但是由于不知道小数位数,所以四舍五入不对,乘法时会出现四舍五入的错误。
此外,我无法使用 strpos('e',$value)
来确定它是否是科学记数法数字,因为即使我将它转换为带有 (string)$value
[=15 的字符串,它也找不到它=]
下面是一些示例代码:
$value = (float)'7.4e-5'; // This number comes from an API like this
$value2 = (float)3.65; // Another number from API
echo bcmul($value,$value2); // 0
默认情况下 bc-functions 舍入为 0 位小数。您可以使用 bcscale 或更改 php.ini.
中的bcmath.scale
值来更改此行为
好的,我找到了解决它的方法,所以,下面是如何乘以非常小的浮点数而不需要为数字设置明确的比例:
function getDecimalPlaces($value) {
// first we get how many decimal places the small number has
// this code was gotten on another Whosebug answer
$current = $value - floor($value);
for ($decimals = 0; ceil($current); $decimals++) {
$current = ($value * pow(10, $decimals + 1)) - floor($value * pow(10, $decimals + 1));
}
return $decimals;
}
function multiplySmallNumbers($value, $smallvalue) {
$decimals = getDecimalPlaces($smallvalue); // Then we get number of decimals on it
$smallvalue = sprintf('%.'.$decimals.'f',$smallvalue ); // Since bcmul uses the float values as strings, we get the number as a string with the correct number of zeroes
return (bcmul($value,$smallvalue));
}