PHP sqrt() returns NAN - php

I've written a piece of code to carry out the quadratic equation:
function quadratic($a,$b,$c) {
$mb = $b - ($b*2);
$bs = $b * $b;
$fac = ($a * $c) * 4;
$ans1 = ($mb + sqrt(($bs - $fac))) / (2 * $a);
$ans2 = ($mb - sqrt(($bs - $fac))) / (2 * $a);
echo ("Your <b>+</b> value is: " . $ans1 . "<br />");
echo ("Your <b>-</b> value is: " . $ans2);
}
The problem is that, if for example a=2, b=4, c=8, both answers are outputted as NAN. Any ideas as to how to fix this so that I get an actual number output?

$a * $c * 4 = 64
$bs = 4 * 4 = 16
sqrt(($bs - $fac))) = sqrt(-48)
You cant take the sqrt of a negative number, it is not defined, hence the result is NaN.
Futhermore your formula can be simplified as:
$mb = $b - ($b*2) = -$b
So instad of $mb you can simply use -$b.
Besides that, your formula is correct for the quadratic equation.

If interested in having a "real number" solution, see:
function quadratic($a,$b,$c) {
$mb = $b - ($b*2);
$bs = $b * $b;
$fac = ($a * $c) * 4;
$bsfac = $bs-$fac;
if($bsfac < 0){
$bsfac *= -1;
}
$ans1 = ($mb + sqrt(($bsfac))) / (2 * $a);
$ans2 = ($mb - sqrt(($bsfac))) / (2 * $a);
echo ("Your <b>+</b> value is: " . $ans1 . "<br />");
echo ("Your <b>-</b> value is: " . $ans2);
}
*Rounding not included

Try swapping in these lines.
$ans1 = ($mb + sqrt(abs($bs - $fac))) / (2 * $a);
$ans2 = ($mb - sqrt(abs($bs - $fac))) / (2 * $a);

Related

PHP round number to 6 decimal places

I need to return a result of (1 / n!) * (1! + 2! + 3! + ... + n!), n>=1.
This is a CodeWars challenge! The code below returns 1.146652 for n = 8, but the correct result is 1.1466510000000001 or 1.146651.
How can I truncate this number correctly?
function factorial($val){
$factor = 1;
for($i=1;$i<=$val;$i++){
$factor *= $i;
}
return $factor;
}
function going($n) {
$val = 1/factorial($n);
$somatorio = 0;
for($i=1;$i<=$n;$i++){
$somatorio += factorial($i);
}
return round($val * $somatorio,6);
}

Undefined offset on multiple lines

I have written a small program to solve a mathematical problem. But when I run, it gives an undefined offset error on line number 9,11,13,15.
I have searched various questions, but didn't find anything useful.
What might be causing this. ?
<?php
$arr = [1,3,5,7,9,11,13,15];
$tries=0;
$answer=0;
while(($answer!=30) && ($tries!=1000))
{
$tries = $tries+1;
$num1=getRandomNumber();
$num2=getRandomNumber();
$num3=getRandomNumber();
$num4=getRandomNumber();
$num5=getRandomNumber();
if($num5 + $num4 + $num3 + $num2 + $num1 == 30)
{
$answer = 30;
echo $num1 + "+" + $num2 + "+" + $num3 + "+" + $num4 + "+" + $num5 + " = 30";
break;
}
}
if($tries==1000)
{
echo "1000 tries completed";
}
function getRandomNumber()
{
$arr = [1,3,5,7,9,11,13,15];
$r = mt_rand(1,15);
if(($r%2)!=0)
{
return $arr[$r];
}
}
?>
In your getRandomNumber() function, you're generating an array index between 1 and 15, but your array is only 8 elements long.
To fix this, update the call to mt_rand() to support your actual array size:
$r = mt_rand(0, count($arr) - 1);
Side-note (not answer specific), string concatenation in PHP is done with the period, . and not the +:
echo $num1 + "+" + $num2 + "+" + $num3 + "+" + $num4 + "+" + $num5 + " = 30";
// should be:
echo $num1 . "+" . $num2 . "+" . $num3 . "+" . $num4 . "+" . $num5 . " = 30";
You should change line:
$r = mt_rand(1,15);
into
$r = mt_rand(0,count($arr)-1);
because your $arr in your getRandomNumber function has only 8 elements (not 16)
function getRandomNumber()
{
$arr = [1,3,5,7,9,11,13,15];
$r = mt_rand(1,15);
if(($r%2)!=0)
{
return $arr[$r];
}
}
The mt_rand function returns a number higher then the array index witch is 7. You can either extend the array and make it have 16 index or reduce the range in mt_rand function to 0-7.

PHP Two Tailed Z-Score to P (Probability) Calculator

