How to get variables and it's values from a variable? - php

I want to know how to get variables and it's values from a variable?
Here is the sample code;
$x = 10;
$y = 20;
$z = 30;
$sum = $x * 5; // It has only one variable
echo $sum; // Page # 1
$sum = ($x * 5) + ($y * 5); // It has two variables
echo $sum; // Page # 2
$sum = ($x * 5) + ($y * 5) + ($z * 5); // It has three variables
echo $sum; // Page # 3
Now I want to get the variables inside of the variable $sum and their values to output a breakup of the calculation.
Something like this;
----- Page # 1 -----
X: 10 * 5 = 50
----- Page # 2 -----
X: 10 * 5 = 50
Y: 20 * 5 = 100
Sum: X + Y = 150
----- Page # 3 -----
X: 10 * 5 = 50
Y: 20 * 5 = 100
Z: 30 * 5 = 150
Sum: X + Y + Z = 300
Is there any PHP function or any other solution to achieve this without making any changes to the variable $sum?
I know I can do it in other ways, but the problem is; I can't change the code $sum as it's required to change it on thousands of pages. It would be highly appreciated if anyone could help me with this.
Thanks in advance :-)

There's no way to use $sum to retrieve the calculations or input values which were used to give it its current value. PHP does not work like that. As far as I am aware, no programming language currently provides that.
A variable simply contains its current value...it does not contain any other variables or calculations, or keep a history of how it got like that.
The only way to get the output you've specified is to directly echo the data explicitly from the original data, for example:
$x = 10;
$y = 20;
$z = 30;
// Page # 1
$sum = $x * 5;
echo "X: ".$x."* 5 = ".$sum;
// Page # 2
$sum = ($x * 5) + ($y * 5);
echo "X: ".$x."* 5 = ".($x * 5);
echo "Y: ".$y."* 5 = ".($y * 5);
echo "Sum: X + Y = ".$sum;
// Page # 3
$sum = ($x * 5) + ($y * 5) + ($z * 5);
echo "X: ".$x."* 5 = ".($x * 5);
echo "Y: ".$y."* 5 = ".($y * 5);
echo "Z: ".$z."* 5 = ".($z * 5);
echo "Sum: X + Y + Z = ".$sum;

Related

Not the outcome i need... round of floor? [duplicate]

