doing maths with php array based on excel function - php

I am new to PHP and stackoverflow and try to figure things out for myself before asking but I am having a little trouble doing some maths on an array I have pulled from a database with PHP.
So far I have an array of numbers called $array['sn']
I have created a function in excel that does the maths and works well in excel but I cant figure out a way to do it in PHP.
the excel function is =QUOTIENT(E32,65536)&QUOTIENT(E32-F34*65536,256)&(G33-G35*256)
E32 being the value I start with i.e $sn
F34 being the answer to the first quotient
G35 being the answer to the second quotient
G33 being E32-F34*65536
I want to take a number e.g. 3675177 divide it by 65536 but without the remainder which is 56, then multiply 56 by 65536 which equals 3670016, then find the difference between 3670016 and 3675177 which is 5161. Then divide 5161 by 256 with no remainder which is 20 then multiply 20 by 256 and subtract 5161 which is 41.
The end result from 3675177 should be 562041. I want to do this calculation on every number in the $array['sn'], any help would be appreciated.

The calculation and formatting of the output would be like this:
$n = 3675177;
$const = 65536;
$const2 = 256;
$a = intval($n / $const); // intval returns only the integer part of a number
$x = $n % $const; // $n % $const means "the remainder of $n / $const"
$b = intval($x / $const2);
$c = $x % $const2;
// Two options to handle values of $c < 10:
// if ($c < 10) $c = "0$c";
// $c = str_pad($c, 2, "0", STR_PAD_LEFT);
echo "$a$b$c";
I would recommend using array_map to apply the calculation to your array of values.

There are php arithmetic operations you can use.
I would do something like this:
$initialNumber = //the initial number, wherever you get it from
$entireDivision = ceil($initialNumber/65536)-1;
$remainder = $initialNumber%65536;
$remainderMultiplied = $remainder * 56;
$difference = $initialNumber - $remainderMultiplied;
$differenceDivided = ceil($difference/256)-1;
$differenceMultipliedAndSubstracted = ($differenceDivided * 256) - $difference;
Maybe I used too many variables, this is to be a bit more easy to understand for you. Maybe I did some operation wrong, check it out too. But this is the idea of mathematic operations in php. Maybe you should put this inside a php function with parameters, so your code gets cleaner if you use multiple times.
EDIT: You should put this code inside a function, then run a foreach loop in your array running this function taking as parameter the value of the array position.

$results = array();
foreach ($array['sn'] as $key => $a) {
$b = intval($a / 65536);
$c = ($a - $b * 65536);
$d = intval($c / 256);
$e = $c - $d * 256;
$results[$key] = $b . $d . $e;
}
var_dump($results);

Related

PHP distribute percentage based on total numbers

I'm trying to distribute 100% to total numbers (not equally), it can be done manually but I'm looking for a automatically way in PHP. I had to open calculator and get it done for manual.
What I'm trying to achieve is the result similar to this:
$value = 10000;
$total_numbers = 9
$a1 = $value*0.2;
$a2 = $value*0.175;
$a3 = $value*0.15;
$a4 = $value*0.125;
$a5 = $value*0.1;
$a6 = $value*0.08;
$a7 = $value*0.07;
$a8 = $value*0.05;
$a9 = $value*0.04;
So as you can see, the first variables have more quantity than the later ones, but if you add these, it will be 1 which is 100%. So lets say I have total_numbers=20 then I'll have to re-write it and get a calculator and do it the hard way to accomplish my goal. Is there any way this can be done automatically with a function where I can just tell the total number and it can distribute it to proportions or something?
The first one will always be bigger than rest, then second one bigger than rest but smaller than first, third one being greater than rest but small than first and second, and so on.
function distributeValue($value, $num) {
$parts = $num * ($num + 1) / 2;
$values = [];
for ($i = $num; $i > 1; --$i) {
$values[] = round($value * $i / $parts);
}
$values[] = $value - array_sum($values);
return $values;
}
var_dump(distributeValue(10000, 9));
This works by calculating the $numth triangle number (the number you get by adding all the numbers from 1 to $num) and dividing the total value up into this number of parts.
It then starts by taking $num parts, then $num-1 parts and so on.
Since it's rounding the numbers, the last step is to take the total minus all the other values which is around one part. If you are fine with getting floats instead of ints out, then you can remove the $values[] = $value - array_sum($values); line and change the condition of the for loop to $i > 0.

How to find reminder and Quotient in php?

