<?php
/**
* Quadratic Equation Solver
*
* @package com.cisneiros.math
* @version 1.0
* @author Cisneiros <hide@address.com>
* @copyright 2009 - 2010 (C) by Cisneiros
* @license http://creativecommons.org/licenses/by/2.5/br/ Creative Commons Attribution 2.5 Brazil License
*/
/**
* Quadratic equation to be solved by Bhaskara's method, like "ax^2 + bx + c = 0".
*
* @package com.cisneiros.math
* @version 1.0
* @property float $a The "a" value of the equation. Cannot be zero.
* @property float $b The "b" value of the equation.
* @property float $c The "c" value of the equation.
* @property int $precision The number of decimal places of the roots.
* @property float $delta The discriminant of the equation, calculated based on a, b and c.
* @property array $roots The array containing the equation's roots.
*/
class QuadraticEquation
{
private $a;
private $b;
private $c;
private $precision;
private $delta;
private $roots;
/**
* Constructs the class, optionally setting $a, $b, $c and $precision.
*
* @version 1.0
* @since 1.0
* @param float $a The "a" value of the equation.
* @param float $b The "b" value of the equation.
* @param float $c The "c" value of the equation.
* @param int $precision The number of decimal places of the roots.
*/
public function __construct ($a = NULL, $b = NULL, $c = NULL, $precision = NULL)
{
if ($a)
{
$this->setA($a);
$this->setB($b);
$this->setC($c);
}
if ($precision)
{
$this->setPrecision($precision);
}
}
/**
* Return the root(s) as a string. CANNOT BE USED if the equation is unsolvable!
*
* @version 1.0
* @since 1.0
* @return string Root(s)
* @throws Exception On unsolvable equation (delta < 0).
*/
public function __toString()
{
$roots = $this->getRoots();
$string = "{$roots[0]}";
if (isset($roots[1]))
{
$string .= "; {$roots[1]}";
}
return $string;
}
/**
* Returns the value of "a".
*
* @version 1.0
* @since 1.0
* @return float Value of "a".
*/
public function getA()
{
return $this->a;
}
/**
* Returns the value of "b".
*
* @version 1.0
* @since 1.0
* @return float Value of "b".
*/
public function getB()
{
return $this->b;
}
/**
* Returns the value of "c".
*
* @version 1.0
* @since 1.0
* @return float Value of "c".
*/
public function getC()
{
return $this->c;
}
/**
* Returns the precision.
*
* @version 1.0
* @since 1.0
* @return int Precision.
*/
public function getPrecision()
{
if (!isset($this->precision))
{
$this->setPrecision(2);
}
return $this->precision;
}
/**
* Returns the discriminant (delta).
*
* @version 1.0
* @since 1.0
* @return float Discriminant (delta).
*/
public function getDelta()
{
if (!isset($this->delta))
{
$this->delta = pow($this->getB(), 2) - (4 * $this->getA() * $this->getC());
}
return $this->delta;
}
/**
* Calculates the roots and returns them as an array.
*
* @version 1.0
* @since 1.0
* @return array Roots.
* @throws Exception On unsolvable equation (delta < 0).
*/
public function getRoots()
{
if (!isset($this->roots))
{
if ($this->getDelta() < 0)
{
throw new Exception ('This equation has no real roots.');
}
elseif ($this->getDelta() == 0)
{
$x = (0 - $this->getB()) / 2;
$this->roots = array(round($x, $this->getPrecision()));
}
else
{
$x1 = (0 - $this->getB() + sqrt($this->getDelta())) / (2 * $this->getA());
$x2 = (0 - $this->getB() - sqrt($this->getDelta())) / (2 * $this->getA());
$this->roots = array(round($x1, $this->getPrecision()), round($x2, $this->getPrecision()));
}
}
return $this->roots;
}
/**
* Sets the value of "a". Also unsets the delta and the roots for recalculation.
*
* @version 1.0
* @since 1.0
* @throws Exception On setting a "zero" value.
*/
public function setA($a)
{
if ($a == 0)
{
throw new Exception('The value of "a" cannot be zero.');
}
else
{
$this->a = (float) $a;
unset($this->delta);
unset($this->roots);
}
}
/**
* Sets the value of "b". Also unsets the delta and the roots for recalculation.
*
* @version 1.0
* @since 1.0
*/
public function setB($b)
{
$this->b = (float) $b;
unset($this->delta);
unset($this->roots);
}
/**
* Sets the value of "c". Also unsets the delta and the roots for recalculation.
*
* @version 1.0
* @since 1.0
*/
public function setC($c)
{
$this->c = (float) $c;
unset($this->delta);
unset($this->roots);
}
/**
* Sets the precision. Also unsets the roots for rerouding.
*
* @version 1.0
* @since 1.0
* @throws Exception On precision smaller than zero.
*/
public function setPrecision($precision)
{
if ($precision < 0)
{
throw new Exception('The number of decimal places may not be smaller then zero.');
}
else
{
$this->precision = (int) $precision;
unset($this->roots);
}
}
}