public function rawDemand(City $city1, City $city2) { // city1 raw $c1_manf = $this->popEcon($city1->getPopulation(), $city1->getBaseEconomyManufacture()); $c1_corp = $this->popEcon($city1->getPopulation(), $city1->getBaseEconomyCorporate()); $c1_finc = $this->popEcon($city1->getPopulation(), $city1->getBaseEconomyFinance()); $c1_intl = $this->popEcon($city1->getPopulation(), $city1->getBaseEconomyInternational()); $c1_tour = $this->popEcon($city1->getPopulation(), $city1->getBaseEconomyTourism()); // city2 raw $c2_manf = $this->popEcon($city2->getPopulation(), $city2->getBaseEconomyManufacture()); $c2_corp = $this->popEcon($city2->getPopulation(), $city2->getBaseEconomyCorporate()); $c2_finc = $this->popEcon($city2->getPopulation(), $city2->getBaseEconomyFinance()); $c2_intl = $this->popEcon($city2->getPopulation(), $city2->getBaseEconomyInternational()); $c2_tour = $this->popEcon($city2->getPopulation(), $city2->getBaseEconomyTourism()); $c1ManfRatio = MathProvider::divide($c1_manf, $c2_manf); $c1CorpRatio = MathProvider::divide($c1_corp, $c2_corp); $c1FincRatio = MathProvider::divide($c1_finc, $c2_finc); $c1IntlRatio = MathProvider::divide($c1_intl, $c2_intl); $c1TourRatio = MathProvider::divide($c1_tour, $c2_tour); $c2ManfRatio = MathProvider::divide($c2_manf, $c1_manf); $c2CorpRatio = MathProvider::divide($c2_corp, $c1_corp); $c2FincRatio = MathProvider::divide($c2_finc, $c1_finc); $c2IntlRatio = MathProvider::divide($c2_intl, $c1_intl); $c2TourRatio = MathProvider::divide($c2_tour, $c1_tour); }
public function matchBest($value, $pos = 7) { /* * Have to use this instead of scalar type hints. Because we are dealing with arbitrarily large numbers, we are * using the bc math extension. This means that all numbers are actually strings in order to retain precision. * * If we used the int or float type hints, PHP 7 would cast string values (which is good), but that would lose * precision in the cast (which is bad). * * is_numeric will achieve the desired effect without altering the $value */ if (!is_numeric($value)) { throw new \Exception('Cannot pass a non-numeric value.'); } // The number is more than three orders of magnitude from zero if ($value >= 1000 || $value <= -1000) { // Increase the exponent by three and try again return $this->matchBest(MathProvider::divide($value, 1000), $pos + 1); } // The number is a decimal less than one from zero if ($value < 1 && $value > -1 && $value != 0) { // Decrease the exponent by three and try again return $this->matchBest(MathProvider::multiply($value, 1000), $pos - 1); } // If no transformation is needed, we have a special case of the return if ($pos == 7) { return ['value' => $value, 'scale' => '1', 'prefix' => '']; } // Otherwise, we have our answer return ['value' => $value, 'scale' => $this->scale[$this->order[$pos]], 'prefix' => $this->order[$pos]]; }
/** * * * @param string|int|float $value * @param string $from * @param string $to * @return string * @throws \Exception */ protected function convert($value, $from, $to) { return MathProvider::divide(MathProvider::multiply($value, $this->getConversionRate($from)), $this->getConversionRate($to)); }
/** * Attempts to take the square root of a set of numerators and denominators, determining both the value and unit * composition, and returning the correct unit object with the correct value. * * @param Quantity[]|int[] $numerators * @param Quantity[]|int[] $denominators * @param int $precision * * @return Quantity * @throws \Exception */ public function naiveSquareRoot(array $numerators, array $denominators, $precision = 2) { $newVal = 1; foreach ($numerators as $key => $quantity) { if ($quantity instanceof Quantity) { $oldUnit = $quantity->getUnit(); $newVal = MathProvider::multiply($newVal, $quantity->toNative()->getValue()); $quantity->to($oldUnit); } elseif (is_numeric($quantity)) { $newVal = MathProvider::multiply($newVal, $quantity); unset($numerators[$key]); } else { throw new \Exception('Invalid numerator'); } } foreach ($denominators as $key => $quantity) { if ($quantity instanceof Quantity) { $oldUnit = $quantity->getUnit(); $newVal = MathProvider::divide($newVal, $quantity->toNative()->getValue(), $precision); $quantity->to($oldUnit); } elseif (is_numeric($quantity)) { $newVal = MathProvider::divide($newVal, $quantity, $precision); unset($denominators[$key]); } else { throw new \Exception('Invalid denominator'); } } $unitComp = $this->getUnitCompArray($numerators, $denominators); foreach ($unitComp as $unit => $exp) { $newExp = $exp / 2; if (!is_int($newExp)) { throw new \Exception('Incorrect exponents after square root.'); } $unitComp[$unit] = $newExp; } $newUnit = $this->getUnitCompClass($unitComp); return $newUnit->preConvertedAdd(MathProvider::squareRoot($newVal, $precision)); }