I can find reminder by "%" operator . But how can I find the quotient at the same time . Suppose I will divide 10 by 3 . If there is any function which will give me the output 3 as quotient and 1 as reminder .
$remainder = $a % $b;
$quotient = ($a - $remainder) / $b;
Use type casting:
$quotient = (int)(10/3)
This will divide 10 by 3 and then cast that result to an integer.
Since functions can only return a single value (not counting pass-by-reference functionality), there's no way to return 2 separate values from a single function call (getting both the quotient and remainder at the same time). If you need to calculate two different values, then you will need at least two statements.
You can, however, return an array of values and use PHP's list function to retrieve the results in what looks like a single statement:
function getQuotientAndRemainder($divisor, $dividend) {
$quotient = (int)($divisor / $dividend);
$remainder = $divisor % $dividend;
return array( $quotient, $remainder );
}
list($quotient, $remainder) = getQuotientAndRemainder(10, 3);
How about gmp_div_qr function
<?php
$res = gmp_div_qr(11,5);
die(var_dump($res));
the accepted answer will not work with float values.
another way with inbuilt php>(v.4.2.0) method
fmod
$remainder = fmod ( float $x , float $y );
$quotient = ($x - $remainder) / $y;
Try this
$x=10;
$y=3;
$Quotient =(int)($x/$y);
$Remainder = $x % $y;

Find what 2 numbers add to something and multiply to something

Hey so I'm making a factoring program and I'm wondering if anyone can give me any ideas on an efficient way to find what two numbers multiple to a specified number, and also add to a specified number.
for example I may have
(a)(b) = 6
a + b = 5
So essentially i just need a way to find the a and b values. In this case they would be 2 and 3.
Can anyone give me any ideas on where to start? Negative numbers must also be considered for use.
There is no need to loop, just use simple math to solve this equation system:
a*b = i;
a+b = j;
a = j/b;
a = i-b;
j/b = i-b; so:
b + j/b + i = 0
b^2 + i*b + j = 0
From here, its a quadratic equation, and it's trivial to find b (just implement the quadratic equation formula) and from there get the value for a.
There you go:
function finder($add,$product)
{
$inside_root = $add*$add - 4*$product;
if($inside_root >=0)
{
$b = ($add + sqrt($inside_root))/2;
$a = $add - $b;
echo "$a+$b = $add and $a*$b=$product\n";
}else
{
echo "No real solution\n";
}
}
Real live action:
http://codepad.org/JBxMgHBd
Here is how I would do that:
$sum = 5;
$product = 6;
$found = FALSE;
for ($a = 1; $a < $sum; $a++) {
$b = $sum - $a;
if ($a * $b == $product) {
$found = TRUE;
break;
}
}
if ($found) {
echo "The answer is a = $a, b = $b.";
} else {
echo "There is no answer where a and b are both integers.";
}
Basically, start at $a = 1 and $b = $sum - $a, step through it one at a time since we know then that $a + $b == $sum is always true, and multiply $a and $b to see if they equal $product. If they do, that's the answer.
See it working
Whether that is the most efficient method is very much debatable.
With the multiplication, I recommend using the modulo operator (%) to determine which numbers divide evenly into the target number like:
$factors = array();
for($i = 0; $i < $target; $i++){
if($target % $i == 0){
$temp = array()
$a = $i;
$b = $target / $i;
$temp["a"] = $a;
$temp["b"] = $b;
$temp["index"] = $i;
array_push($factors, $temp);
}
}
This would leave you with an array of factors of the target number.
That's basically a set of 2 simultaneous equations:
x*y = a
X+y = b
(using the mathematical convention of x and y for the variables to solve and a and b for arbitrary constants).
But the solution involves a quadratic equation (because of the x*y), so depending on the actual values of a and b, there may not be a solution, or there may be multiple solutions.

Add a decimal after two first numbers

