UPDATE - the problem was actually completely out of the rounding function. It seems as though $price (used in woo commerce) is a string and for some reason I can't use it in a calculation. If I simply return $price, no problem. All of this was fine when I was simply returning the value of the other function.
function xa_only_sale_price($price, $product)
{
error_log ("price in the beginning is " . $price);
if(!is_cart() && !is_checkout() && !is_ajax()){
if ($product->is_type('simple') || $product->is_type('variation')) {
$price = regularPriceHTML_for_simple_and_variation_product($price, $product);
$val = (float)$price;
error_log( "ceiling = " . ceil($val* 2) / 2); // 0 printed to log
return ceil($val* 2) / 2; this returns 0
// return roundNum(regularPriceHTML_for_simple_and_variation_product($price, $product));
}
}
error_log ("price before call is " . $price); // this returns 0
// return roundNum($price); //this is never in use
}
--------------- original post-----------------------------
I am new to php - thank you for all of the help in advance. I am assuming that this issue has something to do with data types but I haven't been able to figure this one out.
In this example $num is the price of a woocommerce product. If I simply return $num I see the price that I am expecting to see. I am simply trying to round the value in this function (I simplified the function for the sake of the question).
function roundNum($num){
$nearest = 0.50;
return ($num / $nearest) ;
This returns 0 to the browser. However, forcing the value of $num results in a valid calculation and return.
function roundNum($num){
$num = 100.0;
$nearest = 0.50;
return ($num / $nearest) ;
The simplest solution is to typecast your input. A small example in your case is:
function roundNum($num){
$nearest = 0.50;
$result = (float) $num/ (float) $nearest;
return $result;
}
Read more about typecasting here
EDIT:
As it turns out your $num is a string. You can change this to a type float and make your calculations, like so:
$num = "48.2";
$float = (float)$num;
echo ceil($float * 2) / 2;
In this example your number is always rounded up by 0.5, so in this case to 48.5
Demo
Related
I have a number that needs to be rounded up to a specific decimal, is there any function in PHP to do that?
I need every number (which reflects an amount of money) to have a specific decimal number.
For example:
The decimal needs to be 25, so if I got $ 25.50 I need it to be $ 26.25, and if I got $ 25.10 it needs to be $ 25.25.
I've checked PHP round(), and specifically ceil(), and I've come across this answer in Python, but I'm not sure it applies to my case, because what I need is different.
Any ideas? Even pseudo code as a tip on where to start will help me. Thanks!
I think you need a custom function, something like this:
function my_round($number, $decimal = 0.25) {
$result = floor($number) + $decimal;
if ($result < $number) $result = ceil($number) + $decimal;
return $result;
}
print my_round(25.50);
I modified this answer for your case:
<?php
function roundUp($number){
$int = floor($number);
$float = $number-$int;
if ($float*10 < 2.5)
$result = $int;
else
$result = ceil($number);
$result+= 0.25;
echo $number." becomes ".$result."\n";
}
roundUp(25.50);
roundUp(25.10);
Look for demo here
Following axiac's advice mentioned in the comments and following this thread, the best way to deal with floating point numbers in the context of currencies, is to treat the dollars and cents' values as 2 separate entities.
One way I can think of it to split the numbers before and after the decimal into 2 separate variables and process accordingly.
<?php
function customRound($amount){
$amount = strval($amount);
if(preg_match('/(\d+)\.?(\d{1,2})?/', $amount, $matches) !== 1){
throw new \Exception("Invalid amount.");
}
$dollars = intval($matches[1]);
$cents = intval($matches[2] ?? 0);
if($cents < 10) $cents *= 10;
if($cents <= 25) return $dollars . ".25";
return ($dollars + 1) . ".25";
}
$tests = [25.51,25.49,26.25,25.10,25.49];
foreach ($tests as $test){
echo $test," => ",customRound($test),PHP_EOL;
}
Here's another approach:
<?php
function roundUp($number, $decimal=0.25){
$dollars = floor($number);
$cents = $number - $dollars;
if($cents > $decimal) {
++$dollars;
}
return $dollars + $decimal;
}
echo roundUp(25.50).PHP_EOL;
echo roundUp(25.10);
#if($user->dettagli->facebook_follower >= 1000 && $user->dettagli->facebook_follower <= 999999)
<?php
echo(round($user->dettagli->facebook_follower, 5,PHP_ROUND_HALF_DOWN) . "K");
?>
{{$user->dettagli->facebook_follower / 1000}} K
#endif
Hi could someone please help me. I am using Laravel and trying to display a users Facebook follower count, but I got a little stuck with something. I am taking their int at for example 1589 followers and trying to return in the blade "1.5k". On screen I return either 1589k with this php call or 1.589k. How do I get that number to one decimal place and become only 1.5k??
thank you!
As per the docs
Returns the rounded value of val to specified precision (number of digits after the decimal point). precision can also be negative or zero (default).
You are specifying a precision of 5. You should change this to 1.
Change your function call to:
echo(round($user->dettagli->facebook_follower, 1, PHP_ROUND_HALF_DOWN) . "K");
EDIT: I mis-read the question. This is a function that should handle numbers into the millions.
You would need to use laravel-twigbridge to make the function available in your templates though.
function pretty_number(int $n): string {
$prettyN = $n;
$suffix = '';
$len = strlen((string) $n);
$suffixes = ['K', 'M'];
foreach ($suffixes as $s) {
if ($n < 1000) {
break;
}
$suffix = $s;
$n = $n / 1000;
$prettyN = number_format($n, 1);
}
return $prettyN . $suffix;
}
echo pretty_number(100); // 100
echo pretty_number(999); // 99
echo pretty_number(1589); // 1.6K
echo pretty_number(1600); // 1.6K
echo pretty_number(1589300); // 1.6M
You can use the NumberFormatter. This can be defined in a global place so you only need to use the third line in your blade view.
$a = new \NumberFormatter("en-US", \NumberFormatter::DECIMAL);
$a->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, 1);
echo $a->format($user->dettagli->facebook_follower);
I'm finding it really hard to match the values properly.
I have a Excel formula e.g.
=CEILING(8/2,0.5)
How do I convert it into PHP. I have tried the following function from this link but doesn't work properly
function ceiling($number, $significance = 1){
return ( is_numeric($number) && is_numeric($significance) ) ? (ceil($number/$significance)*$significance) : false;
}
I have also tried the Ceil function. Same as above, doesn't work properly. I values are mismatched compare to Excel.
This should work for you. Not sure if it takes much explanation...it just calculates the $multiple and rounds up one integer from there and multiplies by the number parameter. That will mimic Excel's ceiling function.
function ceiling($number, $significance){
$multiple = $number / $significance;
$remainder = $number % $significance;
if($remainder == 0){
$result = $number;
}else{
$result = ceil($multiple) * $significance;
}
echo "\nceiling($number, $significance)";
echo "\nmultiple = $multiple";
echo "\nremainder = $remainder";
echo "\nresult = $result\n";
return $result;
}
So this will be very specific question, but I am losing my sanity as I was staring at this for the better part of the day. So here I wrote this function to calculate the price dependent commission:
function commision($amount, $commision_arg = 0){
// $temp_amount = 0;
// $commision = 0;
if($amount > 999){
$temp_amount = $amount - 999;
$commision_arg += $temp_amount/100*1;
return commision(999, $commision_arg);
}else if($amount>249&&$amount<=999){
$temp_amount = $amount - 249;
$commision_arg += $temp_amount/100*3;
return commision(249, $commision_arg);
}else if($amount>49 && $amount<=249){
$temp_amount = $amount - 49;
$commision_arg += $temp_amount/100*5;
return commision(49, $commision_arg);
}else if($amount <= 49){
return number_format($commision_arg + 3.5, 2);
}
}
Basically if $amount is less then 49 then it is just flat 3.5 rate, if $amount is 49 to 249 then it is flat rate 3.5 + 5% of anything in 49-249 range.
I am not sure if this is good way to do this or not, but it works. However there is issue with another method that uses this function:
public function amountPayable(){
$amount = $this->uri->segment(3);
echo $amount - commision($amount);
}
This is just a function in codeigniter controller, that is called by AJAX request, and it should be returning the amount payable by the customer, which is then injected into DOM.
And this is where the problem lies.
Basically if I pass the $amount that equal to 100.000, what I get back from amountPayable is 99.999, whereas it should be: 98973.9. if I change echo $amount - commision($amount); to echo commision($amount); then I get back 1026.1. So the commision() function returns the correct number. But for some reason $amount - commision($amount); (where $amount = 100000) evaluates to 1.
How can this be?
I could never think it would be even challenging but is there any function to calculate a percentage of a number or do I have to write a custom function?
Example:
$result=percent(25,100); //doing the 100%25 operation
$result = 4
function percentage($part, $whole = 100) {
settype($part, "float");
settype($whole, "float");
$formule = ($part / $whole) * 100;
return $formule . " %";
}
echo percentage(25); // returns 25 %
echo percentage(91.8, 176); // returns 52,15909090909091 %
Voila ;-) Could be improved more, but i saw that you figured it out for yourself, so not needed anymore..