Example #1
0
 /**
  * Shift the decimal point according to the given exponent.
  *
  * @param DecimalValue $decimal
  * @param int $exponent The exponent to apply (digits to shift by). A Positive exponent
  * shifts the decimal point to the right, a negative exponent shifts to the left.
  *
  * @throws InvalidArgumentException
  * @return DecimalValue
  */
 public function shift(DecimalValue $decimal, $exponent)
 {
     if (!is_int($exponent)) {
         throw new InvalidArgumentException('$exponent must be an integer');
     }
     if ($exponent == 0) {
         return $decimal;
     }
     $sign = $decimal->getSign();
     $intPart = $decimal->getIntegerPart();
     $fractPart = $decimal->getFractionalPart();
     if ($exponent < 0) {
         $intPart = $this->shiftLeft($intPart, $exponent);
     } else {
         $fractPart = $this->shiftRight($fractPart, $exponent);
     }
     $digits = $sign . $intPart . $fractPart;
     $digits = $this->stripLeadingZeros($digits);
     return new DecimalValue($digits);
 }
Example #2
0
 /**
  * Compares this DecimalValue to another DecimalValue.
  *
  * @since 0.1
  *
  * @param DecimalValue $that
  *
  * @throws LogicException
  * @return int +1 if $this > $that, 0 if $this == $that, -1 if $this < $that
  */
 public function compare(DecimalValue $that)
 {
     if ($this === $that) {
         return 0;
     }
     $a = $this->getValue();
     $b = $that->getValue();
     if ($a === $b) {
         return 0;
     }
     if ($a[0] === '+' && $b[0] === '-') {
         return 1;
     }
     if ($a[0] === '-' && $b[0] === '+') {
         return -1;
     }
     // compare the integer parts
     $aInt = ltrim($this->getIntegerPart(), '0');
     $bInt = ltrim($that->getIntegerPart(), '0');
     $sense = $a[0] === '+' ? 1 : -1;
     // per precondition, there are no leading zeros, so the longer nummber is greater
     if (strlen($aInt) > strlen($bInt)) {
         return $sense;
     }
     if (strlen($aInt) < strlen($bInt)) {
         return -$sense;
     }
     // if both have equal length, compare alphanumerically
     $cmp = strcmp($aInt, $bInt);
     if ($cmp > 0) {
         return $sense;
     }
     if ($cmp < 0) {
         return -$sense;
     }
     // compare fractional parts
     $aFract = rtrim($this->getFractionalPart(), '0');
     $bFract = rtrim($that->getFractionalPart(), '0');
     // the fractional part is left-aligned, so just check alphanumeric ordering
     $cmp = strcmp($aFract, $bFract);
     return $cmp > 0 ? $sense : ($cmp < 0 ? -$sense : 0);
 }
Example #3
0
 /**
  * @dataProvider getGetIntegerPartProvider
  */
 public function testGetFractionalPart(DecimalValue $value, $expected)
 {
     $actual = $value->getIntegerPart();
     $this->assertSame($expected, $actual);
 }