private static function _irr($pval, $payarray, $fromdayone)
    {
        $low = 0.0;
        $high = 100.0;
        $lowval = self::_npv($pval, $payarray, $low, $fromdayone);
        $highval = self::_npv($pval, $payarray, $high, $fromdayone);

        // The sum of $payarray is smaller than $pval, impossible!
        if ($lowval > 0.0) {
            return (-1);
        }

        // Standard divide and conquer.
        do {
            $mid = self::_midpoint($low, $high);
            $midval  = self::_npv($pval, $payarray, $mid, $fromdayone);
            if (abs($midval) < self::$accuracy) {
                //we are close enough
                return ($mid);
            }

            if ($highval < 0.0) {
                // we are not in range, so double it
                $low = $high;
                $lowval = $highval;
                $high *= 2;
                $highval = self::_npv($pval, $payarray, $high, $fromdayone);
            } else if ($midval >= 0.0) {
                // irr is between low and mid
                $high = $mid;
                $highval = $midval;
            } else {
                // irr is between mid and high
                $low = $mid;
                $lowval = $midval;
            }
        } while ($high < 1000000);
        // bad input, insanely high interest. APR will be INSANER!
        return (-2);
    }