create() public static method

Decimal "constructor".
public static create ( mixed $value, integer $scale = null, boolean $removeZeros = false ) : Decimal
$value mixed
$scale integer
$removeZeros boolean If true then removes trailing zeros from the number representation
return Decimal
示例#1
0
 /**
  * {@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');
     }
 }
示例#2
0
 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')));
 }
示例#4
0
 function tableSchema($db, $table)
 {
     $pdo = $this->getPDO();
     $db = str_replace('`', '', $db);
     $table = str_replace('`', '', $table);
     $stmt = $pdo->query("EXPLAIN `{$db}`.`{$table}`");
     $props = [];
     while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
         $checks = [];
         $textLength = null;
         $dateFormat = null;
         $required = $row['Null'] == 'NO';
         $default = $row['Default'];
         easy_matches:
         switch ($row['Type']) {
             case 'float':
                 // FIXME: cheating. this should change the tolerance but
                 // for expedience we will treat it as the same for now.
             // FIXME: cheating. this should change the tolerance but
             // for expedience we will treat it as the same for now.
             case 'double':
                 $check = ['required' => $required, 'allowString' => true];
                 if ($default !== null) {
                     $check['initial'] = (double) $default;
                 }
                 $checks[] = $this->registry->construct('check', 'double', $check);
                 break;
             case 'date':
             case 'datetime':
             case 'timestamp':
                 $check = ['required' => $required, 'initial' => $default, 'formats' => ['Y-m-d H:i:s', 'Y-m-d']];
                 $checks[] = $this->registry->construct('check', 'dateFormat', $check);
                 $checks[] = $this->registry->construct('check', 'date', []);
                 break;
             case 'time':
                 $check = ['required' => $required, 'pattern' => '^[0-9]?[0-9]:[0-9]?[0-9]$', 'emptyMode' => \Fulfil\Check\String_::EMPTY_BLOCK, 'initial' => $default];
                 $checks[] = $this->registry->construct('check', 'string', $check);
                 break;
             case 'tinyint(1)':
                 if ($this->interpretBools) {
                     $checks[] = $this->registry->construct('check', 'bool', ['required' => $required, 'trueValues' => [1, '1', true], 'falseValues' => [0, '0', false], 'initial' => $default === null ? null : $default !== '0']);
                 }
                 break;
             case 'text':
             case 'blob':
                 $textLength = 65535;
             case 'mediumtext':
             case 'mediumblob':
                 $textLength = 16777215;
             case 'longtext':
             case 'longblob':
                 $textLength = 4294967295;
             case 'tinytext':
             case 'tinyblob':
                 $textLength = $textLength ?: 255;
                 $check = ['required' => $required, 'emptyMode' => \Fulfil\Check\String_::EMPTY_ALLOW, 'initial' => $default];
                 if (substr($row['Type'], -4) == 'text') {
                     $check['lengthMax'] = $textLength;
                 } else {
                     $check['bytesMax'] = $textLength;
                 }
                 $checks[] = $this->registry->construct('check', 'string', $check);
                 break;
         }
         if (!$checks) {
             if (preg_match('/^ (?P<kind> medium | tiny | big )? int \\( (?P<len> [0-9]+ ) \\) (?P<unsigned> \\s+ unsigned )? $/ix ', $row['Type'], $intMatch)) {
                 integer_type:
                 $max = null;
                 switch ($intMatch['kind']) {
                     case 'big':
                         $check = ['required' => $required];
                         $max = Num::create(2);
                         if (isset($match['unsigned'])) {
                             $check['min'] = 0;
                             $check['max'] = $max->pow(Num::create(64))->sub(Num::create(1));
                         } else {
                             $check['max'] = $max->pow(Num::create(63))->sub(Num::create(1));
                             $check['min'] = $max->pow(Num::create(63))->mul(Num::create(-1));
                         }
                         if ($default !== null) {
                             $check['default'] = Num::create($default);
                         }
                         $checks[] = $this->registry->construct('check', 'decimal', $check);
                         break;
                     case '':
                         $max = $max ?: 4294967296;
                     case 'medium':
                         $max = $max ?: 65536;
                     case 'tiny':
                         $max = $max ?: 256;
                     default:
                         $check = ['required' => $required, 'allowString' => true];
                         if ($default !== null) {
                             $check['initial'] = (int) $default;
                         }
                         if (isset($intMatch['unsigned'])) {
                             $check['min'] = 0;
                             $check['max'] = $max - 1;
                         } else {
                             $check['min'] = -($max / 2);
                             $check['max'] = $max / 2 - 1;
                         }
                         $checks[] = $this->registry->construct('check', 'int', $check);
                         break;
                 }
             } elseif (preg_match('/ ^ ( decimal | numeric ) \\( (?P<precision> [0-9]+ ) , [ ]? (?P<scale> [0-9]+ ) \\) (?P<unsigned> [ ] unsigned )? $/xi', $row['Type'], $decimalMatch)) {
                 decimal_type:
                 $check = ['required' => $required, 'precision' => $decimalMatch['precision'], 'scale' => $decimalMatch['scale']];
                 if ($default !== null) {
                     $check['default'] = Num::create($default);
                 }
                 $range = Num::create(10)->pow(Num::create($check['precision']))->sub(Num::create(1)->div(Num::create(10)->pow(Num::create($check['scale']))));
                 $check['min'] = isset($decimalMatch['unsigned']) ? 0 : $range->mul(Num::create(-1));
                 $check['max'] = $range;
                 $checks[] = $this->registry->construct('check', 'decimal', $check);
             } elseif (preg_match('/ ^ (?P<var> var)? (?P<kind> char|binary) \\( (?P<len>[0-9]+) \\) $/xi', $row['Type'], $charMatch)) {
                 string_type:
                 $check = ['required' => $required, 'emptyMode' => \Fulfil\Check\String_::EMPTY_ALLOW, 'initial' => $default];
                 if ($charMatch['kind'] == 'char') {
                     $check['lengthMax'] = (int) $charMatch['len'];
                 } else {
                     $check['bytesMax'] = (int) $charMatch['len'];
                 }
                 $checks[] = $this->registry->construct('check', 'string', $check);
             } elseif (preg_match('/ ^ (?P<kind> enum | set ) \\( (?P<values> .* ) \\) $/xi', $row['Type'], $enumMatch)) {
                 enum_type:
                 $check = ['required' => $required, 'initial' => $default];
                 // FIXME: enums and sets seem to allow an empty string, but
                 // there's some malarkey about "error strings"
                 $values = [''];
                 foreach (token_get_all('<?php ' . $enumMatch['values']) as $idx => $t) {
                     if (!$idx) {
                         continue;
                     } elseif ($t == ',') {
                         continue;
                     } elseif ($t[0] == T_CONSTANT_ENCAPSED_STRING) {
                         $values[] = substr($t[1], 1, -1);
                     } else {
                         throw new \Exception();
                     }
                 }
                 $check['values'] = $values;
                 $check['emptyMode'] = \Fulfil\Check\String_::EMPTY_ALLOW;
                 $check = $this->registry->construct('check', 'string', $check);
                 if ($enumMatch['kind'] == 'enum') {
                     $checks[] = $check;
                 } else {
                     if ($check->initial) {
                         $check->initial = explode(',', $check->initial);
                     }
                     $checks[] = $this->registry->construct('check', 'list', ['defaultItem' => $check]);
                 }
             }
         }
         if (!$checks) {
             throw new \Exception("No checks for {$row['Type']}");
         }
         $props[$row['Field']] = $checks;
     }
     $schema = $this->registry->construct('check', 'schema', ['props' => $props]);
     return $schema;
 }
示例#5
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;
 }
示例#6
0
文件: Money.php 项目: coolms/money
 /**
  * {@inheritDoc}
  */
 public function unserialize($serialized)
 {
     $unserialized = unserialize($serialized);
     $this->amount = Decimal::create($unserialized['amount']);
     $this->currency = unserialize($unserialized['currency']);
 }
