PHP: Get thousand from number - php

When the user enters a number from 1000 and above I want to be able to get the thousand for that number in an array.
For example…
Number entered by user: 165124
My array should return:
array('thousand_low' => 165000, 'thousand_high' = 165999)
Thanks!

The complete array-returning function, using PHP's native floor and ceil functions:
function get_thousands($num) {
return array(
'thousand_low'=>floor($num/1000)*1000,
'thousand_high'=>ceil($num/1000)*1000-1
);
}

Untested (edit: but should work ;) ):
$number = 165124;
$low = floor($number / 1000) * 1000;
$high = $low + 999;

Something like this:
$num = 165124;
$result = array();
$result['thousand_low'] = floor($num / 1000) * 1000;
$result['thousand_high'] = $result['thousand_low'] + 999;

Have a look at the round function (http://php.net/manual/en/function.round.php) - you can specify the precision so you can customise the magnitude of the rounding.

array('thousand_low' => floor($int/1000)*1000,
'thousand_high' => floor($int/1000)*1000+999);

Haven't used php in quite a while but i think it should look something like this :
$num_input = 165124;
$array['thousand_low'] = floor($num_input / 1000) * 1000;
$array['thousand_high'] = $array['thousand_low'] + 999;

Related

How to proportionally decrease positive and negative numbers

I have two variables:
$points - could be positive or negative
$time_elapsed -is always positive
I'm trying to proportionally decrease $points based on $time_elapsed. I can't use subtraction because it's not "proportional" the way I need it. I need something similar to division, but that always decreases $points (division increases the number if it's negative) so that I get the following result:
$points = -12;
$time_elapsed = 4;
$points/time_elapsed = -48;
$points = 12;
$time_elapsed = 4;
$points/time_elapsed = 3;
I cannot use abs() because it would return -3 when points is -12, when really I need it to return -48 (I always need something that is $time_elapsed times smaller than $points).
I cannot use if conditions or anything similar. Is this even possible?
This will work. No conditionals!
Fiddle here
function getPoints($points, $time_elapsed)
{
$is_positive = $points > 0;
$converters = [
true => function($points, $time_elapsed) {
return $points / $time_elapsed;
},
false => function($points, $time_elapsed) {
return $points * $time_elapsed;
}
];
return $converters[$is_positive]($points, $time_elapsed);
}
echo getPoints(-12, 4), PHP_EOL;
echo getPoints(12, 4), PHP_EOL;
You can extract sign bit and use it to avoid conditional operators (while this restriction is weird idea):
$sgn = ($points >> 31) & 1 //(for 32-bit variables)
return $points * $sgn * $time + $points * (1 - $sgn) / $time
//returns $points * $time for negative and $points / $time for positive

How can I keep a number in specific range?

I have a function like this:
<?php
function keepInRange($n){
$min = 5;
$max = 15;
if ( $n < $min ) {
$res = $min;
} elseif ( $n > $max ) {
$res = $max;
} else {
$res = $n;
}
return $res;
}
It always returns a number between $min and $max. It works as well, but doesn't seem clean an professional to me. I think it can be better (without those conditions). Any idea how can I make it shorter and cleaner?
If you are trying to make it shorter (and probably cleaner) and also removing those if statements, you can use max() and min() functions:
function keepInRange($n){
$min = 5;
$max = 15;
return max(min($max, $n), $min);
}
Also as #admcfajn mentioned, you can pass $min and $max as arguments to make the function more flexible:
function keepInRange($n, $min = 5, $max = 15){
return max(min($max, $n), $min);
}
Definitely its not the best way, You can use Rand() to generate numbers between a particular range.
Try this
print rand(10, 30) . "";​
It'll generate and print a random number between 10 and 30 (10 and 30 are included).
I think it can be better (without those conditions). Any idea how can I make it shorter and cleaner?
Well if you want it without explicit conditions, then you could simply use min() and max():
function keepInRange2($n) {
$min = 5;
$max = 15;
return max($min, min($max, $n));
}
The order of the functions and parameters might seem odd at first glance - but since you want 15 to be the maximum value, we need to get the minimum of 15 and whatever the value is first - and then vice versa for the minimum 5.
This can be achieved cleaner using ternary operator.
function keepInRange($n){
$min = 5;
$max = 15;
return ( $n < $min ) ? $min : (( $n > $max ) ? $max : $n);
}

