fromFloat() public static method

public static fromFloat ( float $fltValue, integer $scale = null, boolean $removeZeros = false ) : Decimal
$fltValue float
$scale integer
$removeZeros boolean If true then removes trailing zeros from the number representation
return Decimal
 public function testNegativeNumbers()
 {
     $this->assertFalse(Decimal::fromInteger(-1)->isZero());
     $this->assertFalse(Decimal::fromFloat(-1.0)->isZero());
     $this->assertFalse(Decimal::fromFloat(-0.1)->isZero());
     $this->assertFalse(Decimal::fromString('-1')->isZero());
 }
 public function testIntegerRound()
 {
     $this->assertTrue(Decimal::fromFloat(0.4)->round()->isZero());
     $this->assertTrue(Decimal::fromFloat(0.4)->round()->equals(Decimal::fromInteger(0)));
     $this->assertFalse(Decimal::fromFloat(0.5)->round()->isZero());
     $this->assertTrue(Decimal::fromFloat(0.5)->round()->equals(Decimal::fromInteger(1)));
 }
 public function testCreateFromFloat()
 {
     $this->assertTrue(Decimal::create(-35.125)->equals(Decimal::fromFloat(-35.125)));
     $this->assertTrue(Decimal::create(0.0)->equals(Decimal::fromFloat(0.0)));
     $this->assertTrue(Decimal::create(35.125)->equals(Decimal::fromFloat(35.125)));
     $this->assertTrue(Decimal::create(INF)->equals(Decimal::getPositiveInfinite()));
     $this->assertTrue(Decimal::create(-INF)->equals(Decimal::getNegativeInfinite()));
 }
Example #4
0
 public function toFileMakerValue($value)
 {
     if (null === $value) {
         return null;
     }
     Assertion::float($value);
     return Decimal::fromFloat($value);
 }
 public function testAsFloat()
 {
     $this->assertEquals(1.0, Decimal::fromString('1.0')->asFloat());
     $this->assertTrue(is_float(Decimal::fromString('1.0')->asFloat()));
     $this->assertEquals(1.0, Decimal::fromInteger(1)->asFloat());
     $this->assertTrue(is_float(Decimal::fromInteger(1)->asFloat()));
     $this->assertEquals(1.0, Decimal::fromFloat(1.0)->asFloat());
     $this->assertEquals(1.123123123, Decimal::fromString('1.123123123')->asFloat());
     $this->assertTrue(is_float(Decimal::fromFloat(1.0)->asFloat()));
     $this->assertTrue(is_float(Decimal::fromString('1.123123123')->asFloat()));
 }
 public function testNotIntegers()
 {
     $this->assertFalse(Decimal::fromString("-200.001")->isInteger());
     $this->assertFalse(Decimal::fromString("-2.001")->isInteger());
     $this->assertFalse(Decimal::fromString("-1.001")->isInteger());
     $this->assertFalse(Decimal::fromString("0.001")->isInteger());
     $this->assertFalse(Decimal::fromString("1.001")->isInteger());
     $this->assertFalse(Decimal::fromString("2.001")->isInteger());
     $this->assertFalse(Decimal::fromString("200.001")->isInteger());
     $this->assertFalse(Decimal::fromFloat(-200.001)->isInteger());
     $this->assertFalse(Decimal::fromFloat(-2.001)->isInteger());
     $this->assertFalse(Decimal::fromFloat(-1.001)->isInteger());
     $this->assertFalse(Decimal::fromFloat(0.001)->isInteger());
     $this->assertFalse(Decimal::fromFloat(1.001)->isInteger());
     $this->assertFalse(Decimal::fromFloat(2.001)->isInteger());
     $this->assertFalse(Decimal::fromFloat(200.001)->isInteger());
 }
