PHP计算除法整数
PHP calculate integer of division
我想计算除法的整数部分。分子和分母(尤其是它们的精度)不应更改,因为它可能会从一种计算变为另一种计算,分母也是一个例子,它的整数部分和小数部分可能不同。
我尝试使用 floor, ceil, round,但其中 none 产生了正确的结果。
请看下面的代码,也许你会发现错误:
<?php
$valueArr = [
// should return 1999
199.90,
199.92,
199.95,
199.97,
// should return 2000
200.00,
200.02,
200.05,
200.07,
// should return 2001
200.10,
200.12,
200.15,
200.17,
];
$denominator = 0.1;
$resultArr = [];
foreach ($valueArr as $value) {
$key = (string) $value;
$result = floor($value / $denominator);
$resultArr[$key] = $result;
}
echo "Denominator:\n";
var_dump($denominator);
echo "\n";
print_r($resultArr);
给出结果:
Denominator:
float(0.1)
Array
(
[199.9] => 1999
[199.92] => 1999
[199.95] => 1999
[199.97] => 1999
[200] => 2000
[200.02] => 2000
[200.05] => 2000
[200.07] => 2000
[200.1] => 2000
[200.12] => 2001
[200.15] => 2001
[200.17] => 2001
)
其中:
[200.1] => 2000
是错误的,因为 (200.1 / 0.1) 的整数部分是 2001.
你知道如何为上面的 $valueArr
生成正确的结果吗?我做错了什么?
我正在使用 PHP 7.3.8 (cli)
我使用 bcdiv() 得到了正确的结果。
$result = bcdiv($value,$denominator);
我一直用 BcMath,对我来说似乎更可靠。
你没有做错任何事。这是电脑的问题。很难在固定的 space.
中准确表示浮点数
试试这个
foreach ($valueArr as $v) {
$resultArr []= floor($v * (1 / $denominator));
}
我的建议是尝试将除法运算转换为乘法。
在你的情况下,除以 0.1 === 乘以 10。所以,使用它。
所以您要 运行 进入这里的两个问题。首先是一般浮点数缺乏精度,其次是 PHP 在您有机会使用 bcdiv
.
之类的东西之前自动将您的输入强制转换为浮点数
因此:第一步是将您的输入数字存储为字符串,这样您就不会因为解析器将它们解释为浮点数而失去精度。然后对它们使用bcdiv
。
因为你只是在整数部分和 bcdiv returns 成功的字符串之后,我们可以用字符串函数删除小数部分。
<?php
$valueArr = [
// should return 1999
'199.90',
'199.92',
'199.95',
'199.97',
// should return 2000
'200.00',
'200.02',
'200.05',
'200.07',
// should return 2001
'200.10',
'200.12',
'200.15',
'200.17',
'381736192374124241.294',
];
$denominator = '0.1';
$resultArr = [];
foreach ($valueArr as $value) {
$key = (string) $value;
$result = explode('.', bcdiv($value, $denominator))[0];
$resultArr[$key] = $result;
}
echo "Denominator:\n";
var_dump($denominator);
echo "\n";
print_r($resultArr);
如果您想对 bcdiv
的输出进行舍入、ceil、floor 之类的操作,请查看此答案:
如果您没有 BcMath
扩展附带的 bcdiv
您可以使用 sprintf() function to achieve a proper result with the floor() 并且即使在分母是小于 0.0001
.
的浮点数的情况下也没有任何问题
而不是:
$result = floor($value / $denominator);
使用这个:
$result = floor(sprintf('%f', $value / $denominator));
你会得到正确的:
[200.1] => 2001
我想计算除法的整数部分。分子和分母(尤其是它们的精度)不应更改,因为它可能会从一种计算变为另一种计算,分母也是一个例子,它的整数部分和小数部分可能不同。
我尝试使用 floor, ceil, round,但其中 none 产生了正确的结果。 请看下面的代码,也许你会发现错误:
<?php
$valueArr = [
// should return 1999
199.90,
199.92,
199.95,
199.97,
// should return 2000
200.00,
200.02,
200.05,
200.07,
// should return 2001
200.10,
200.12,
200.15,
200.17,
];
$denominator = 0.1;
$resultArr = [];
foreach ($valueArr as $value) {
$key = (string) $value;
$result = floor($value / $denominator);
$resultArr[$key] = $result;
}
echo "Denominator:\n";
var_dump($denominator);
echo "\n";
print_r($resultArr);
给出结果:
Denominator:
float(0.1)
Array
(
[199.9] => 1999
[199.92] => 1999
[199.95] => 1999
[199.97] => 1999
[200] => 2000
[200.02] => 2000
[200.05] => 2000
[200.07] => 2000
[200.1] => 2000
[200.12] => 2001
[200.15] => 2001
[200.17] => 2001
)
其中:
[200.1] => 2000
是错误的,因为 (200.1 / 0.1) 的整数部分是 2001.
你知道如何为上面的 $valueArr
生成正确的结果吗?我做错了什么?
我正在使用 PHP 7.3.8 (cli)
我使用 bcdiv() 得到了正确的结果。
$result = bcdiv($value,$denominator);
我一直用 BcMath,对我来说似乎更可靠。
你没有做错任何事。这是电脑的问题。很难在固定的 space.
中准确表示浮点数试试这个
foreach ($valueArr as $v) {
$resultArr []= floor($v * (1 / $denominator));
}
我的建议是尝试将除法运算转换为乘法。
在你的情况下,除以 0.1 === 乘以 10。所以,使用它。
所以您要 运行 进入这里的两个问题。首先是一般浮点数缺乏精度,其次是 PHP 在您有机会使用 bcdiv
.
因此:第一步是将您的输入数字存储为字符串,这样您就不会因为解析器将它们解释为浮点数而失去精度。然后对它们使用bcdiv
。
因为你只是在整数部分和 bcdiv returns 成功的字符串之后,我们可以用字符串函数删除小数部分。
<?php
$valueArr = [
// should return 1999
'199.90',
'199.92',
'199.95',
'199.97',
// should return 2000
'200.00',
'200.02',
'200.05',
'200.07',
// should return 2001
'200.10',
'200.12',
'200.15',
'200.17',
'381736192374124241.294',
];
$denominator = '0.1';
$resultArr = [];
foreach ($valueArr as $value) {
$key = (string) $value;
$result = explode('.', bcdiv($value, $denominator))[0];
$resultArr[$key] = $result;
}
echo "Denominator:\n";
var_dump($denominator);
echo "\n";
print_r($resultArr);
如果您想对 bcdiv
的输出进行舍入、ceil、floor 之类的操作,请查看此答案:
如果您没有 BcMath
扩展附带的 bcdiv
您可以使用 sprintf() function to achieve a proper result with the floor() 并且即使在分母是小于 0.0001
.
而不是:
$result = floor($value / $denominator);
使用这个:
$result = floor(sprintf('%f', $value / $denominator));
你会得到正确的:
[200.1] => 2001