Function round php not work correctly - php

php function round not working correctly.
I have number 0.9950.
I put code:
$num = round("0.9950", 2);
And I get 1.0? Why?? Why I can't get 0.99?

You can add a third parameter to the function to make it do what you need.
You have to choose from one of the following :
PHP_ROUND_HALF_UP
PHP_ROUND_HALF_DOWN
PHP_ROUND_HALF_EVEN
PHP_ROUND_HALF_ODD
This constants are easy enough to understand, so just use the adapted one :)
In your example, to get 0.99, you'll need to use :
<?php echo round("0.9950", 2, PHP_ROUND_HALF_DOWN); ?>
DEMO

When you round 0.9950 to two decimal places, you get 1.00 because this is how rounding works. If you want an operation which would result in 0.99 then perhaps you are looking for floating point truncation. One option to truncate a floating point number to two decimal places is to multiply by 100, cast to integer, then divide again by 100:
$num = "0.9950";
$output = (int)(100*$num) / 100;
echo $output;
0.99
This trick works because after the first step 0.9950 becomes 99.50, which, when cast to integer becomes just 99, discarding everything after the second decimal place in the original number. Then, we divide again by 100 to restore the original number, minus what we want truncated.
Demo

Just tested in PHP Sandbox... PHP seems funny sometimes.
<?php
$n = 16.90;
echo (100*$n)%100, "\n"; // 89
echo (int)(100*$n)%100, "\n"; // 89
echo 100*($n - (int)($n)), "\n"; // 90
echo (int)(100*($n - (int)($n))), "\n"; // 89
echo round(100*($n - (int)($n))), "\n"; // 90

Related

is possible to less float values..?

$quantity = 20;
$product_rate = 66.79;
$total = $quantity * $product_rate;
echo $total;
Output is showing 1335.8000000000002
is there possible to show 1335.8 using php..?
You can use the number_format() function like this:
$firstNum = 1335.8000000000002;
$number = number_format($firstNum, 1, '.', '');
echo $number;
outputs:
1335.8
more on number_format() here: http://php.net/number-format.
You can also multiply the number by 10, then use intval() to convert it to an integer (that way stripping out the decimals) and then divide by 10 like this:
$firstNum = 1335.8000000000002;
$number = 10 * intval($firstNum)/10;
echo $number;
outputs:
1335.8
Note: when using the methods above there will be no rounding, for rounding you would use something like this:
$number = round($firstNum, 1);
echo $number;
which in this case also outputs:
1335.8
Do you really use these variable values? I'm using PHP7 and the output for your given values is 1335.8. If you do a manual calculation it is the same result. It should be 1335.8. Anyway if you need to roundup the value you can use below.
round($total,1);
Please refer the below link and you will be able to grab more details.
http://php.net/manual/en/function.round.php
Because how floating point numbers work, they cannot represent every numbers exactly, so approximations are made.
The closest representation of 20 is 20, it can represent 20 exactly, but 66.79 for instance is approximated to 66.7900000000000062527760746889, that times 20 is 1335.800000000000125055521493778 that again cannot be represented and is approximated to 1335.80000000000018189894035459.
Depending on how you choose to print this number, it may round different ways, in your case for some reason you decided to print 13 decimal places so it rounded to 1335.8000000000002, but if you print only 1 or 2 decimal places it will print as 1335.8 or 1335.80. Just be mindful about that when printing floating point numbers, you may want to specify how many decimal places are relevant to you. For that, use number_format().
Example:
echo number_format($number, 2); // prints 2 decimal places
You can do this simply using echo echo round($total, 1) instead of doing round($total)

2 digit precision PHP

I am trying to do a 2 digit precision in PHP Laravel project but it doesnt work. I have the value 1234666.6666667 that I want to make 1234666.66 but all the results I've seen in here or/and in other search pages.
This is my code:
$value = 1234666.6666667;
return round($value,2);
any other solution?
EDIT:
As I see, you actually want to floor number to 2 decimal points, not to round it, so this answer could help you:
$value = 1234666.6666667;
floor($value * 100) / 100; // returns 1234666.66
If you want 3 decimal points you need to multiple and divide with 1000, for 4 - with 10000 and etc.
You can use number_format, it convert value to string though, so you lose real float value:
$value = 1234666.6666667;
echo number_format($value, 2, '.', ''); // prints 1234666.67
Use this function.
function truncate($i) {
return floor($i*100) / 100.0;
}
Then you can do
$value = truncate(123.5666666); // 123.56
A pragmatic way is to use round($value - 0.05, 2), but even that gets you into hot water with some edge cases. Floating point numbers just don't round well. It's life I'm afraid. The closest double to 1234666.66 is
1234666.65999999991618096828460693359375
That's what $value will be after applying my formula! Really, if you want exact decimal precision, then you need to use a decimal type. Else use integer types and work in multiples of 100.
For the former choice, see http://de2.php.net/manual/en/ref.bc.php
$value = bcadd($value, 0, 2); // 1234666.6666667 -> 1234666.66
Another more exotic way to solve this issue is to use bcadd() with a dummy value for the $right_operand of 0,
This will give you 2 number after decimal.