How to generate random numbers to produce a non-standard distributionin PHP

I've searched through a number of similar questions, but unfortunately I haven't been able to find an answer to this problem. I hope someone can point me in the right direction.
I need to come up with a PHP function which will produce a random number within a set range and mean. The range, in my case, will always be 1 to 100. The mean could be anything within the range.
For example...
r = f(x)
where...
r = the resulting random number
x = the mean
...running this function in a loop should produce random values where the average of the resulting values should be very close to x. (The more times we loop the closer we get to x)
Running the function in a loop, assuming x = 10, should produce a curve similar to this:
+
+ +
+ +
+ +
+ +
Where the curve starts at 1, peeks at 10, and ends at 100.
Unfortunately, I'm not well versed in statistics. Perhaps someone can help me word this problem correctly to find a solution?
interesting question. I'll sum it up:
We need a funcion f(x)
f returns an integer
if we run f a million times the average of the integer is x(or very close at least)
I am sure there are several approaches, but this uses the binomial distribution: http://en.wikipedia.org/wiki/Binomial_distribution
Here is the code:
function f($x){
$min = 0;
$max = 100;
$curve = 1.1;
$mean = $x;
$precision = 5; //higher is more precise but slower
$dist = array();
$lastval = $precision;
$belowsize = $mean-$min;
$abovesize = $max-$mean;
$belowfactor = pow(pow($curve,50),1/$belowsize);
$left = 0;
for($i = $min; $i< $mean; $i++){
$dist[$i] = round($lastval*$belowfactor);
$lastval = $lastval*$belowfactor;
$left += $dist[$i];
}
$dist[$mean] = round($lastval*$belowfactor);
$abovefactor = pow($left,1/$abovesize);
for($i = $mean+1; $i <= $max; $i++){
$dist[$i] = round($left-$left/$abovefactor);
$left = $left/$abovefactor;
}
$map = array();
foreach ($dist as $int => $quantity) {
for ($x = 0; $x < $quantity; $x++) {
$map[] = $int;
}
}
shuffle($map);
return current($map);
}
You can test it out like this(worked for me):
$results = array();
for($i = 0;$i<100;$i++){
$results[] = f(20);
}
$average = array_sum($results) / count($results);
echo $average;
It gives a distribution curve that looks like this:
I'm not sure if I got what you mean, even if I didn't this is still a pretty neat snippet:
<?php
function array_avg($array) { // Returns the average (mean) of the numbers in an array
return array_sum($array)/count($array);
}
function randomFromMean($x, $min = 1, $max = 100, $leniency = 3) {
/*
$x The number that you want to get close to
$min The minimum number in the range
$max Self-explanatory
$leniency How far off of $x can the result be
*/
$res = [mt_rand($min,$max)];
while (true) {
$res_avg = array_avg($res);
if ($res_avg >= ($x - $leniency) && $res_avg <= ($x + $leniency)) {
return $res;
break;
}
else if ($res_avg > $x && $res_avg < $max) {
array_push($res,mt_rand($min, $x));
}
else if ($res_avg > $min && $res_avg < $x) {
array_push($res, mt_rand($x,$max));
}
}
}
$res = randomFromMean(22); // This function returns an array of random numbers that have a mean close to the first param.
?>
If you then var_dump($res), You get something like this:
array (size=4)
0 => int 18
1 => int 54
2 => int 22
3 => int 4
EDIT: Using a low value for $leniency (like 1 or 2) will result in huge arrays, since testing, I recommend a leniency of around 3.

Auto increase value php in file based on number entered

