Round up numbers - php

I get some numbers from database. I would like round up these numbers this way:
Database => Round up number
34 => 0
89 => 100
421 => 400
561 => 600
4421 => 4000
6701 => 7000
45000 => 50000
91000 => 90000
132000 => 130000
Is there any php function to do this? So numbers under 1000 would be round up closest full 100. Over thousands would be rounded up to nearest full 1000 figure. And if number is over 10 000 then it would be always rounded up to closest full 10 000.
Hopefully you understand what I'm after.

Since I'm fed up of people not reading the damn question...
function myRound(int $number) : int {
// remove typehints if you're on old versions of PHP...
$magnitude = abs($number);
if( $magnitude < 1000) $precision = -2;
elseif( $magnitude < 10000) $precision = -3;
else $precision = -4;
return round($number,$precision);
}
IDEOne test

You can use some simple math(mostly to calc num length) and build in with negative precision round() function
function customRound($number) {
return round($number, -floor(log10($number)));
}
echo customRound(6701); // sample of usage
-floor(log10($number)) this part is to calc length of num - 1 and also it is negated for round() needs

Have a look at the round() function here
http://php.net/manual/en/function.round.php
and the ceil() function here
http://php.net/manual/en/function.ceil.php
Something like
$number = 1;
$number = ceil($number / 10) * 10;
echo $number;

Here is one solution:
$numbers = [
34,
89,
421,
561,
4421,
6701,
45000,
91000,
132000
];
foreach ($numbers as $number) {
$len = strlen((string)$number);
$precision = $len - 1;
$precision = $len <= 2 ? 2 : $precision;
$precision = $len > 4 ? 4 : $precision;
echo $number . ' => '. round($number, -1 * $precision) . PHP_EOL;
}
Outputs:
34 => 0
89 => 100
421 => 400
561 => 600
4421 => 4000
6701 => 7000
45000 => 50000
91000 => 90000
132000 => 130000

You can use a function like this:
$number = 45000;
function rounder($num)
{
$length = strlen($num);
if(is_int($num))
{
if($num < 100)
return round($num, -($length));
elseif($num < 1000 || $num <= 9999)
return round($num, -($length-1));
else
return round($num, -4);
}
}
echo rounder($number);
Though not tested, should work..

Related

Calculating Median of an array in PHP