I want a php function which returns 55 when calling it with 52.
I've tried the round() function:
echo round(94, -1); // 90
It returns 90 but I want 95.
Thanks.
This can be accomplished in a number of ways, depending on your preferred rounding convention:
1. Round to the next multiple of 5, exclude the current number
Behaviour: 50 outputs 55, 52 outputs 55
function roundUpToAny($n,$x=5) {
return round(($n+$x/2)/$x)*$x;
}
2. Round to the nearest multiple of 5, include the current number
Behaviour: 50 outputs 50, 52 outputs 55, 50.25 outputs 50
function roundUpToAny($n,$x=5) {
return (round($n)%$x === 0) ? round($n) : round(($n+$x/2)/$x)*$x;
}
3. Round up to an integer, then to the nearest multiple of 5
Behaviour: 50 outputs 50, 52 outputs 55, 50.25 outputs 55
function roundUpToAny($n,$x=5) {
return (ceil($n)%$x === 0) ? ceil($n) : round(($n+$x/2)/$x)*$x;
}
Divide by 5
round() (or ceil() if you want to round up always)
Multiply by 5.
The value 5 (the resolution / granularity) can be anything — replaced it in both step 1 and 3
So in summary:
$rounded_number = ceil( $initial_number / 5 ) * 5
Round down:
$x = floor($x/5) * 5;
Round up:
$x = ceil($x/5) * 5;
Round to closest (up or down):
$x = round($x/5) * 5;
echo $value - ($value % 5);
I know it's an old question, but IMHO using modulus operator is the best way, and far more elegant than the accepted answer.
Try this little function I wrote.
function ceilFive($number) {
$div = floor($number / 5);
$mod = $number % 5;
If ($mod > 0) $add = 5;
Else $add = 0;
return $div * 5 + $add;
}
echo ceilFive(52);
From Gears library
MathType::roundStep(50, 5); // 50
MathType::roundStep(52, 5); // 50
MathType::roundStep(53, 5); // 55
MathType::floorStep(50, 5); // 50
MathType::floorStep(52, 5); // 50
MathType::floorStep(53, 5); // 50
MathType::ceilStep(50, 5); // 50
MathType::ceilStep(52, 5); // 55
MathType::ceilStep(53, 5); // 55
Source:
public static function roundStep($value, int $step = 1)
{
return round($value / $step) * $step;
}
public static function floorStep($value, int $step = 1)
{
return floor($value / $step) * $step;
}
public static function ceilStep($value, int $step = 1)
{
return ceil($value / $step) * $step;
}
Multiply by 2, round to -1, divide by 2.
Here is my version of Musthafa's function. This one is more complex but it has support for Float numbers as well as Integers. The number to be rounded can also be in a string.
/**
* #desc This function will round up a number to the nearest rounding number specified.
* #param $n (Integer || Float) Required -> The original number. Ex. $n = 5.7;
* #param $x (Integer) Optional -> The nearest number to round up to. The default value is 5. Ex. $x = 3;
* #return (Integer) The original number rounded up to the nearest rounding number.
*/
function rounduptoany ($n, $x = 5) {
//If the original number is an integer and is a multiple of
//the "nearest rounding number", return it without change.
if ((intval($n) == $n) && (!is_float(intval($n) / $x))) {
return intval($n);
}
//If the original number is a float or if this integer is
//not a multiple of the "nearest rounding number", do the
//rounding up.
else {
return round(($n + $x / 2) / $x) * $x;
}
}
I tried the functions from Knight, Musthafa and even the suggestion from Praesagus. They don't have support for Float numbers and the solutions from Musthafa's & Praesagus do not work correctly in some numbers. Try the following test numbers and do the comparison yourself:
$x= 5;
$n= 200; // D = 200 K = 200 M = 200 P = 205
$n= 205; // D = 205 K = 205 M = 205 P = 210
$n= 200.50; // D = 205 K = 200 M = 200.5 P = 205.5
$n= '210.50'; // D = 215 K = 210 M = 210.5 P = 215.5
$n= 201; // D = 205 K = 205 M = 200 P = 205
$n= 202; // D = 205 K = 205 M = 200 P = 205
$n= 203; // D = 205 K = 205 M = 205 P = 205
** D = DrupalFever K = Knight M = Musthafa P = Praesagus
I do it like this:
private function roundUpToAny(int $n, $x = 9)
{
return (floor($n / 10) * 10) + $x;
}
Tests:
assert($this->roundUpToAny(0, 9) == 9);
assert($this->roundUpToAny(1, 9) == 9);
assert($this->roundUpToAny(2, 9) == 9);
assert($this->roundUpToAny(3, 9) == 9);
assert($this->roundUpToAny(4, 9) == 9);
assert($this->roundUpToAny(5, 9) == 9);
assert($this->roundUpToAny(6, 9) == 9);
assert($this->roundUpToAny(7, 9) == 9);
assert($this->roundUpToAny(8, 9) == 9);
assert($this->roundUpToAny(9, 9) == 9);
assert($this->roundUpToAny(10, 9) == 19);
assert($this->roundUpToAny(11, 9) == 19);
assert($this->roundUpToAny(12, 9) == 19);
assert($this->roundUpToAny(13, 9) == 19);
assert($this->roundUpToAny(14, 9) == 19);
assert($this->roundUpToAny(15, 9) == 19);
assert($this->roundUpToAny(16, 9) == 19);
assert($this->roundUpToAny(17, 9) == 19);
assert($this->roundUpToAny(18, 9) == 19);
assert($this->roundUpToAny(19, 9) == 19);
function round_up($n, $x = 5) {
$rem = $n % $x;
if ($rem < 3)
return $n - $rem;
else
return $n - $rem + $x;
}
I just wrote this function in 20 min, based on many results I found here and there, I don't know why it works or how it works!! :D
I was mainly interested in converting currency numbers from this 151431.1 LBP to 150000.0 LBP. (151431.1 LBP == ~100 USD) which works perfectly so far, however I tried to make it somehow compatible with other currencies and numbers, but not sure if it works fine!!
/**
* Example:
* Input = 151431.1 >> return = 150000.0
* Input = 17204.13 >> return = 17000.0
* Input = 2358.533 >> return = 2350.0
* Input = 129.2421 >> return = 125.0
* Input = 12.16434 >> return = 10.0
*
* #param $value
* #param int $modBase
*
* #return float
*/
private function currenciesBeautifier($value, int $modBase = 5)
{
// round the value to the nearest
$roundedValue = round($value);
// count the number of digits before the dot
$count = strlen((int)str_replace('.', '', $roundedValue));
// remove 3 to get how many zeros to add the mod base
$numberOfZeros = $count - 3;
// add the zeros to the mod base
$mod = str_pad($modBase, $numberOfZeros + 1, '0', STR_PAD_RIGHT);
// do the magic
return $roundedValue - ($roundedValue % $mod);
}
Feel free to modify it and fix it if there's anything wrong
Probably you can also consider this one liner. It's faster! Works for $num >= 0 and $factor > 0.
$num = 52;
$factor = 55;
$roundedNum = $num + $factor - 1 - ($num + $factor - 1) % $factor;

