Error With Using (int) and (double) together to Cu

2019-02-22 18:30发布

When I am using (int) with (double) some times it is not working correct.
Look At The PHP Code Example:

I Need To LEAVE 2 Decimals And REMOVE Other...

I Know number_format(); function But I Cannot Use It. Because It Is Rounding Number

number_format(24.299,2);
Output: 24.30
I Need: 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
?>

I need To leave two decimals in the number and cut other WITHOUT rounding.

5条回答
倾城 Initia
2楼-- · 2019-02-22 18:47

Never cast an unknown fraction to integers, see the manual on http://www.php.net/manual/en/language.types.integer.php. (int) ( (0.1+0.7) * 10 ); will result in 7, not 8 as one might expect. Casting from float to integer will always round down - and you may also want to check the operator precedence http://php.net/manual/en/language.operators.precedence.php.

Solution: calculate your fraction before you cast it. $fStr = (float) $str; $iStr = (int) $fStr;

查看更多
forever°为你锁心
3楼-- · 2019-02-22 18:48

Because of floating point precision (see for example this question: PHP - Floating Number Precision), 158.2 * 100 is not exactly 15820 but something like 15819.99999999.

Now (int) is for type conversion, not for rounding, and any digits after the point are cut of.

I need To leave two decimals in the number and cut other WITHOUT rounding.

This is easy:

number_format($str, 2);

Update

number_format does round, so it is a bit more complicated:

bcmul($str,100,0)/100

bcmul multiplies with arbitrary precision, in this case 0. Results:

bcmul(158.2,100,0)/100 == 158.2
bcmul(24.299,100,0)/100 == 24.29
查看更多
\"骚年 ilove
4楼-- · 2019-02-22 18:58

This doesn't answer the question of why that happens (it could be a precision bug), but to solve your problem, try using $foo = sprintf("%.2f", (float)$str);.

Example:

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

EDIT: Infact, yes, this is a precision issue. (in C++) by printing 158.2 to 20 decimal places, I get the output of "158.19999999999998863132". This is an inherent problem with floating point/double precision values. You can see the same effect by using echo sprintf("%.20f", $var); in PHP.

查看更多
▲ chillily
5楼-- · 2019-02-22 19:00

First off, PHP is a language that allows you to type juggle. Which means you do not need the (int) or the (double) to do what you're trying to do.

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

Use the number_format command to format your numbers how you want.

More here

查看更多
唯我独甜
6楼-- · 2019-02-22 19:02

Fixed.

    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 />";

?>
查看更多
登录 后发表回答