示例#7
0
 /**
  * Get item price (with or without VAT based on _pricesWithVat setting)
  *
  * @param CartItemInterface item
  * @param int quantity (null to use item quantity)
  * @return void
  */
 public function getItemPrice(CartItemInterface $item, $quantity = null)
 {
     $price = Decimal::create($item->getUnitPrice());
     // when listed as gross
     if ($this->_pricesWithVat) {
         $price = $price->mul(Decimal::fromFloat(1 + (double) $item->getTaxRate() / 100));
     }
     return $price->mul(Decimal::fromInteger(is_null($quantity) ? $item->getCartQuantity() : (int) $quantity))->round($this->_roundingDecimals);
 }
示例#8
0
文件: Math.php 项目: coolms/money
 /**
  * BCRound implementation
  *
  * @param number|Decimal $number
  * @param int $precision
  * @param int $roundingMode
  * @return Decimal
  * @throws InvalidArgumentException
  */
 public static final function bcround($number, $precision, $roundingMode = self::ROUND_HALF_UP)
 {
     if ($number instanceof Decimal) {
         $number = (string) $number;
     }
     $precision = self::normalizePrecision($precision);
     if (self::isNotDecimalString($number)) {
         return Decimal::create($number, $precision);
     }
     if ($roundingMode === self::ROUND_HALF_UP) {
         return Decimal::create(self::bcRoundHalfUp($number, $precision), $precision);
     }
     $firstDecimalAfterPrecision = self::getFirstDecimalAfterPrecision($number, $precision);
     if ($firstDecimalAfterPrecision === self::HALF) {
         $result = self::roundTied($number, $precision, $roundingMode);
     } else {
         $result = self::roundNotTied($firstDecimalAfterPrecision, $number, $precision);
     }
     /*
      * Arbitrary precision arithmetic allows for '-0.0' which is not equal to '0.0' if compared with bccomp.
      * We have no use for this behaviour, so negative numbers have to be checked if they are minus zero,
      * so we can convert them into unsigned zero and return that.
      */
     $result = self::normalizeZero($result, $precision);
     return Decimal::create($result, $precision);
 }
示例#9
0
 function dataEqual()
 {
     return [[true, 1, 1], [false, 1, 2, 'equal.intNotEqual'], [true, 1, 1.0], [true, 1.0, 1.0], [false, 1.0, 2, 'equal.doubleNotEqual'], [true, -1, -1], [true, Decimal::create("1"), Decimal::create("1")], [false, Decimal::create("2"), Decimal::create("1"), 'equal.decimalNotEqual'], [true, new \DateTime('2015-01-01'), new \DateTime('2015-01-01')], [true, new \DateTime('2015-01-01 14:00', new \DateTimeZone('Australia/Melbourne')), new \DateTime('2015-01-01 03:00', new \DateTimeZone('UTC'))], [false, new \DateTime('2015-01-01 01:00'), new \DateTime('2015-01-01 00:00'), 'equal.dateNotEqual'], [true, 'foo', 'foo'], [false, 'foo', 'bar', 'equal.stringNotEqual'], [true, \Normalizer::normalize('zwölf', \Normalizer::FORM_C), \Normalizer::normalize('zwölf', \Normalizer::FORM_D)], [true, true, true], [true, false, false], [false, true, false]];
 }
示例#10
0
文件: Money.php 项目: werkint/money
 /**
  * {@inheritdoc}
  */
 public function isNegative()
 {
     return -1 == $this->amount->comp(Decimal::create(0), 10);
 }