Example #7
0
 /**
  * Parse condition divided to field, operator and value
  *
  * @param string field
  * @return array
  */
 protected function _parseCondition($field, $operator, $value)
 {
     // sum function
     $sum = function ($item) use($field) {
         $sum = Decimal::fromInteger(0);
         foreach ($item[$field] as $s) {
             $sum = $sum->add($s);
         }
         return $sum;
     };
     // convert value to decimal
     $value = Decimal::fromFloat($this->_parseDecimal($value));
     switch ($operator) {
         case '=':
             return function ($item) use($sum, $value) {
                 $total = $sum($item);
                 return $total->equals($value);
             };
         case 'NOT':
             return function ($item) use($sum, $value) {
                 $total = $sum($item);
                 return $total->equals($value);
             };
         case '>=':
             return function ($item) use($sum, $value) {
                 $total = $sum($item);
                 return $total->comp($value) > -1;
             };
         case '<=':
             return function ($item) use($sum, $value) {
                 $total = $sum($item);
                 return $total->comp($value) < 1;
             };
         case '>':
             return function ($item) use($sum, $value) {
                 $total = $sum($item);
                 return $total->comp($value) > 0;
             };
         case '<':
             return function ($item) use($sum, $value) {
                 $total = $sum($item);
                 return $total->comp($value) < 0;
             };
     }
     return [$field . $operator => $value];
 }
 public function testScaledComp()
 {
     // Transitivity
     $this->assertEquals(0, Decimal::fromFloat(1.001)->comp(Decimal::fromFloat(1.01), 1));
     $this->assertEquals(0, Decimal::fromFloat(1.01)->comp(Decimal::fromFloat(1.004), 1));
     $this->assertEquals(0, Decimal::fromFloat(1.001)->comp(Decimal::fromFloat(1.004), 1));
     // Reflexivity
     $this->assertEquals(0, Decimal::fromFloat(1.00525)->comp(Decimal::fromFloat(1.00525), 2));
     // Symmetry
     $this->assertEquals(0, Decimal::fromFloat(1.01)->comp(Decimal::fromFloat(1.001), 1));
     $this->assertEquals(0, Decimal::fromFloat(1.004)->comp(Decimal::fromFloat(1.01), 1));
     $this->assertEquals(0, Decimal::fromFloat(1.004)->comp(Decimal::fromFloat(1.001), 1));
     // Proper rounding
     $this->assertEquals(0, Decimal::fromFloat(1.004)->comp(Decimal::fromFloat(1.0), 2));
     // Warning, float to Decimal conversion can have unexpected behaviors, like converting
     // 1.005 to Decimal("1.0049999999999999")
     $this->assertEquals(0, Decimal::fromFloat(1.0050000000001)->comp(Decimal::fromFloat(1.01), 2));
     $this->assertEquals(0, Decimal::fromString("1.005")->comp(Decimal::fromString("1.010"), 2));
     # Proper rounding
     $this->assertEquals(-1, Decimal::fromFloat(1.004)->comp(Decimal::fromFloat(1.0050000000001), 2));
 }
 /**
  * @dataProvider floatProvider
  */
 public function testFromFloat($in, $str, $scale = null, $removeZeroes = false)
 {
     $v = Decimal::fromFloat($in, $scale, $removeZeroes);
     $this->assertSame($str, $v->innerValue());
 }
