round up decimal values to exact integer value php - php

I have came across the php rounding decimal values by using:
The round() function rounds a floating-point number.
To round a number UP to the nearest integer, look at the ceil() function.
To round a number DOWN to the nearest integer, look at the floor() function.
I have an example of dividing 1000/13 which when we use
round(1000/13, 2) will give you 999.98 and then i will use ceil to round it to 1000.
Now, my value is 925.6 which has to be divided by 11 and I tried with the round(925.6/11, 2) which will give 84.15, then if u multiply this with 11(84.15 * 11)then you will get 925.56. Now how can achieve the exact decimal if any decimal input.

Rounding-off a Double or Float using round(), ceil() or floor() all have one thing in Common and that is: by using them you are subscribing to losing the Precision of your Data. This means; once the die is cast, you cannot get the Original value again.... it is that simple:
If you want to retain both the Truncated and the Original Values, you have to do it differently.... You may need to keep 2 Variables or simply put your Variables in an Array. A Simple example would demonstrate this even better:
<?php
$num = (925.6/11);
// STORE THE ORIGINAL & ROUNDED VALUES IN AN ARRAY (IN CASE YOU NEED BOTH)
$arrNumbers = [
'original' => $num,
'rounded' => round($num, 2),
];
// NOW; FOR YOUR MULTIPLICATIONS:
$original = $arrNumbers['original'] * 11;
$broken = $arrNumbers['rounded'] * 11;
var_dump($original); //<== float 925.6
var_dump($broken); //<== float 925.65 :: ADDED AN EXTRA 0.05 (BOGUS, HUH?)
var_dump($arrNumbers); //<== array (size=2) 'original' => float 84.1454545455 'rounded' => float 84.15
UPDATE: NUMERATOR AS A VALUE FROM FORM-FIELD.
<?php
// ASSUME THE VALUE OF THE NUMERATOR IS: 925.6
$numerator = htmlspecialchars(trim($_POST['some_field']));
// AND THE DENOMINATOR IS NOW SOMETHING LIKE MONTH 11 AS IN: 11.0000
$denominator = 11.0000;
// NO PROBLEMS STILL...
$num = ($numerator/$denominator);
// STORE THE ORIGINAL & ROUNDED VALUES IN AN ARRAY (IN CASE YOU NEED BOTH)
$arrNumbers = [
'original' => $num,
'rounded' => round($num, 2),
];
// NOW; FOR YOUR MULTIPLICATION,
// TO GET THE STARTING VALUES BACK DO:
$original = $arrNumbers['original'] * 11;
$broken = $arrNumbers['rounded'] * 11;
var_dump($original); //<== float 925.6
var_dump($broken); //<== float 925.65 :: ADDED AN EXTRA 0.05 (BOGUS, HUH?)
var_dump($arrNumbers); //<== array (size=2) 'original' => float 84.1454545455 'rounded' => float 84.15

Related

PHP string to decimal with .00

so I am trying to achieve this
I have decimal 1.00 Which when i convert to float becomes 1.0. So my question is how can i save the last zero and at the same time to be float not a string if i use number_format(1.0,2) it becomes "1.00" Which is string but i need to be decimal with the last zero. This is what i tried so far
<?php
$decimal = "1.0";
$decimalToFloat = floatval($decimal) // It becomes 1.0
$decimalToFloat = number_format($decimal,2) // It becomes "1.00" !!! String not a float !!!
// The result which i want is 1.00 not "1.00"
Let me start by saying that this is an XY problem, as you don't need to convert from a string to an integer in PHP, as PHP will coerce the type for you automatically.
In addition to this, there is no need to specify the number of places on a decimal, as 1 is exactly equal to 1.0, and 1.0 is exactly equal to 1.00. In fact, forcibly casting the string showcases that PHP will automatically trim the decimal places:
$decimal = "1.0";
echo number_format((float)$decimal, 2, '.', ''); // "1.00" (string)
echo (int)number_format((float)$decimal, 2, '.', ''); // 1 (int)
echo (float)number_format((float)$decimal, 2, '.', ''); // 1 (float)
It is impossible to showcase an int or float with decimal places comprised purely of zeros in PHP. Though you do not need to do this; you can simply use the whole numbers instead:
echo 1 + 1.01; // 2.01 (float)
Hope this helps! :)

PHP round to integer

