public function testInfiniteRound() { $pInf = Decimal::getPositiveInfinite(); $nInf = Decimal::getNegativeInfinite(); $this->assertTrue($pInf->round()->equals($pInf)); $this->assertTrue($nInf->round()->equals($nInf)); }
public function testPositiveNegativeDecimalAdd() { $n1 = Decimal::fromString('3.45'); $n2 = Decimal::fromString('-7.67'); $this->assertTrue($n1->add($n2)->equals(Decimal::fromString('-4.22'))); $this->assertTrue($n2->add($n1)->equals(Decimal::fromString('-4.22'))); }
/** * @dataProvider modProvider */ public function testFiniteFiniteMod($number, $mod, $answer, $scale = null) { $numberDec = Decimal::fromString($number); $modDec = Decimal::fromString($mod); $decimalAnswer = $numberDec->mod($modDec, $scale); $this->assertTrue(Decimal::fromString($answer)->equals($decimalAnswer), $decimalAnswer . ' % ' . $mod . ' must be equal to ' . $answer . ', but was ' . $decimalAnswer); }
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 testBasicCase() { $n1 = Decimal::fromString('3.45'); $this->assertTrue(Decimal::fromDecimal($n1)->equals($n1)); $this->assertTrue(Decimal::fromDecimal($n1, 2)->equals($n1)); $this->assertTrue(Decimal::fromDecimal($n1, 1)->equals(Decimal::fromString('3.5'))); $this->assertTrue(Decimal::fromDecimal($n1, 0)->equals(Decimal::fromString('3'))); }
public function toFileMakerValue($value) { if (null === $value) { return null; } Assertion::integer($value); return Decimal::fromInteger($value); }
public function toFileMakerValue($value) { if (null === $value) { return null; } Assertion::float($value); return Decimal::fromFloat($value); }
public function testNegativeInfiniteNegativePower() { $nInf = InfiniteDecimal::getNegativeInfinite(); $zero = DecimalConstants::Zero(); $this->assertTrue($nInf->pow(Decimal::fromInteger(-1))->equals($zero)); $this->assertTrue($nInf->pow(Decimal::fromInteger(-2))->equals($zero)); $this->assertTrue($nInf->pow(Decimal::fromInteger(-3))->equals($zero)); $this->assertTrue($nInf->pow($nInf)->equals($zero)); }
public function __invoke($value) : ValidationResult { Assertion::numeric($value); $decimalValue = Decimal::fromString((string) $value); if ($decimalValue->comp($this->limit) === 1) { return new ValidationResult(new ValidationError('error.max-number', ['limit' => (string) $this->limit])); } return new ValidationResult(); }
function handleValueFromDb($value, array $fieldInfo, $row) { if ($value === null && $this->zeroIfNull) { $value = "0"; } if ($value !== null) { return BigNumbers\Decimal::fromString($value); } }
public function testInfiniteInfiniteComp() { $pInf = Decimal::getPositiveInfinite(); $nInf = Decimal::getNegativeInfinite(); $this->assertTrue($pInf->comp($pInf) === 0); $this->assertTrue($nInf->comp($nInf) === 0); $this->assertTrue($pInf->comp($nInf) === 1); $this->assertTrue($nInf->comp($pInf) === -1); }
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())); }
/** * {@inheritDoc} */ public function convertToPHPValue($value, AbstractPlatform $platform) { if ($value === null) { return null; } try { return Decimal::create($value); } catch (\Exception $e) { throw ConversionException::conversionFailedFormat($value, $this->getName(), '0.0'); } }
public function testFiniteInfiniteDiv() { $pTen = Decimal::fromInteger(10); $nTen = Decimal::fromInteger(-10); $pInf = InfiniteDecimal::getPositiveInfinite(); $nInf = InfiniteDecimal::getNegativeInfinite(); $this->assertTrue($pInf->div($pTen)->equals($pInf)); $this->assertTrue($pInf->div($nTen)->equals($nInf)); $this->assertTrue($nInf->div($pTen)->equals($nInf)); $this->assertTrue($nInf->div($nTen)->equals($pInf)); $this->assertTrue($pTen->div($pInf)->isZero()); $this->assertTrue($nTen->div($pInf)->isZero()); $this->assertTrue($pTen->div($nInf)->isZero()); $this->assertTrue($nTen->div($nInf)->isZero()); }
public function testBasicDiv() { $one = Decimal::fromInteger(1); $two = Decimal::fromInteger(2); $four = Decimal::fromInteger(4); $eight = Decimal::fromInteger(8); // Integer exact division $this->assertTrue($eight->div($two)->equals($four)); $this->assertTrue($eight->div($four)->equals($two)); // Arbitrary precision division $this->assertTrue($one->div($eight, 0)->equals(Decimal::fromString('0'))); $this->assertTrue($one->div($eight, 1)->equals(Decimal::fromString('0.1'))); $this->assertTrue($one->div($eight, 2)->equals(Decimal::fromString('0.13'))); $this->assertTrue($one->div($eight, 3)->equals(Decimal::fromString('0.125'))); }
public function __invoke(string $value) { $cleanedValue = preg_replace_callback('(^[^\\d-.]*(-?)([^.]*)(.?)(.*)$)', function (array $match) : string { return $match[1] . preg_replace('([^\\d]+)', '', $match[2]) . $match[3] . preg_replace('([^\\d]+)', '', $match[4]); }, $value); if ('' === $cleanedValue) { return null; } if ('-' === $cleanedValue) { $cleanedValue = '0'; } if (0 === strpos($cleanedValue, '.')) { $cleanedValue = '0' . $cleanedValue; } return Decimal::fromString($cleanedValue); }
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()); }
/** * 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 testInfiniteMul() { $pInf = Decimal::getPositiveInfinite(); $nInf = Decimal::getNegativeInfinite(); $pOne = Decimal::fromInteger(1); $nOne = Decimal::fromInteger(-1); $oipp = $pOne->mul($pInf); $oipn = $pOne->mul($nInf); $oinp = $nOne->mul($pInf); $oinn = $nOne->mul($nInf); $this->assertTrue($oipp->isPositive()); $this->assertTrue($oinn->isPositive()); $this->assertTrue($oinp->isNegative()); $this->assertTrue($oipn->isNegative()); $this->assertTrue($oipp->isInfinite()); $this->assertTrue($oipn->isInfinite()); $this->assertTrue($oinp->isInfinite()); $this->assertTrue($oinn->isInfinite()); }
function testDecimalToDb() { $d = Test\Factory::managerNoteModelCustom(' /** :amiss = true; */ class Pants { /** :amiss = {"field": {"primary": true, "type": "autoinc"}}; */ public $id; /** :amiss = {"field": {"type": "decimal"}}; */ public $num; } '); $c = $d->ns . '\\Pants'; $obj = new $c(); $obj->num = Decimal::fromString("1.23456"); $d->manager->insert($obj); $out = $d->connector->query("SELECT num FROM pants")->fetchColumn(0); $this->assertEquals("1.23456", $out); }
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)); }
public function testInfiniteInfiniteSub() { $pInf = Decimal::getPositiveInfinite(); $nInf = Decimal::getNegativeInfinite(); $catched = false; try { $pInf->sub($pInf); } catch (\DomainException $e) { $catched = true; } $this->assertTrue($catched); $catched = false; try { $nInf->sub($nInf); } catch (\DomainException $e) { $catched = true; } $this->assertTrue($catched); $this->assertTrue($pInf->sub($nInf)->equals($pInf)); $this->assertTrue($nInf->sub($pInf)->equals($nInf)); }
private function isDecimal($v) { try { BigNumbers\Decimal::create($v); return true; } catch (\Exception $e) { return false; } }
public function testCreateFromDecimal() { $this->assertTrue(Decimal::create(Decimal::fromString('345.76'), 1)->equals(Decimal::fromString('345.8'))); $this->assertTrue(Decimal::create(Decimal::fromString('345.76'), 2)->equals(Decimal::fromString('345.76'))); }
public function testPositiveAdditiveInverse() { $this->assertTrue(Decimal::fromInteger(1)->additiveInverse()->equals(Decimal::fromInteger(-1))); $this->assertTrue(Decimal::fromString('1.768')->additiveInverse()->equals(Decimal::fromString('-1.768'))); }
/** * @dataProvider floatProvider */ public function testFromFloat($in, $str, $scale = null, $removeZeroes = false) { $v = Decimal::fromFloat($in, $scale, $removeZeroes); $this->assertSame($str, $v->innerValue()); }
public function testGetInfinite() { $this->assertTrue(Decimal::getPositiveInfinite()->equals(InfiniteDecimal::getPositiveInfinite())); $this->assertTrue(Decimal::getNegativeInfinite()->equals(InfiniteDecimal::getNegativeInfinite())); }
public function testSuccessfulConversionToFileMaker() { $type = new DecimalType(); $value = Decimal::fromInteger(1); $this->assertSame($value, $type->toFileMakerValue($value)); }
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; }
/** * 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; }