Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error With Using (int) and (double) together to Cut off Decimals

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.

like image 791
VoW Avatar asked Feb 21 '13 15:02

VoW


2 Answers

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
like image 144
Fabian Schmengler Avatar answered Sep 29 '22 19:09

Fabian Schmengler


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.

like image 40
slugonamission Avatar answered Sep 29 '22 19:09

slugonamission