Example #10
0
 protected function applyValue($input, Context $ctx)
 {
     $output = $input;
     cast:
     $allowString = $this->allowString === null ? true : $this->allowString;
     try {
         $cast = $input;
         if ($allowString && is_string($input)) {
             if ($input === '') {
                 $cast = null;
             } else {
                 $cast = BigNumbers\Decimal::fromString($input);
             }
         } elseif ($this->allowInt && is_int($input)) {
             $cast = BigNumbers\Decimal::fromInteger($input);
         } elseif ($this->allowDouble && is_float($input)) {
             $cast = BigNumbers\Decimal::fromFloat($input);
         }
         if ($cast !== $input) {
             $ctx->setChange(Change::Internal);
         }
         $output = $cast;
     } catch (\Exception $ex) {
         $ctx->addReason($this, ['id' => 'decimal.invalid']);
         goto done;
     }
     // must cast before this so we can cast to null
     if ($output === null) {
         goto done;
     }
     type:
     if (!$output instanceof BigNumbers\Decimal) {
         $ctx->addReason($this, ['id' => 'decimal.invalid']);
         goto done;
     }
     scale:
     if ($this->scale !== null) {
         if (preg_match('/\\.([0-9]+)$/', $output . '', $match)) {
             $inScale = strlen($match[1]);
             if ($inScale > $this->scale) {
                 $ctx->addReason($this, ['id' => 'decimal.scale', 'params' => ['scale' => $inScale, 'expected' => $this->scale]]);
             }
         }
     }
     precision:
     if ($this->precision !== null) {
         $digits = preg_replace("/[^0-9]/", '', $output . '');
         $inPrecision = strlen($digits);
         if ($inPrecision > $this->precision) {
             $ctx->addReason($this, ['id' => 'decimal.precision', 'params' => ['precision' => $inPrecision, 'expected' => $this->precision]]);
         }
     }
     minmax:
     $min = $this->min !== null ? BigNumbers\Decimal::create($this->min) : null;
     $max = $this->max !== null ? BigNumbers\Decimal::create($this->max) : null;
     if ($min !== null && $max !== null) {
         if ($output->comp($min) < 0 || $output->comp($max) > 0) {
             $ctx->addReason($this, ['id' => 'decimal.between', 'params' => ['atLeast' => $min . '', 'atMost' => $max . '']]);
         }
     } elseif ($min !== null) {
         if ($output->comp($min) < 0) {
             $ctx->addReason($this, ['id' => 'decimal.atLeast', 'params' => ['atLeast' => $min . '']]);
         }
     } elseif ($max !== null) {
         if ($output->comp($max) > 0) {
             $ctx->addReason($this, ['id' => 'decimal.atMost', 'params' => ['atMost' => $max . '']]);
         }
     }
     divisibleBy:
     if ($this->divisibleBy !== null) {
         $divisibleBy = !$this->divisibleBy instanceof BigNumbers\Decimal ? BigNumbers\Decimal::create($this->divisibleBy) : $this->divisibleBy;
         if (!$output->mod($divisibleBy)->isZero()) {
             $dvFmt = $this->removeTrailingZeroes($divisibleBy);
             $ctx->addReason($this, ['id' => 'decimal.divisibleBy', 'params' => ['divisibleBy' => $dvFmt]]);
         }
     }
     done:
     if ($this->emitString && $output instanceof BigNumbers\Decimal) {
         $output = $output->innerValue();
         if (!is_string($input)) {
             $ctx->setChange(Change::Internal);
         }
     }
     return $output;
 }