Round to 5 and 9 php

I'm looking for a formula to round a value to nearest 5 or 9 if the val is less than 5 make 5 if is bigger than 5 make 9.
Example:
$RoundToFive = ceil('232' / 5) * 5;
echo floor($RoundToFive * 2 ) / 2; //Result is 235 Is good
$RoundToNine = ceil('236' / 5) * 5;
echo floor($RoundToNine * 2 ) / 2; //Result is 240 but i need 239
Is there a way to extract always the last 2 digits and convert to 5 or nine ?
Any help is appreciated !
how about:
function funnyRound($number){
$rounded = ceil($number / 5) * 5;
return $rounded%10?$rounded:$rounded-1;
}
This is working
<?php
function roundToDigits($num, $suffix, $type = 'floor') {
$pow = pow(10, floor(log($suffix, 10) + 1));
return $type(($num - $suffix) / $pow) * $pow + $suffix;
};
$RoundToNine = ceil('236' / 5) * 5;
echo roundToDigits($RoundToNine,5);
echo roundToDigits($RoundToNine,9);
You can use any number as $suffix to round to it.
other way, working with strings... :
<?php
function round59($NUMB){
//cast the value to be Int
$NUMB = intval($NUMB);
//Get last number
$last_number = intval(substr($NUMB, -1));
$ROUND_NUMBER = 5;
if($last_number<=5)
$ROUND_NUMBER = 5;
else
$ROUND_NUMBER = 9;
//Remove Last Character
$NUMB = substr($NUMB, 0, -1);
// now concat the results
return intval($NUMB."".$ROUND_NUMBER) ;
}
echo round59(232);
echo round59(236);
?>

Block scanning on sudoku solver explanation

