Esempio n. 1
0
 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]];
 }
Esempio n. 2
0
 /**
  * @param Time                  $time
  * @param Acceleration          $acceleration
  * @param UnitComposition|null  $unitComposition
  *
  * @return Length
  */
 public static function distanceFromConstantAccel(Time $time, Acceleration $acceleration, UnitComposition $unitComposition = null)
 {
     if (is_null($unitComposition)) {
         $unitComposition = new UnitComposition();
     }
     /** @var Length $distance */
     $distance = $unitComposition->naiveMultiOpt([$time, $time, $acceleration], []);
     return $distance->preConvertedSubtract(MathProvider::divide($distance->getValue(), 2));
 }
Esempio n. 3
0
 public function preConvertedDivide($value, $precision = 2)
 {
     $this->value = MathProvider::divide($this->value, $value, $precision);
     return $this;
 }
Esempio n. 4
0
 /**
  * @param Quantity[] $mults
  * @param Quantity[] $divides
  * @param int        $precision
  */
 public function naiveMultiOpt(array $mults, array $divides, $precision = 2)
 {
     $newUnit = $this->getMultiUnits($mults, $divides);
     $newVal = 1;
     foreach ($mults as $quantity) {
         $newVal = MathProvider::multiply($newVal, $quantity->toNative()->getValue());
     }
     foreach ($divides as $quantity) {
         $newVal = MathProvider::divide($newVal, $quantity->toNative()->getValue(), $precision);
     }
     return $newUnit->preConvertedAdd($newVal);
 }