Example #11
0
 /**
  * Calculate totals
  *
  * @param callable filter
  * @return array
  */
 protected function _calculateTotals($filter)
 {
     if (!is_callable($filter)) {
         throw new \InvalidArgumentException('Filter for _calculateTotals method has to be callable.');
     }
     $taxTotals = [];
     $weight = Decimal::fromInteger(0);
     foreach ($this->getItems($filter) as $item) {
         $price = $this->getItemPrice($item);
         if (!isset($taxTotals[$item->getTaxRate()])) {
             $taxTotals[$item->getTaxRate()] = Decimal::fromInteger(0);
         }
         $taxTotals[$item->getTaxRate()] = $taxTotals[$item->getTaxRate()]->add($price);
         // weight
         if ($item instanceof WeightedCartItemInterface) {
             $itemWeight = Decimal::fromFloat((double) $item->getWeight());
             $itemWeight = $itemWeight->mul(Decimal::fromInteger((int) $item->getCartQuantity()));
             $weight = $weight->add($itemWeight);
         }
     }
     $totals = ['subtotals' => [], 'taxes' => [], 'totals' => [], 'weight' => $weight->round(6)];
     foreach ($taxTotals as $taxRate => $amount) {
         if ($this->_pricesWithVat) {
             $totals['totals'][$taxRate] = $amount;
             $totals['taxes'][$taxRate] = $amount->mul(Decimal::fromFloat(1 - 1 / (1 + (double) $taxRate / 100)))->round($this->_roundingDecimals);
             $totals['subtotals'][$taxRate] = $amount->sub($totals['taxes'][$taxRate]);
         } else {
             $totals['subtotals'][$taxRate] = $amount;
             $totals['taxes'][$taxRate] = $amount->mul(Decimal::fromFloat((double) $taxRate / 100))->round($this->_roundingDecimals);
             $totals['totals'][$taxRate] = $amount->add($totals['taxes'][$taxRate]);
         }
     }
     return $totals;
 }
 public function testNegativeFloor()
 {
     $this->assertTrue(Decimal::fromFloat(-3.4)->floor()->equals(Decimal::fromFloat(-4.0)));
     $this->assertTrue(Decimal::fromFloat(-3.6)->floor()->equals(Decimal::fromFloat(-4.0)));
 }
 public function testPositiveWithNegativeExponent()
 {
     $pFive = Decimal::fromInteger(5);
     $this->assertTrue($pFive->pow(Decimal::fromInteger(-1))->equals(Decimal::fromString("0.2")), "The answer must be 0.2, but was " . $pFive->pow(Decimal::fromInteger(-1)));
     $this->assertTrue($pFive->pow(Decimal::fromInteger(-2))->equals(Decimal::fromString("0.04")), "The answer must be 0.04, but was " . $pFive->pow(Decimal::fromInteger(-2)));
     $this->assertTrue($pFive->pow(Decimal::fromInteger(-3))->equals(Decimal::fromString("0.008")), "The answer must be 0.008, but was " . $pFive->pow(Decimal::fromInteger(-3)));
     $this->assertTrue($pFive->pow(Decimal::fromInteger(-4))->equals(Decimal::fromString("0.0016")), "The answer must be 0.0016, but was " . $pFive->pow(Decimal::fromInteger(-4)));
     $this->assertTrue($pFive->pow(Decimal::fromFloat(-4.5))->equals(Decimal::fromString("0.0007155417527999")), "The answer must be 0.0007155417527999, but was " . $pFive->pow(Decimal::fromFloat(-4.5)));
 }
Example #14
0
 /**
  * Calculate totals
  *
  * @param string type
  * @return void
  */
 protected function _calculate($type)
 {
     $totals = [];
     foreach ($this->_items as $item) {
         // test type
         if (!$this->_typeCondition($item->getCartType(), $type)) {
             continue;
         }
         $price = $this->getItemPrice($item);
         if (!isset($totals[$item->getTaxRate()])) {
             $totals[$item->getTaxRate()] = Decimal::fromInteger(0);
         }
         $totals[$item->getTaxRate()] = $totals[$item->getTaxRate()]->add($price);
     }
     $this->_totals[$type] = ['subtotal' => Decimal::fromInteger(0), 'taxes' => [], 'total' => Decimal::fromInteger(0)];
     foreach ($totals as $taxRate => $amount) {
         if ($this->_pricesWithVat) {
             $this->_totals[$type]['total'] = $this->_totals[$type]['total']->add($amount);
             $this->_totals[$type]['taxes'][$taxRate] = $amount->mul(Decimal::fromFloat(1 - 1 / (1 + (double) $taxRate / 100)))->round($this->_roundingDecimals);
             $this->_totals[$type]['subtotal'] = $this->_totals[$type]['subtotal']->add($amount)->sub($this->_totals[$type]['taxes'][$taxRate]);
         } else {
             $this->_totals[$type]['subtotal'] = $this->_totals[$type]['subtotal']->add($amount);
             $this->_totals[$type]['taxes'][$taxRate] = $amount->mul(Decimal::fromFloat((double) $taxRate / 100))->round($this->_roundingDecimals);
             $this->_totals[$type]['total'] = $this->_totals[$type]['total']->add($amount)->add($this->_totals[$type]['taxes'][$taxRate]);
         }
     }
 }
 public function testScaledNotEquals()
 {
     # Proper rounding
     $this->assertFalse(Decimal::fromFloat(1.004)->equals(Decimal::fromFloat(1.0050000000001), 2));
 }
 public function testSuccessfulConversionFromFileMaker()
 {
     $type = new FloatType();
     $value = Decimal::fromFloat(1.1);
     $this->assertSame(1.1, $type->fromFileMakerValue($value));
 }