I've been searching all over and cannot find anything about this.
I'm looking for a function that will convert a Z-Score to a Probability using a two tailed table, preferably in PHP.
(Like this one: http://www.sjsu.edu/faculty/gerstman/StatPrimer/z-two-tails.pdf)
My only other option is to make an array based on that table and comparing the Z-Score.. There must be a better way.
Edit:
Below is a slab of code found on the PHP.net statistics function page. These functions are really poorly documented.
The functions below will accurately calculate a one-tailed z-score into a probability.
function erf($x)
{
$pi = 3.1415927;
$a = (8*($pi - 3))/(3*$pi*(4 - $pi));
$x2 = $x * $x;
$ax2 = $a * $x2;
$num = (4/$pi) + $ax2;
$denom = 1 + $ax2;
$inner = (-$x2)*$num/$denom;
$erf2 = 1 - exp($inner);
return sqrt($erf2);
}
function cdf($n)
{
if($n < 0)
{
return (1 - erf($n / sqrt(2)))/2;
}
else
{
return (1 + erf($n / sqrt(2)))/2;
}
}
Found a solution:
function erf($x)
{
$pi = 3.1415927;
$a = (8*($pi - 3))/(3*$pi*(4 - $pi));
$x2 = $x * $x;
$ax2 = $a * $x2;
$num = (4/$pi) + $ax2;
$denom = 1 + $ax2;
$inner = (-$x2)*$num/$denom;
$erf2 = 1 - exp($inner);
return sqrt($erf2);
}
function cdf($n)
{
return (1 - erf($n / sqrt(2)))/2;
//I removed the $n < 0 test which inverses the +1/-1
}
function cdf_2tail($n)
{
return 2*cdf($n);
//After a little more digging around, the two tail test is simply 2 x the cdf.
}
I tested my results against: http://vassarstats.net/tabs.html#z and the z-score table.
It is correct to 0.1%

Welle's Wilder Accumulative Swing Index PHP calculation - Cannot return proper value

I am trying to get the accumulative swing index for an aapl stock chart. I am using this calculation for reference.
http://www.barchart.com/education/std_studies.php?what=int_swing&hideheader=true#study
This is what I have written so far. This should return 252.09 but I cannot get it to work.
$asi[0] = -78.75
$ht = 584; // High today
$lt = 574.25; // low
$ct = 584.00; // close
$ot = 578; // open
$hy = 574; // High yesterday
$ly = 565.61;
$cy = 569.05;
$oy = 571.67;
$k = max(($hy-$ct),($ly-$ct));
$abc = array(($ht-$cy), ($lt-$cy), ($ht-$lt));
$max = max($abc);
$r = 0;
if($max == $abc[0]){
$r = ($ht-$cy)-.5*($lt-$cy)+.25*($cy-$oy);
}elseif($max == $abc[1]){
$r = ($lt-$cy)-.5*($ht-$cy)+.25*($cy-$oy);
}elseif($max == $abc[2]){
$r = ($ht-$lt)+.25*($cy-$oy);
}else{
echo "Error in welles accumulative swing index";
exit;
}
$l = 3 //period;
$val = 50 * (($cy - $ct) + .5 *($cy - $oy) + .25*($ct-$ot)) / $r * $k / $l;
$asi[] = $asi[$i-1] + $val;
Any help would be greatly appreciated.
I have tried to implement this index newly symbol-by-symbol and have get different result (swing: -248.7032967033 ).
May be your control value wrong?
That is my code:
class Swing
{
public function calculate($high_price, $low_price, $close_price, $open_price, $t)
{
// (Ct-1 - Ct)
$summand0 = ($close_price[$t-1] - $close_price[$t]);
// 0.5(Ct-1 - Ot-1)
$summand1 = 0.5 * ($close_price[$t-1] - $open_price[$t-1]);
// 0.25(Ct - Ot)
$summand2 = 0.25 * ($close_price[$t] - $open_price[$t]);
$limit_move_default = 3.0;
$r = $this->get_r_value($high_price, $low_price, $close_price, $open_price, $t);
$k = $this->get_k_value($high_price, $low_price, $close_price, $t);
$factor0 = 50.0 * ($summand0 + $summand1 + $summand2) / $r;
$factor1 = $k / $limit_move_default;
// SWING = 50 * ((Ct-1 - Ct)+ 0.5(Ct-1 - Ot-1)+ 0.25(Ct - Ot))/ R * K / M
return $factor0 * $factor1;
}
public function get_k_value($high_price, $low_price, $close_price, $t)
{
// K= MAX(| Ht-Ct-1|, | Lt-Ct-1|)
return max(
abs($high_price[$t] - $close_price[$t-1]),
abs($low_price[$t] - $close_price[$t-1]));
}
public function get_r_value($high_price, $low_price, $close_price, $open_price, $t)
{
// A. |Ht-Ct-1|
$a = abs($high_price[$t] - $close_price[$t-1]);
// B. |Lt-Ct-1|
$b = abs($low_price[$t] - $close_price[$t-1]);
// C. |Ht-Lt|
$c = abs($high_price[$t] - $low_price[$t]);
$max_value = max($a, $b, $c);
$d = abs($high_price[$t] - $low_price[$t]);
if($a == $max_value)
// R= (| Ht-Ct-1|)-.5(| Lt-Ct-1|)+.25(| Ct-1-Ot-1|)
return $a - 0.5 * $b + 0.25 * $d;
if($b == $max_value)
// R= (| Lt-Ct-1|)-.5(| Ht-Ct-1|)+.25(| Ct-1-Ot-1|)
return $b - 0.5 * $a + 0.25 * $d;
if($c == $max_value)
// R= (| Ht-Lt|)+.25(| Ct-1-Ot-1|)
return $c + 0.25 * $d;
}
};
$swing = new Swing();
$high_price = array(574.0, 584.0);
$low_price = array(565.61, 574.25);
$close_price = array(569.05, 584.0);
$open_price = array(571.67, 578.0);
$value = $swing->calculate($high_price, $low_price, $close_price, $open_price, 1);
echo("swing: $value \n");
$d looks wrong.
It should be abs($close_price[$t-1] - $open_price[$t-1]);

SQL or PHP mistake? Distance calculation

I have a problem with my file. I'm making Travian Clone script and we went really far. Now we decided to add artefacts into game.
Goal is to show closest artefacts to the current village we are in. The code is:
function getDistance($coorx1, $coory1, $coorx2, $coory2) {
$max = 2 * WORLD_MAX + 1;
$x1 = intval($coorx1);
$y1 = intval($coory1);
$x2 = intval($coorx2);
$y2 = intval($coory2);
$distanceX = min(abs($x2 - $x1), $max - abs($x2 - $x1));
$distanceY = min(abs($y2 - $y1), $max - abs($y2 - $y1));
$dist = sqrt(pow($distanceX, 2) + pow($distanceY, 2));
return round($dist, 1);
}
unset($reqlvl);
unset($effect);
$arts = mysql_query("SELECT * FROM ".TB_PREFIX."artefacts WHERE id > 0");
$rows = array();
while($row = mysql_fetch_array($arts)) {
$query = mysql_query('SELECT * FROM `' . TB_PREFIX . 'wdata` WHERE `id` = ' . $row['vref']);
$coor2 = mysql_fetch_assoc($query);
$wref = $village->wid;
$coor = $database->getCoor($wref);
$dist = getDistance($coor['x'], $coor['y'], $coor2['x'], $coor2['y']);
$rows[$dist] = $row;
}
ksort($rows, SORT_ASC);
foreach($rows as $row) {
echo '<tr>';
echo '<td class="icon"><img class="artefact_icon_'.$row['type'].'" src="img/x.gif" alt="" title=""></td>';
echo '<td class="nam">';
echo ''.$row['name'].' <span class="bon">'.$row['effect'].'</span>';
echo '<div class="info">';
if($row['size'] == 1){
$reqlvl = 10;
$effect = "village";
}elseif($row['size'] == 2 OR $row['size'] == 3){
$reqlvl = 20;
$effect = "account";
}
echo '<div class="info">Treasury <b>'.$reqlvl.'</b>, Effect <b>'.$effect.'</b>';
echo '</div></td><td class="pla">'.$database->getUserField($row['owner'],"username",0).'</td>';
echo '<td class="dist">'.getDistance($coor['x'], $coor['y'], $coor2['x'], $coor2['y']).'</td>';
echo '</tr>';
}
?>
but the code seems to be wrong because its showing all same distances. 14.8 to me. I know i maybe have bad explanation but u will probably understand what I need.
I can't help with your current code I'm afraid but you could try using the Haversine Formula instead:
// Where:
// $l1 ==> latitude1
// $o1 ==> longitude1
// $l2 ==> latitude2
// $o2 ==> longitude2
function haversine ($l1, $o1, $l2, $o2) {
$l1 = deg2rad ($l1);
$sinl1 = sin ($l1);
$l2 = deg2rad ($l2);
$o1 = deg2rad ($o1);
$o2 = deg2rad ($o2);
$distance = (7926 - 26 * $sinl1) * asin (min (1, 0.707106781186548 * sqrt ((1 - (sin ($l2) * $sinl1) - cos ($l1) * cos ($l2) * cos ($o2 - $o1)))));
return round($distance, 2);
}
Credit goes to this post on go4expert.com, I've used this function in the past and found it works very well.

Categories