I tried this sudoku solver http://www.emanueleferonato.com/2008/12/09/sudoku-creatorsolver-with-php/. It works fine.
Also see this spreadsheet to see more detail in calculation : spreadsheet
I understand how the row and col scanning. From the board, we know that:
index = 9*row + col
row = floor(index/9)
col = index % 9
And for the block, because it build from 3x3 board so the formula: block_index = 3*row_block + col_row. Because per block there are 3 rows and cols, so the formula for row_block = floor(row/3) and col_block = floor(col/3). From here we can conclude that:
block_index = 3*row_block + col_row
block_index = 3(floor(row/3)) + floor(col/3)
block_index = floor(row/3)*3 + floor(col/3)
This could explain for these function :
return_row
retun_col
return_block
is_possible_row
is_possible_col
But I cannot understand about is_possible_block function. Here is the function:
function is_possible_block($number,$block,$sudoku){
$possible = true;
for($x = 0;$x <= 8;$x++){
if($sudoku[floor($block / 3) * 27 + $x % 3 + 9 * floor($x / 3) + 3 * ($block % 3)] == $number){
$possible = false;
}
}
return $possible;
}
What I know about is_possible_block function is:
floor($block / 3) * 27 + $x % 3 + 9 * floor($x / 3) + 3 * ($block % 3)
= 9row+col
= 9(floor($block/3)*3 + floor($x/3)) + ($x%3 + 3*($block%3))
row = 3row_block+row_x_block
floor($block/3) = row_block
floor($x/3) = row_x_block
col = 3col_block+col_x_block
How col = 3col_block+col_x_block , because what I know, the formula should be like this : col = 3row_block+col.
I know col_x_block mean column position on 0-8 block. And row_block mean row position on 0-2 block.
How do you explain this formula? Thanks
UPDATE
Now I know. floor($block/3)*3 and 3*($block%3) determine top left corner in block. Then floor($x / 3) and $x % 3 moves each cell in the block.
I use it in c++
for(int k = ((x - 1) / 3) * 3 + 1; k < ((x - 1) / 3) * 3 + 4; k++
because of "x" is integer "/" operation return int value.
maybe 3(floor($block-1/3)) can help you.

round to nearest multiple of 5 in a range in php

I have this if statement:
if($_GET["angle_1"] > 39) {
$markers["###ANGLE###"] = "45";
} elseif($_GET["angle_1"] > 29 && $_GET["angle_1"] < 40) {
$markers["###ANGLE###"] = "35";
} elseif($_GET["angle_1"] < 30) {
$markers["###ANGLE###"] = "25";
} else {
$markers["###ANGLE###"] = "45";
}
Is there a better / simpler way to do this check, f.x. with round that will round the integer to the nearest 5, i.e. 28 -> 25 or 34 -> 35 etc. and in that, if the integer is less than 25, it will always be 25 and if the integer is higher than 45, it will always be 45 and again if the integer is between 30 and 40 it will always be 35.
That returned value will be used to display an image.
EDIT:
I have 3 images: image_25, image_35 and image_45, therefore the need to round.
Let say $x has the number:
$x = 39;
If you want the closest multiple of 5 (39 --> 40):
$x = round($x / 5) * 5;
If you want to round up (36 --> 40):
$x = ceil($x / 5) * 5;
If you want to round down (39 --> 35):
$x = floor($x / 5) * 5;
After defining $x, you can use the following to make sure its in the 25-45 range:
$x = ($x > 45) ? 45 : ($x < 25) ? 25 : $x;
Give this a try:
$var = 5 * round($n / 5);
Taken from here

Algorithm to portion

I have a number X, consider X = 1000
And I want piecemeal this number at three times, then Y = 3, then X = (X / 3)
This will give me equal, just not always accurate, so I need: a percentage value is set, also consider K = 8, K is the percentage, but what I want to do? I want the first portion has a value over 8% in K, suppose that 8% are: 500 and the other two plots are 250, 250
The algorithm is basically what I need it, add a percentage value for the first installment and the other equals
EDIT
I just realized, this is far simpler than I made it. To find the value of $div in my original answer you can just:
$div = (int)($num / ($parcels + $percent / 100));
Then the $final_parcels will be the same as below. Basically, the line above replaces the while loop entirely. Don't know what I was thinking.
/EDIT
I think this will do what you want... unless I am missing something.
<?php
$num = 1000;
$percent = 8;
$parcels = 3;
$total = PHP_INT_MAX;
$div = (int)($num / $parcels);
while ($total > $num) {
$div -= 1;
$total = (int)($div * ($parcels + $percent / 100));
}
$final_parcels = array();
$final_parcels[] = ($num - (($parcels - 1) * $div));
for ($i = 1; $i < $parcels; $i++) {
$final_parcels[] = $div;
}
print_r($final_parcels);
This output will be
Array
(
[0] => 352
[1] => 324
[2] => 324
)
324 * 1.08 = 350.
352 + 324 * 2 = 1000.
Let $T is your total X, $n is a number of parts and $K is percentage mentioned above. Than
$x1 = $T / $n + $T * $K / 100;
$x2 = $x3 = .. = $xn = ($T - $x1) / ($n - 1);
Applied to your example:
$x1 = 1000 / 3 + 1000 * 0.03 = 363.3333333333333333333333333333
// you could round it if you want
// lets round it to ten, as you mentioned
$x1 = round($x1, -1) = 360
$x2 = $x3 = (1000 - 360) / 2 = 320
Extra for the first piece W = X*K/100
Remaining Z = X-W
Each non-first piece = Z/Y = (X-W)/Y = (100-K)*X/(100*Y)
The first piece = W + (100-K)*X/(100*Y) = X*K/100 + (100-K)*X/(100*Y)

Categories