PHP计算除法的整数

我想计算除法的整数部分。分子和分母(尤其是它们的精度)不应更改,因为它可能从一种计算变为另一种计算,同样以分母为例,其整数部分和小数部分可能不同。

我尝试使用Floorceilround但它们都没有产生正确的结果。请看下面的代码,也许你会发现错误:

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


尚方宝剑之说
浏览 128回答 4
4回答

SMILET

因此,您将在这里遇到两个问题。首先是浮点数一般缺乏精度,其次是 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);

繁花如伊

我使用 bcdiv() 得到了正确的结果。$result&nbsp;=&nbsp;bcdiv($value,$denominator);我总是使用 BcMath,对我来说似乎更可靠。

跃然一笑

如果您没有扩展bcdiv附带的,BcMath您可以使用sprintf()函数通过Floor()获得正确的结果,即使分母是小于 的浮点数,也没有任何问题0.0001。代替:$result = floor($value / $denominator);用这个:$result = floor(sprintf('%f', $value / $denominator));你会得到正确的:[200.1] => 2001

狐的传说

你没有做错任何事。这是电脑的问题。在固定的空间内准确地表示浮点数是很困难的。尝试这个foreach&nbsp;($valueArr&nbsp;as&nbsp;$v)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;$resultArr&nbsp;[]=&nbsp;floor($v&nbsp;*&nbsp;(1&nbsp;/&nbsp;$denominator)); }我的建议是尝试将除法运算转换为乘法运算。在你的例子中,除以 0.1 === 乘以 10。所以,使用它。
打开App,查看更多内容
随时随地看视频慕课网APP