I want to round a number and I need a proper integer because I want to use it as an array key. The first "solution" that comes to mind is:
$key = (int)round($number)
However, I am unsure if this will always work. As far as I know (int) just truncates any decimals and since round($number) returns a float with theoretically limited precision, is it possible that round($number) returns something like 7.999999... and then $key is 7 instead of 8?
If this problem actually exists (I don't know how to test for it), how can it be solved? Maybe:
$key = (int)(round($number) + 0.0000000000000000001) // number of zeros chosen arbitrarily
Is there a better solution than this?
To round floats properly, you can use:
ceil($number): round up
round($number, 0): round to the nearest integer
floor($number): round down
Those functions return float, but from Niet the Dark Absol comment: "Integers stored within floats are always accurate, up to around 2^51, which is much more than can be stored in an int anyway."
round(), without a precision set always rounds to the nearest whole number. By default, round rounds to zero decimal places.
So:
$int = 8.998988776636;
round($int) //Will always be 9
$int = 8.344473773737377474;
round($int) //will always be 8
So, if your goal is to use this as a key for an array, this should be fine.
You can, of course, use modes and precision to specify exactly how you want round() to behave. See this.
UPDATE
You might actually be more interested in intval:
echo intval(round(4.7)); //returns int 5
echo intval(round(4.3)); // returns int 4
What about simply adding 1/2 before casting to an int?
eg:
$int = (int) ($float + 0.5);
This should give a predictable result.
Integers stored within floats are always accurate, up to around 253, which is much more than can be stored in an int anyway. I am worrying over nothing.
For My Case, I have to make whole number by float or decimal type
number. By these way i solved my problem. Hope It works For You.
$value1 = "46.2";
$value2 = "46.8";
// If we print by round()
echo round( $value1 ); //return float 46.0
echo round( $value2 ); //return float 47.0
// To Get the integer value
echo intval(round( $value1 )); // return int 46
echo intval(round( $value2 )); // return int 47
My solution:
function money_round(float $val, int $precision = 0): float|int
{
$pow = pow(10, $precision);
$result = (float)(intval((string)($val * $pow)) / $pow);
if (str_contains((string)$result, '.')) {
return (float)(intval((string)($val * $pow)) / $pow);
}
else {
return (int)(intval((string)($val * $pow)) / $pow);
}
}
Round to the nearest integer
$key = round($number, 0);

Excel rounddown function equivalent in php

Everyday we need to calculate number of units allocated based on two variables called investment amount and NAV. This we are doing now in Excel using rounddown function, which I am trying to achieve in PHP but it is sometimes rounding up the result.
In Excel:
Cell A1 = 287011570.56
Cell B1 = 14.9482
Cell C1 = =ROUNDDOWN(A1/ROUND(B1,4),4)
= 19200410.1202
In PHP:
<?php
$var1=287011570.56;
$var2=14.9482;
$var3=$var1/$var2;
$var4 = floor(($var3) * 100000 + .5) * .00001;
$var5 = intval($var4);
$var6 = strlen($var5)+5;
$test = substr("$var4", 0, $var6);
print "$test";
?>
Result : 19200410.1203
The result should contain 4 digits after decimal and it should not round up the result.
Thanks in advance.
You shouldn't need to add the 0.5 when you are using floor(). That can move the value to the next highest value which you don't want when you are doing division.
From your example just doing:
floor($var3 * 10000) / 10000
Gave me the correct result and should work properly.
Use Round - float round ( float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]] ).
You need to pass PHP_ROUND_HALF_DOWN as 3rd parameter(Mode).
round($value, 4, PHP_ROUND_HALF_DOWN);
If mode parameter is not available in your version of PHP(as it didn't work for me) then use this:
floor($value * 10000) / 10000;

Rounding in PHP to achieve 100%

I need to total the number of clicks over 10 links on my page and then figure out the percentage of people that clicked each. This is easy division, but how do I make sure that I get a round 100% at the end.
I want to use the below code, but am worried that a situation could arise where the percentages do not tally to 100% as this function simply removes the numbers after the period.
function percent($num_amount, $num_total) {
$count1 = $num_amount / $num_total;
$count2 = $count1 * 100;
$count = number_format($count2, 0);
echo $count;
}
Any advice would be much appreciated.
Instead of calculating one percentage in your function you could pass all your results as an array and process it as a whole. After calculating all the percentages and rounding them make a check to see if they total 100. If not, then adjust the largest value to force them all to total 100. Adjusting the largest value will make sure your results are skewed as little as possible.
The array in my example would total 100.02 before making the adjustment.
function percent(array $numbers)
{
$result = array();
$total = array_sum($numbers);
foreach($numbers as $key => $number){
$result[$key] = round(($number/$total) * 100, 2);
}
$sum = array_sum($result);//This is 100.02 with my example array.
if(100 !== $sum){
$maxKeys = array_keys($result, max($result));
$result[$maxKeys[0]] = 100 - ($sum - max($result));
}
return $result;
}
$numbers = array(10.2, 22.36, 50.10, 27.9, 95.67, 3.71, 9.733, 4.6, 33.33, 33.33);
$percentages = percent($numbers);
var_dump($percentages);
var_dump(array_sum($percentages));
Output:-
array (size=10)
0 => float 3.51
1 => float 7.69
2 => float 17.22
3 => float 9.59
4 => float 32.86
5 => float 1.28
6 => float 3.35
7 => float 1.58
8 => float 11.46
9 => float 11.46
float 100
This will also work with an associative array as the function parameter. The keys will be preserved.
These figures could now be presented in a table, graph or chart and will always give you a total of 100%;
What you want to do is this.
Total the number of clicks across the board, then divide each number by the total.
For example:
1134
5391
2374
2887
In this case, four buttons, with a total of 11786 clicks, so:
1134 / 11786 = 0.09621....
5391 / 11786 = 0.45740....
2374 / 11786 = 0.20142....
2887 / 11786 = 0.24495....
Then for each division, round the result to 'two decimal points', so the first result:
0.09621.... becomes 0.10
because the 3rd point is 5 or above, it would remain at 0.09 if the 3rd point was below 5.
Once you have all of the results rounded, multiply each by 100 then add them up.
The ending result will always be 100.
Should warn you however that depending on how you use each individual percentage, when you round them, any result less that 0.05 will become 0%, unless you keep the value before you round it so you can declare it as a percentage less than 1.
I think you want to use ceil() or round() .
Since these are floating point numbers, there is room for error. Be careful how you round, and be sure that you don't independently calculate the last remaining percentages. Simply subtract the total of what you have from 1 or 100.
Make sure you dont calculate separate sides of the equation, sum one side, then subtract the other from 1 or 100 or however you are handling your percentages.
I run into this quite a bit and have a hack for it.
$percentages = array(
'1' => 87.5,
'2' => 12.5,
'3' => 0,
'4' => 0,
'5' => 0
);
If you round those percentages for output, you will end up with 88% and 13% (101%)
round($percentages['1']);
round($percentages['2']);
// 88
// 13
So here is the code I use to fix it.
$checkTotal = array_sum($percentages);
$max = max(array_keys($percentages));
if ($checkTotal > 100) {
$percentages[$max] = $percentages[$max] - 1;
}
if ($checkTotal < 100) {
$percentages[$max] = $percentages[$max] + 1;
}
If it is 100, do nothing.
If it is less than 100, add 1 to equal 100
If it is over 100, subtract 1 to equal 100

Conversion and rounding help

I need to convert pounds to kilograms and vice versa -- and round the number to the nearest quarter (and possibly half). I need to be able to make a conversion, take that conversion and convert it back, and have all the values still be the same.
Sample code:
for ($i = 1; $i <= 100; $i = $i + .25)
{
$kilograms = convert_pounds_to_kilograms($i);
$pounds = convert_kilograms_to_pounds($kilograms);
$new_kilograms = convert_pounds_to_kilograms($pounds);
echo ("$i => $pounds => $kilograms => $new_kilograms<br/>");
}
function convert_pounds_to_kilograms($pounds)
{
assert(is_numeric($pounds) === TRUE);
$kilograms = $pounds * 0.45359237;
// Round to the nearest quarter
$kilograms = round($kilograms * 4, 0) / 4;
return $kilograms;
}
function convert_kilograms_to_pounds($kilograms)
{
assert(is_numeric($kilograms) === TRUE);
$pounds = $kilograms * 2.20462262185;
// Round to the nearest quarter
$pounds = round($pounds * 4, 0) / 4;
return $pounds;
}
The first line of output is correct:
1 => 1 => 0.5 => 0.5
The second is not correct:
1.25 => 1 => 0.5 => 0.5
(the value 1 should have been 1.25)
How do I do this? I'm not looking for precision in the conversion, obviously. I just need to be able to convert these imprecise values back and forth to the same number.
EDIT 1:
The reason for this is that I will be allowing users to enter their height in centimeters, meters, or feet/inches -- then saving whatever their entered value to centimeters (thus, the first conversion). Users can then view their height in either centimeters, meters, or feet/inches (thus, a possible conversion again).
So, say a user enters their height in ft/inches, I need to store that in centimeters. Then the user may want to see that height again in ft/inches -- meaning I need to convert the centimeters back to the original ft/inches value.
Users will probably be limited to entering and viewing values to quarter increments. Meaning, 5'8.25" is valid, but not 5'8.39".
Do not round in the function itself. Go as precise as you can. Only round right before you display it.
If you round it off in the functions, then the ROUNDED value is put into the next function. If you keep doing this, you're going to lose a lot of precision, and you'll get less precise results the more you loop it.
You are rounding to 0 decimal places, hence the 1.25 is rounded to 1.
Try removimg the round() function and see what happens.
http://php.net/manual/en/function.round.php
Edit
To address your comment change:-
$kilograms = convert_pounds_to_kilograms($i);
To:-
$kilograms = round(convert_pounds_to_kilograms($i), 0);
And remove round() from inside your functions.
You're rounding out the precision. Your $pounds that you're printing out are converted from original value ($i) to kilograms with a round function, and then back to pounds with a round function; the round() is causing your values to converge.

Categories