I have 5 different variables that I need to calculate. Right now these work, but what I want to do is have the price recalculate every 50 increase. Now, I can code into the form to only allow a maximum purchase of 50 at a time, but I want to allow for as many of each as the person has money for (that is what the numbers are). So I think what I need is a parabola style formula that auto increases every 50, but I don't know exactly what I'm looking for or how to implement it.
$resprice = 20000+($cityFetch['residential']*502)+($cityNum*1000);
$comprice = 18000+($cityFetch['commercial']*506)+($cityNum*1000);
$indprice = 23000+($cityFetch['industrial']*508)+($cityNum*1000);
$landprice = 600+($cityFetch['land']*.008);
$milprice = 25000+($cityFetch['military']*512)+($cityNum*1000);
EDIT: I was indicated that a loop will work for this.
EDIT3: Finally landed on this, Havvy helped me out on IRC
$cityCheck = mysql_query("SELECT * FROM cities WHERE nation='$nation'");
$cityNum = mysql_num_rows($cityCheck);
function determinePrice($baseCost, $scalar, $current, $bought) {
$min = $baseCost + $scalar * ($current + 1) + ($cityNum * 1000);
$max = $baseCost + $scalar * ($current + $bought) + ($cityNum * 1000);
$average = ($min + $max) / 2;
return $average * $bought;
}
$resprice = determinePrice(20000, 502, $cityFetch['residential'], $cityFetch['residential']);
$comprice = determinePrice(18000, 506, $cityFetch['commercial'], $cityFetch['commercial']);
$indprice = determinePrice(23000, 508, $cityFetch['industrial'], $cityFetch['industrial']);
$milprice = determinePrice(25000, 502, $cityFetch['residential'], $cityFetch['military']);
$landprice = 600+($cityFetch['land']*.008);
I use a step size of 1, instead of 50. It's more logical (one less magic number) to not give discounts based on how much you buy at a time, and it would be confusing to new players having a stepwise-linear function.
The reasoning behind this function can be found at http://betterexplained.com/articles/techniques-for-adding-the-numbers-1-to-100/.
function determinePrice($baseCost, $scalar, $current, $bought) {
$min = $scalar * ($current + 1) + ($cityNum * 1000);
$max = $scalar * ($current + $bought) + ($cityNum * 1000);
$average = ($min + $max) / 2;
return $average * $bought;
}
Using it would look something like this:
$resprice = determinePrice(20000, 502, $cityFetch['residential'], $resBought);
It won't work for land though, because land doesn't include the city price in it. For land, you can copy the function and remove the $cityNum * 1000 portions. You could also add in a $isLand parameter to the signature, and use a ternary operator to add 0 instead.
If you don't like that $cityNum has to already be declared with the proper value before declaring this function, you can always add it to the function signature, making it a pure function.
$count=1
if($count==50)
{
You increase the prices then
$count=1;
}
$resprice = 20000+($cityFetch['residential']*502)+($cityNum*1000);
$comprice = 18000+($cityFetch['commercial']*506)+($cityNum*1000);
$indprice = 23000+($cityFetch['industrial']*508)+($cityNum*1000);
$landprice = 600+($cityFetch['land']*.008);
$milprice = 25000+($cityFetch['military']*512)+($cityNum*1000);
$count++;

Approximate count in PHP

I have a website that contains a list of articles. I want to include a line that says how many articles there are in the DB, however I don't want it to show the exact count.
I would like it to round down to the nearest 10, so for example for 105 articles I would like it to say "100+", etc.
How would I go about doing this?
Quite simple:
floor($num / 10) * 10
docs
To do something similar you have to use the logarithm with base = 10 and round it
$exp= floor(log($num)/log(10));
$num = pow(10,$exp)."+";
This works with 10, 100, 1000 ecc, i think it better do what you asked.
$count = 105;
$nearest10 = floor($count / 10) * 10;
printf("%d0+", $count * 0.1);
or
echo substr($count, 0, -1), '0+';
And the roundDocs function does support it out of the box, too:
round($count, -1, PHP_ROUND_HALF_DOWN);
but the plus-sign is missing.
First of all, you will need to use the COUNT() Aggregate function of MySQL to fetch the total number of results, or something like that.
Then you will need to use the modulo operator (%) with 10 as the base, and then deduct that value from the main result, which will be something like this:-
$sql = "SELECT COUNT(id) AS `total_num_records` FROM `table`";
$resource = mysql_query($sql);
$result = mysql_fetch_array($resource);
$totalRecords = $result['total_num_records'];
if ($totalRecords > 0) {
$remainder = $totalRecords % 10;
$showHumanFriendlyRecords = ($totalRecords - $remainder);
$strHumanFriendlyRecords = $showHumanFriendlyRecords . "+";
}
Hope it helps.

Categories