Always round up on first decimal

I want my variable's first decimal to always be rounded up. For example:
9.66 goes to 9.7
9.55 goes to 9.6
9.51 goes to 9.6
9.00000001 goes to 9.1
How do I do this?
Use round() with an optional precision and round type arguments, e.g.:
round($value, 1, PHP_ROUND_HALF_UP)
The optional second argument to round() is the precision argument and it specifies the number of decimal digits to round to. The third optional argument specifies the rounding mode. See the PHP manual for round for details.
Using round() does not always round up, even when using PHP_ROUND_HALF_UP (e.g. 9.00001 is not rounded to 9.1). You could instead try to use multiplication, ceil() and division:
ceil($value * 10.0) / 10.0
Since these are floating-point values, you might not get exact results.
I made couple tests and suggest the following answer with test cases
<?php
echo '9.66 (expected 9.7) => '.myRound(9.66).PHP_EOL;
echo '9.55 (expected 9.6) => '.myRound(9.55).PHP_EOL;
echo '9.51 (expected 9.6) => '.myRound(9.51).PHP_EOL;
echo '9.00000001 (expected 9.1) => '.myRound(9.00000001).PHP_EOL;
echo '9.9 (expected ??) => '.myRound(9.9).PHP_EOL;
echo '9.91 (expected ??) => '.myRound(9.91).PHP_EOL;
function myRound($value)
{
return ceil($value*10)/10;
}
I'm not a php programmer so will have to answer in "steps". The problem you have is the edge case where you have a number with exactly one decimal. (e.g. 9.5)
Here's how you could do it:
Multiply your number by 10.
If that's an integer, then return the original number (that's the edge case), else continue as follows:
Add 0.5
Round that in the normal way to an integer (i.e. "a.5" rounds up).
Divide the result by 10.
For step (2), sniffing around the php documentation reveals a function bool is_int ( mixed $var ) to test for an integer.
You will need a custom ceil() function, your requirements cannot be satisfied by the default function or by the round.
Use this: online test
You can use this technique. Just explode the given number / string, get the number which is next value / digit of the .. after getting this you need to increment that value and check if the value is greater than 9 or nor, if then divide that and add the carry to the first portion of the main number.
$var = '9.96';
$ar = explode(".", $var);
$nxt = substr($ar[1], 0, 1) + 1;
if($nxt > 9){
$tmp = (string) $nxt;
$num = floatval(($ar[0] + $tmp[0]).".".$tmp[1]);
}
else
$num = floatval($ar[0].".".$nxt);
var_dump($num); // float(10)

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

How to delete all numbers after point in PHP

example: 1.123 =>1 1.999 => 1
thanks.
$y = 1.235251;
$x = (int)$y;
echo $x; //will echo "1"
Edit:
Using the explicit cast to (int) is the most efficient way to to this AFAIK. Also casting to (int) will cut off the digits after the "." if the number is negative instead of rounding to the next lower negative number:
echo (int)(-3.75); //echoes "-3";
echo floor(-3.75); //echoes "-4";
floor()
will round a number down to the nearest integer.
EDIT: As pointed out by Mark below, this will only work for positive values, which is an important assumption. For negative values, you'd want to use ceil() -- but checking the sign of the input value would be cumbersome and you'd probably want to employ Mark's or TechnoP's (int) cast idea instead. Hope that helps.
You could use a bitwise operator.
Without:
echo 49 / 3;
>> 16.333333333333
With "| 0" bitwise:
echo 49 / 3 | 0;
>> 16
$y = 1.234;
list($y) = explode(".", "$y");
If your input can only be positive floats then as already mentioned floor works.
floor(1.2)
However if your integer could also be negative then floor may not give you what you want: it always rounds down even for negative numbers. Instead you can cast to int as another post mentioned. This will give you the correct result for both negative and positive numbers.
(int)-1.2
To remove all number after point use some php function
echo round(51.5); // Round the number, return 51.
echo floor(51.5); // Round down number, return 51.
echo ceil(51.3); // Round up number, return 52.

Categories