Php 同时使用(int)和(double)截断小数时出错

Php 同时使用(int)和(double)截断小数时出错,php,floating-point,int,double,floating-point-precision,Php,Floating Point,Int,Double,Floating Point Precision,有时,当我将(int)与(double)一起使用时,它无法正常工作。 请看PHP代码示例: 我需要留下2个小数并删除其他… 我知道数字格式();功能,但我不能使用它。因为它是舍入数 number_格式(24.299,2) 输出:24.30 我需要:24.29 <?php $str="158.2"; echo (double)$str; // Output: 158.2 echo (double)$str*100; // Output: 15820 echo (int)((double)

有时,当我将(int)与(double)一起使用时,它无法正常工作。
请看PHP代码示例:

我需要留下2个小数并删除其他…

我知道数字格式();功能,但我不能使用它。因为它是舍入数

number_格式(24.299,2)
输出:24.30
我需要:24.29

<?php

$str="158.2";

echo (double)$str; // Output: 158.2
echo (double)$str*100; // Output: 15820
echo (int)((double)$str*100); // Output: 15819 <-WHY? It Must To Be 15820, Why 15819? 
echo ((int)((double)$str*100)/100); // Output: 158.19
?>


我需要在数字中保留两个小数,并在不舍入的情况下删去其他小数。

这并不能回答为什么会发生这种情况的问题(这可能是一个精度错误),但要解决您的问题,请尝试使用
$foo=sprintf(“%.2f”,(float)$str)

例如:

$str = "158.2";
$num = (double)$str;
print sprintf("%.2f", $num);

编辑:事实上,是的,这是一个精度问题。(在C++中)通过打印158.2到20个小数位,我得到了“158.199999999998863132”的输出。这是浮点/双精度值的固有问题。通过使用echo sprintf(“%.20f”,$var),您可以看到相同的效果在PHP中。

首先,PHP是一种允许您使用的语言。这意味着您不需要使用
(int)
(double)
来执行您试图执行的操作

<?php
$str="158.2"; //could also do $str = 158.2
echo $str; // Ouput: 158.2
echo $str * 100; //Output: 15820
echo number_format($str, 2); //Output: 158.20
echo number_format(($str*100)/100, 2); //Output: 158.20
?>

使用
number\u format
命令以您想要的方式格式化数字


更多信息

切勿将未知分数转换为整数,请参阅上的手册。
(int)((0.1+0.7)*10)
将产生7,而不是预期的8。从float到integer的强制转换将始终向下舍入-您可能还需要检查运算符的优先级

解决方案:在施放之前计算分数<代码>$fStr=(浮动)$str$iStr=(整数)$fStr

已修复。
    function cutDecimals($number,$decimal){
        $_str=(string)$number;
        if(strpos($_str,".")!==false){
            $dotPosition=strpos($_str,".")+1;
            $_numCount=strpos($_str,".");
            $_decimal=strlen($_str)-$dotPosition;

            if($_decimal<$decimal) return (double)$_str;
            else return (double)substr($_str,0,$_numCount+$decimal+1);
        }else return (double)$_str;
    }

    echo cutDecimals("158.099909865",2)."<br />";
    echo cutDecimals("14.02",2)."<br />";
    echo cutDecimals("41.12566",2)."<br />";
    echo cutDecimals("1.981",2)."<br />";
    echo cutDecimals("0.4111",2)."<br />";
    echo cutDecimals("144.2",2)."<br />";
    echo cutDecimals("55.000000",2)."<br />";
    echo cutDecimals("1456115.499811445121",2)."<br />";

?>
函数小数($number,$decimal){
$\u str=(字符串)$number;
if(strpos($_str,“.”)==false){
$dotPosition=strpos($_str,“.”)+1;
$\u numCount=strpos($\u str,“.”);
$\u decimal=strlen($\u str)-$dotPosition;
如果($\十进制)

由于浮点精度(例如,请参见此问题:),
158.2*100
不完全是
15820
,而是类似
15819.9999999

现在,
(int)
用于类型转换,不用于取整,点后的任何数字都被切掉

我需要在数字中留下两个小数,并在不舍入的情况下删去另一个

这很简单:

number_format($str, 2);
更新

number\u格式
是四舍五入格式,所以它有点复杂:

bcmul($str,100,0)/100
以任意精度相乘,在本例中为0。结果:

bcmul(158.2,100,0)/100 == 158.2
bcmul(24.299,100,0)/100 == 24.29

$str=“24.299”;$num=(double)$str;打印sprintf(“%.2f”,$num);输出24.30由于精度问题,我需要24.29,这很棘手。请参阅,但它不适用于158.2