I'm trying to figure out how to calculate the median of an array of randomly generated numbers. I have the array all set up, but I'm having trouble putting together a function for the calcuation.
This is what I have so far:
//array
$lessFifty = array();
$moreFifty = array();
//number generation
for ($i = 0; $i<=30; $i++) {
$number = rand(0, 100);
//Sorting <50>
if ($number < 50 ) {
$lessFifty[] = $number;
} else {
$moreFifty[] = $number;
}
}
echo print_r($lessFifty);
echo "<br>" ;
echo print_r($moreFifty);
//Average
echo "<p> Average of values less than fifty: </p>";
print array_sum($lessFifty) / count($lessFifty) ;
echo "<p> Average of values greater than fifty: </p>" ;
print array_sum($moreFifty) / count($moreFifty) ;
//Median
$func = function (median ($array, $output = $median)){
if(!is_array($array)){
return FALSE;
}else{
switch($output){
rsort($array);
$middle = round(count($array) 2);
$total = $array[$middle-1];
break;
return $total;
}
}
echo $func ;
I'm pretty sure that I'm doing this median section completely wrong. I'm just learning and its proving to be a challenge.
Be careful about how you write your for() loop. If you want 30 entries, then you should not use <= or you will end up with 31 because $i starts with 0.
Build an array of the random numbers, then sort them.
Then determine if you have a central entry (odd array length) or if you need to average the middle two entries (even array length).
Here is a modern implementation of a median method posted in 2022 on CodeReview.
Code: (Demo)
$limit = 30; // how many random numbers do you want? 30 or 31?
for ($i = 0; $i < $limit; ++$i) {
$numbers[] = rand(0, 100);
}
var_export($numbers);
//echo "\n---\nAverage: " , array_sum($numbers) / $limit;
echo "\n---\n";
sort($numbers);
$count = sizeof($numbers); // cache the count
$index = floor($count/2); // cache the index
if (!$count) {
echo "no values";
} elseif ($count & 1) { // count is odd
echo $numbers[$index];
} else { // count is even
echo ($numbers[$index-1] + $numbers[$index]) / 2;
}
Possible Output:
array (
0 => 27,
1 => 24,
2 => 84,
3 => 43,
4 => 8,
5 => 51,
6 => 60,
7 => 86,
8 => 9,
9 => 48,
10 => 67,
11 => 20,
12 => 44,
13 => 85,
14 => 6,
15 => 63,
16 => 41,
17 => 32,
18 => 64,
19 => 73,
20 => 43,
21 => 24,
22 => 15,
23 => 19,
24 => 9,
25 => 93,
26 => 88,
27 => 77,
28 => 11,
29 => 54,
)
---
43.5
After sorting, elements [14] and [15] hold 43 and 44 respectively. The average of these "middle two" values is how the result is determined. (Hardcoded numbers demo)
If you want a short, inflexible, hardcoded snippet, then you can use 30 and 14 and 15 as your predetermined size and indexes.
for ($i = 0; $i < 30; ++$i) {
$numbers[] = rand(0, 100);
}
sort($numbers);
echo ($numbers[14] + $numbers[15]) / 2;

Alternating Algorithm Starting from Center

I'm trying to figure out an algorithm to come up with an arrayed result that are equidistant alternating points from the center (can be percent based). So, my end result would be something like:
X = 20 (separation distance based on # of items) - 100 / 5 (5 items spread out over 100%)
A = 50 (center point)
B = 70 (A + 20)
C = 30 (A - 20)
D = 90 (B + 20)
E = 10 (C - 20)
Another result would be if we have 10 items (X = 100 / 10):
A = 50 (center point)
B = 60 (A + 10)
C = 40 (A - 10)
D = 70 (B + 10)
E = 30 (C - 10)
F = 80 (D + 10)
G = 20 (E - 10)
H = 90 (F + 10)
I = 10 (G - 10)
J = 100 (H + 10)
If it's important, I'm trying to arrive at this algorithm using PHP. I'm not much of a Math wiz so I'm not sure if there's a name for this type of calculation. Thanks!
You could write a function like:
function getArrayEquidistant($startValue, $step, $nbEntries)
{
$i = 0;
$count = 1;
$final = array();
$final[] = $startValue;
while($i < $nbEntries)
{
if ($i % 2 == 0)
$final[] = $startValue + ($count * $step);
else
{
$final[] = $startValue + ($count * $step);
$count++;
}
$i++;
}
retun $final;
}
Where $startValue is the initial value (at index 0), $step is the value added or sub at each iteration, and $nbEntries the number of entries after the initial value.
As example:
print_r(getArrayEquidistant(50, 20, 10));
will give you:
Array
(
[0] => 50
[1] => 70
[2] => 30
[3] => 90
[4] => 10
[5] => 110
[6] => -10
[7] => 130
[8] => -30
[9] => 150
[10] => -50
)
If I understood you correctly, this should work:
function pointsArray($center, $numPoints) {
$arr = array();
$arr[0] = $center;
for($i = 1;$i < $numPoints; $i++)
$arr[$i] = $i%2 == 0 ? $center - ($i-1)*20 : $center + $i*20;
return $arr;
}
Than, you can use the function like this:
$PointsArray = pointsArray(50, 5); // {50,70,30,90,10}

Best way to get N numbers from range betwen 2 (big) numbers

Hello I need to get N numbers from range between 2 big numbers, without the start and end numbers.
The (N) numbers must be on equal intervals... I will try to explain with small numbers:
<?php
$rangeStart = 0;
$rangeEnd = 100;
$n = 9;
In this example i need to get 10,20,30,40,50,60,70,80,90
I have try with 'for loop' but it is veeery slow, because I'm using range like 1207083600 ~ 1275512399
Will appreciate any help.
=====
This is what I call slow http://jsfiddle.net/pbF7N/1/
The start and end are timestamps and I need to extract 10 dates...
range() with its optional 3rd parameter to specify the step size...
range(10, 90, 10);
$range = range(10, 90, 10);
print_r($range);
Array
(
[0] => 10
[1] => 20
[2] => 30
[3] => 40
[4] => 50
[5] => 60
[6] => 70
[7] => 80
[8] => 90
)
Something like this maybe:
function nrange($num, $start, $end)
{
$out = array(); $i = 0;
$interval = floor(($end - $start) / ($num + 1));
while ($i++ < $num )
$out[] = $start + $i * $interval;
return $out;
}
Consider first your example case. Your numbers broke up the range [0..100) into 10 equal intervals, [0..10), [10, 20), etc. up to [90..100).
Notice that the number of intervals is $n+1. So you see that each interval is of length ($rangeEnd - $rangeStart) / $n.
Using this information, you can use range to step across $interval numbers at a time, i.e.,
$interval = ($rangeEnd - $rangeStart) / $n;
$range = range($rangeStart, $rangeEnd, $interval);

php round/ceil/floor how to make a number to Multiples of 7

Firstly poor of my mathematica. I tried to use php to make a number to Multiples of 7. the rules as below:
$num >=0;
$num = '0'; => output '7'
$num = '1'; => output '7'
$num = '6'; => output '7'
$num = '8'; => output '14'
$num = '14'; => output '14'
$num = '16'; => output '21'
$num = '20'; => output '21'
$num = '40'; => output '42'
$num = '84'; => output '84'
...
I cost many times, but I am not smart to solve this by myself. such as
echo round(($num*7-1)/7); // not a right answer.
any one is kindly help me? Thanks.
Your requirements are not consistent if the output for 0 is 7; 0 is already a multiple of 7, since 0 * 7 = 0.
echo ceil($num / 7) * 7;
Alternatively, use the modulus operator:
$m = $num % 7;
echo $m == 0 ? $num : $num - $m + 7;
Try ceil($num / 7) * 7. The code:
<?php
for ($i = 0; $i < 50; $i++) {
echo get_number($i) . "\n";
}
function get_number($num) {
return ceil($num / 7) * 7;
}
?>
Produces:
0 => 0
1 => 7
2 => 7
3 => 7
4 => 7
5 => 7
6 => 7
7 => 7
8 => 14
9 => 14
10 => 14
11 => 14
12 => 14
13 => 14
14 => 14
15 => 21
...
46 => 49
47 => 49
48 => 49
49 => 49
One possibility is to use modulo arithmetic, e.g.:
$x = $whatever;
while($x % 7 != 0){
$x++
}
echo $x; // will now be next multipe of seven >= $whatever

Evenly distributed integers within a range

Lets say I have a range between 0 and 100 and I want an array returned containing 3 integers which are evenly distributed within that range, what would be the best way to do this?
For example:
Range: 0-100
Wanted: 3
Returned: 25, 50, 75
Pseudo code:
function distributeIntegers(int wanted, int rangeLow, int rangeHigh)
int increment = (rangeHigh - rangeLow) / (wanted + 1)
array r = new array()
for (int i = rangeLow + increment; i < rangeHigh; i += increment)
r.push(i)
return r
PHP:
function distributeIntegers($wanted = 3, $rangeLow = 0, $rangeHigh = 100){
$increment = ($rangeHigh - $rangeLow) / ($wanted + 1);
$r = array();
for ($i = $rangeLow + $increment; $i < $rangeHigh; $i += $increment)
$r []= $i;
return $r;
}
/*
examples:
call:
distributeIntegers();
returns:
[0] => 25
[1] => 50
[2] => 75
call:
distributeIntegers(4);
returns:
[0] => 20
[1] => 40
[2] => 60
[3] => 80
call:
distributeIntegers(5, 50, 200);
returns:
[0] => 75
[1] => 100
[2] => 125
[3] => 150
[4] => 175
*/
you can make use of array_chunk(), eg only
$end=100;
$a = range(0,$end);
$chunk=3;
foreach (array_chunk($a,$end/($chunk+1)) as $s){
print $s[0]."\n";
}
output
$ php test.php
0
25
50
75
100
you can get rid of the start (0) and end(100) points if not needed.
Here's a solution in groovy that gives the answers you want, you should be able to switch it to whatever language you're using:
def distributedValues(min, max, wanted) {
def incrementBy = (max - min)/(wanted + 1)
(1..wanted).collect { count -> min + (count * incrementBy) }
}
assert distributedValues(0, 100, 1) == [50]
assert distributedValues(0, 100, 3) == [25, 50, 75]
assert distributedValues(0, 100, 4) == [20, 40, 60, 80]
assert distributedValues(0, 100, 5) == [16.6666666667, 33.3333333334, 50.0000000001, 66.6666666668, 83.3333333335]
assert distributedValues(100, 200, 3) == [125, 150, 175]
You can use the rand function to get the random value between the specific ranges.
Use this code . This following function would return set of element in a array
function array_elements( $start = 0 , $end = 100 , $element =5 )
{
$myarray = array () ;
for ( $i = 0 ; $i < $element;$i++ )
{
$myarray[$i]= rand ( $start, $end );
}
return $myarray ;
}
print_r ( array_elements() ) ;

Categories