I am generating some data of latitude and longitude with rand(10000000, 3000000); for example. But I need to calculate distance between two locations, so basically I need to convert my result, for example 22049256 to 22.049256 in order to pass to my function.
How can I achieve this most effectively with using least amount of resources?
TL;DR
I have integer 22049256, needs to be converted to float 22.049256.
Divide by 1M?
22049256 / 1000000 = 22.049256
$foo = rand(10000000, 30000000);
$foo /= 1000000;
echo $foo;
If you always want the decimal after the first two digits, that should do the trick.
<?php
$n = rand(10000000, 3000000);
$len = strlen($n);
$div = pow(10, $len - 2);
$n /= $div;
var_dump($n);
?>
http://codepad.viper-7.com/Nrql15
Basically just dividing by a number made by checking how many characters there are in your original number.
Simplest way would be to treat the number as a string and iterate through it, adding the decimal point at the appropriate position.
$new_number = '';
for($i=0;$i<strlen((string)$number;$i++)
{
if($i == 2)
$new_number .= '.';
$new_number .= substr((string)$number, $i, 1);
}
Edit:
Another possibility is to divide by 1000000 and run number_format to ensure proper decimal places:
$new_number = number_format($number/1000000, 6);

How can I calculate a trend line in PHP?

So I've read the two related questions for calculating a trend line for a graph, but I'm still lost.
I have an array of xy coordinates, and I want to come up with another array of xy coordinates (can be fewer coordinates) that represent a logarithmic trend line using PHP.
I'm passing these arrays to javascript to plot graphs on the client side.
Logarithmic Least Squares
Since we can convert a logarithmic function into a line by taking the log of the x values, we can perform a linear least squares curve fitting. In fact, the work has been done for us and a solution is presented at Math World.
In brief, we're given $X and $Y values that are from a distribution like y = a + b * log(x). The least squares method will give some values aFit and bFit that minimize the distance from the parametric curve to the data points given.
Here is an example implementation in PHP:
First I'll generate some random data with known underlying distribution given by $a and $b
// True parameter valaues
$a = 10;
$b = 5;
// Range of x values to generate
$x_min = 1;
$x_max = 10;
$nPoints = 50;
// Generate some random points on y = a * log(x) + b
$X = array();
$Y = array();
for($p = 0; $p < $nPoints; $p++){
$x = $p / $nPoints * ($x_max - $x_min) + $x_min;
$y = $a + $b * log($x);
$X[] = $x + rand(0, 200) / ($nPoints * $x_max);
$Y[] = $y + rand(0, 200) / ($nPoints * $x_max);
}
Now, here's how to use the equations given to estimate $a and $b.
// Now convert to log-scale for X
$logX = array_map('log', $X);
// Now estimate $a and $b using equations from Math World
$n = count($X);
$square = create_function('$x', 'return pow($x,2);');
$x_squared = array_sum(array_map($square, $logX));
$xy = array_sum(array_map(create_function('$x,$y', 'return $x*$y;'), $logX, $Y));
$bFit = ($n * $xy - array_sum($Y) * array_sum($logX)) /
($n * $x_squared - pow(array_sum($logX), 2));
$aFit = (array_sum($Y) - $bFit * array_sum($logX)) / $n;
You may then generate points for your Javascript as densely as you like:
$Yfit = array();
foreach($X as $x) {
$Yfit[] = $aFit + $bFit * log($x);
}
In this case, the code estimates bFit = 5.17 and aFit = 9.7, which is quite close for only 50 data points.
For the example data given in the comment below, a logarithmic function does not fit well.
The least squares solution is y = -514.734835478 + 2180.51562281 * log(x) which is essentially a line in this domain.
I would recommend using library: http://www.drque.net/Projects/PolynomialRegression/
Available by Composer: https://packagist.org/packages/dr-que/polynomial-regression.
In case anyone is having problems with the create_function, here is how I edited it. (Though I wasn't using logs, so I did take those out.)
I also reduced the number of calculations and added an R2. It seems to work so far.
function lsq(){
$X = array(1,2,3,4,5);
$Y = array(.3,.2,.7,.9,.8);
// Now estimate $a and $b using equations from Math World
$n = count($X);
$mult_elem = function($x,$y){ //anon function mult array elements
$output=$x*$y; //will be called on each element
return $output;
};
$sumX2 = array_sum(array_map($mult_elem, $X, $X));
$sumXY = array_sum(array_map($mult_elem, $X, $Y));
$sumY = array_sum($Y);
$sumX = array_sum($X);
$bFit = ($n * $sumXY - $sumY * $sumX) /
($n * $sumX2 - pow($sumX, 2));
$aFit = ($sumY - $bFit * $sumX) / $n;
echo ' intercept ',$aFit,' ';
echo ' slope ',$bFit,' ' ;
//r2
$sumY2 = array_sum(array_map($mult_elem, $Y, $Y));
$top=($n*$sumXY-$sumY*$sumX);
$bottom=($n*$sumX2-$sumX*$sumX)*($n*$sumY2-$sumY*$sumY);
$r2=pow($top/sqrt($bottom),2);
echo ' r2 ',$r2;
}

Categories