为了账号安全,请及时绑定邮箱和手机立即绑定

PHP计算除法的整数

PHP计算除法的整数

PHP
尚方宝剑之说 2023-09-08 14:35:02
我想计算除法的整数部分。分子和分母(尤其是它们的精度)不应更改,因为它可能从一种计算变为另一种计算,同样以分母为例,其整数部分和小数部分可能不同。我尝试使用Floor、ceil、round但它们都没有产生正确的结果。请看下面的代码,也许你会发现错误:<?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) 的整数部分是 200 1。您知道如何为$valueArr上述结果生成正确的结果吗?我做错了什么?我正在使用 PHP 7.3.8 (cli)
查看完整描述

4 回答

?
SMILET

TA贡献1796条经验 获得超4个赞

因此,您将在这里遇到两个问题。首先是浮点数一般缺乏精度,其次是 PHP 在你有机会使用类似bcdiv.


因此:第一步是将输入数字存储为字符串,这样解析器将它们解释为浮点数时就不会丢失精度。然后用bcdiv在他们身上。


由于您就在整数部分之后,并且 bcdiv 在成功时返回一个字符串,因此我们可以使用字符串函数删除小数部分。


<?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);


查看完整回答
反对 回复 2023-09-08
?
繁花如伊

TA贡献2012条经验 获得超12个赞

我使用 bcdiv() 得到了正确的结果。

$result = bcdiv($value,$denominator);

我总是使用 BcMath,对我来说似乎更可靠。


查看完整回答
反对 回复 2023-09-08
?
跃然一笑

TA贡献1826条经验 获得超6个赞

如果您没有扩展bcdiv附带的,BcMath您可以使用sprintf()函数通过Floor()获得正确的结果,即使分母是小于 的浮点数,也没有任何问题0.0001

代替:

$result = floor($value / $denominator);

用这个:

$result = floor(sprintf('%f', $value / $denominator));

你会得到正确的:

[200.1] => 2001


查看完整回答
反对 回复 2023-09-08
?
狐的传说

TA贡献1804条经验 获得超3个赞

你没有做错任何事。这是电脑的问题。在固定的空间内准确地表示浮点数是很困难的。

尝试这个

foreach ($valueArr as $v) {
    $resultArr []= floor($v * (1 / $denominator));
}

我的建议是尝试将除法运算转换为乘法运算。

在你的例子中,除以 0.1 === 乘以 10。所以,使用它。


查看完整回答
反对 回复 2023-09-08
  • 4 回答
  • 0 关注
  • 86 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信