I'm working on a 5 stars products review for a website using php and MySQL, everything works great except my total stars,
When the review is submitted the customer can only add from 1 to 5 stars (no .5) then I'm summing the rating of each review and dividing it by the number of reviews. Now the proble is I need to get either 1, 1.5, 2, 2.5 and so on and sometimes I'll get something like 3.66768748.
How can I round the number so that if it's below if it's more that .5 it will be the ceil, if it's .5 it stays as is and if it's less than .5 it will floor it?
Is there a built in function that I can use for this?
Thank you in advance!
The following function will round to whichever is closest - the next lowest integer, the next highest integer, or the halfway point between them.
function half_star_round($input) {
$frac = $input - floor($input);
if($frac < 0.25) {
return floor($input);
} else if($frac >= 0.75) {
return ceil($input);
} else {
return floor($input) + 0.5;
}
}
This works. Pass the value you want to be rounded to in the second arg. In your case 0.5
function roundTo($value, $roundTo = 1) {
$rounded = round($value); // 4
$roundToComparer = $roundTo / 2;
if ($value < $rounded) { // rounded to ceiling
if (($rounded - $roundToComparer) > $value) {
$rounded = $rounded - $roundTo;
}
} else { // rounded to floor
if (($rounded + $roundToComparer) < $value) {
$rounded = $rounded + $roundTo;
}
}
return $rounded;
}
$rating = 3.66768748;
echo roundTo($rating, 0.5);
Take the sum of the reviews
Divide by the total reviews
Multiply by two
Round
Divide by two
Php proveide round function for that.
http://php.net/manual/en/function.round.php
Related
I want to round up my variable if it's decimal larger than .3 and if it's lower or equal it will round down, for example if i have 1.34 it will round up to 2, if i have 1.29 it will round down to 1, and if i have 1.3 it will round down to 1. I don't know how to do this precisely, right now i'm using the round basic function like this:
$weight = $weight/1000;
if($weight < 1) $weight = 1;
else $weight = round($weight, 0, PHP_ROUND_HALF_DOWN);
If you manipulate the numbers a bit, you can figure out if the decimals are .3 or higher. You achieve this by flooring the value, and subtract that from the original value. Check if the result of that, multiplied by 10, is greater than 3. If it is, you've got something above x.3.
$number = 1.31;
$int = floor($number);
$float = $number-$int;
if ($float*10 > 3.1)
$result = ceil($number);
else
$result = $int;
echo $result; // 2
Live demo
I made you a little hack, here's the code
$weight = 5088;
$weight = $weight/1000;
if($weight < 1) {
$weight = 1;
} else {
// I get the last number (I treat the $weight as a string here)
$last_number = substr($weight, -1, 1);
// Then I get the precision (floating numbers)
$precision = strlen(substr(strrchr($weight, "."), 1));
// Then I convert it to a string so I can use some helpful string functions
$weight_str = (string) $weight;
// If the last number is less then 3
if ($last_number > 3)
// I change it to 9 I could just change it to 5 and it would work
// because round will round up if then number is 5 or greater
$weight_str[strlen($weight_str) -1] = 9;
}
}
// Then the round will round up if it's 9 or round down if it's 3 or less
$weight = round($weight_str, $precision);
echo $weight;
Maybe something like this function?
function roundImproved($value, $decimalBreakPart = 0.3) {
$whole = floor($value);
$decimal = $value - $whole;
$decimalPartLen = strlen($decimal) - 2;
return (number_format($decimal, $decimalPartLen) <= number_format($decimalBreakPart, $decimalPartLen) ? $whole : ceil($value));
}
Proof:
http://sandbox.onlinephpfunctions.com/code/d75858f175dd819de069a8a05611ac9e7053f07a
You can specify "break part" if you want.
Is there a way to set a probability control on getting a random value either 1 or 2? Suppose if I want more than 70% of the time it should be 1 and only 30% should be the chance of getting 2 in rand(1,2). Is it possible?
Generate a number between 1 and 10, then if the number is greater than 7, return 2, else return 1
x = rand(1, 10);
if(x > 7){
return 2;
}
else {
return 1;
}
You will have 70% and 30% of chance to get the number you want
Why don't you generate a uniformly distributed random number and then filter the number with an if?
int x,r;
r=rand() % 100; // r in the range 0 to 99
if(r<=70){x=1;}
else{x=2;}
This should do the trick:
function yourrand($prob) {
$r = rand();
if ($r < $prob) { return 1; }
else { return 2; }
}
I need some help. It's a simple code, but I don't have idea how to write in down. I have the numbers:
$NumberOne = 500;
$NumberTwo = 430;
$NumberThree = 150;
$NumberFour = 30;
At all this is:
$Everything = 1110; // all added
Now I want to show what percentage is for example $NumberFour of everything or what percentage is $NumberTwo of $Everything. So the "market share".
Use some simple maths: divide the number you wish to find the percentage for by the total and multiply by 100.
Example:
$total = 250;
$portion = 50;
$percentage = ($portion / $total) * 100; // 20
Solution to original example
To get $NumberFour as a percentage of the total amount you'd use:
$percentage = ($NumberFour / $Everything) * 100;
Rounding
Depending on the numbers you're working with, you may want to round the resulting percentage. In my initial example, we get 20% which is a nice round number. The original question however uses 1110 as the total and 30 as the number to calculate the percentage for (2.70270...).
PHP's built in round() function could be useful when working with percentages for display: https://www.php.net/manual/en/function.round.php
echo round($percentage, 2) . '%'; // 2.7% -- (30 / 1110) * 100 rounded to 2dp
Helper Functions
I would only contemplate creating helper functions when their use justifies it (if calculating and displaying a percentage isn't a one-off). I've attached an example below tying together everything from above.
function format_percentage($percentage, $precision = 2) {
return round($percentage, $precision) . '%';
}
function calculate_percentage($number, $total) {
// Can't divide by zero so let's catch that early.
if ($total == 0) {
return 0;
}
return ($number / $total) * 100;
}
function calculate_percentage_for_display($number, $total) {
return format_percentage(calculate_percentage($number, $total));
}
echo calculate_percentage_for_display(50, 250); // 20%
echo calculate_percentage_for_display(30, 1110); // 2.7%
echo calculate_percentage_for_display(75, 190); // 39.47%
Create function to calculate percentage between two numbers.
<?php
/**
* Calculate percetage between the numbers
*/
function percentageOf( $number, $everything, $decimals = 2 ){
return round( $number / $everything * 100, $decimals );
}
$numbers = array( 500, 430, 150, 30 );
$everything = array_sum( $numbers );
echo 'First of everything: '.percentageOf( $numbers[0], $everything )."%\n";
echo 'Second of everything: '.percentageOf( $numbers[1], $everything )."%\n";
echo 'Third of everything: '.percentageOf( $numbers[2], $everything )."%\n";
echo 'Fourth of everything: '.percentageOf( $numbers[3], $everything )."%\n";
?>
This outputs
First of everything: 45.05%
Second of everything: 38.74%
Third of everything: 13.51%
Fourth of everything: 2.7%
You can also come up with the percentage with the following formula. For the percentage, add a 0. in front of it. So 5% would be 0.05. Total X 0.05 is the amount.
I know ceil, which will round 15.1 to 16 and 31.2 to 32.
But how to round up to the next x20 number? like 15.1 to 20 and 31,2 to 40?
Is needed to make sensefull labels for the y-axis of a chart.
Try this (works in JavaScript):
$result = 20 * ceil($input / 20);
Here, we're rounding to 20. To round to other numbers, simply replace 20 with whatever base you want. The documentation for ceil() can be found here.
A function that does the same:
function roundTo($value, $base)
{
return $base * ceil($value / $base);
}
As a small aside, if you want to round to the nearest base, instead of rounding up, use round() instead of ceil().
divide by 20 and use ceil, then multiply by 20
Or you could use modulus:
echo round($a + 20 - ($a % 20));
If you want "mid-range" values to round more, you can use the following.
function roundTo($n,$i = 1){
$r = $n % $i;
$d = round(($n - $r * $i) / $i);
return $r * $i + $d * $i;
}
for ($a = 0; $a < 100; $a++){
printf("%d = %d\r\n", $a, ceil2($a, 20));
}
The above produces:
Number: Rounded To:
0-10 0
11-30 20
31-50 40
etc.
This more closely simulates how 1.3=1 but 1.5=2.
you can use this
ceil(x/2)*2
Time to test your math skills...
I'm using php to find the average of $num1, $num2, $num3 and so on; upto an unset amount of numbers. It then saves that average to a database.
Next time the php script is called a new number is added to the mix.
Is there a math (most likely algebra) equation that I can use to find the average of the original numbers with the new number included. Or do I need to save the original numbers in the database so I can query them and re-calculate the entire bunch of numbers together?
array_sum($values) / count($values)
If what you mean by average is the 'mean' and you don't want to store all numbers then store their count:
$last_average = 100;
$total_numbers = 10;
$new_number = 54;
$new_average = (($last_average * $total_numbers) + $new_number) / ($total_numbers + 1);
Average = Sum / Number of values
Just store all 3 values, there's no need for anything complicated.
If you store the Average and Sum then calculate Number of values you'll lose a little accuracy due to truncation of Average.
If you store the Average and Number of values then calculate Sum you'll lose even more accuracy. You have more margin for error in calculating a correct value for Number of values than Sum thanks to it being an integer.
<?php
function avrg()
{
$count = func_num_args();
$args = func_get_args();
return (array_sum($args) / $count);
}
?>
http://php.net/manual/en/function.array-sum.php#101727
Thought that I should share my function
function avg(array $values) {
$sum = array_sum($values);
$count = count($values);
return ($count !== 0)? $sum / $count: NAN;
}
echo avg([1, 2, 3, 4]); // 2.5
Will return the average and also take into account 0, for example dividing by zero always returns NaN (Not a number)
1/0 = NaN
0/0 = NaN
If you know the amount of numbers you can calculate the old sum, add the new one and divide by the old amount plus one.
$oldsum = $average * $amount;
$newaverage = ($oldsum + $newnum) / ($amount + 1);
Typically what you might do is save two pieces of information:
the sum of all the numbers
the count of numbers
Whenever you want to get the average, divide the sum by the count (taking care for the case of count == 0, of course). Whenever you want to include a new number, add the new number to the sum and increment the count by 1.
This is called a 'running average' or 'moving average'.
If the database stores the average and the number of values averaged, it will be possible to calculate a new running average for each new value.
function avgvals($avg_vals,$avg_delimiter=',') {
if ( (is_string($avg_vals) && strlen($avg_vals) > 2) && (is_string($avg_delimiter) && !empty($avg_delimiter)) ) {
$average_vals = explode($avg_delimiter, $avg_vals);
$return_vals = ( array_sum($average_vals) / count($average_vals) );
} elseif ( (is_string($avg_vals) && strlen($avg_vals) <= 2) && (is_string($avg_delimiter) && !empty($avg_delimiter)) ) {
$return_vals = $avg_vals;
} else {
$return_vals = FALSE;
}
return $return_vals;
}
Code:
function avg($list){
$sum = array_sum($list);
$count = count($list);
return ($count)? $sum / $count: NAN;
}
print ("Average: ".avg([1,2,3,4,5]));
Output:
Average: 3
You need to save all the original numbers in the database.