4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Intl\NumberFormatter
;
14 use Symfony\Component\Intl\Exception\NotImplementedException
;
15 use Symfony\Component\Intl\Exception\MethodNotImplementedException
;
16 use Symfony\Component\Intl\Exception\MethodArgumentNotImplementedException
;
17 use Symfony\Component\Intl\Exception\MethodArgumentValueNotImplementedException
;
18 use Symfony\Component\Intl\Globals\IntlGlobals
;
19 use Symfony\Component\Intl\Intl
;
20 use Symfony\Component\Intl\Locale\Locale
;
23 * Replacement for PHP's native {@link \NumberFormatter} class.
25 * The only methods currently supported in this class are:
27 * - {@link __construct}
29 * - {@link formatCurrency}
31 * - {@link getAttribute}
32 * - {@link getErrorCode}
33 * - {@link getErrorMessage}
36 * - {@link setAttribute}
38 * @author Eriksen Costa <eriksen.costa@infranology.com.br>
39 * @author Bernhard Schussek <bschussek@gmail.com>
43 /* Format style constants */
44 const PATTERN_DECIMAL
= 0;
52 const PATTERN_RULEBASED
= 9;
54 const DEFAULT_STYLE
= 1;
56 /* Format type constants */
57 const TYPE_DEFAULT
= 0;
60 const TYPE_DOUBLE
= 3;
61 const TYPE_CURRENCY
= 4;
63 /* Numeric attribute constants */
64 const PARSE_INT_ONLY
= 0;
65 const GROUPING_USED
= 1;
66 const DECIMAL_ALWAYS_SHOWN
= 2;
67 const MAX_INTEGER_DIGITS
= 3;
68 const MIN_INTEGER_DIGITS
= 4;
69 const INTEGER_DIGITS
= 5;
70 const MAX_FRACTION_DIGITS
= 6;
71 const MIN_FRACTION_DIGITS
= 7;
72 const FRACTION_DIGITS
= 8;
74 const GROUPING_SIZE
= 10;
75 const ROUNDING_MODE
= 11;
76 const ROUNDING_INCREMENT
= 12;
77 const FORMAT_WIDTH
= 13;
78 const PADDING_POSITION
= 14;
79 const SECONDARY_GROUPING_SIZE
= 15;
80 const SIGNIFICANT_DIGITS_USED
= 16;
81 const MIN_SIGNIFICANT_DIGITS
= 17;
82 const MAX_SIGNIFICANT_DIGITS
= 18;
83 const LENIENT_PARSE
= 19;
85 /* Text attribute constants */
86 const POSITIVE_PREFIX
= 0;
87 const POSITIVE_SUFFIX
= 1;
88 const NEGATIVE_PREFIX
= 2;
89 const NEGATIVE_SUFFIX
= 3;
90 const PADDING_CHARACTER
= 4;
91 const CURRENCY_CODE
= 5;
92 const DEFAULT_RULESET
= 6;
93 const PUBLIC_RULESETS
= 7;
95 /* Format symbol constants */
96 const DECIMAL_SEPARATOR_SYMBOL
= 0;
97 const GROUPING_SEPARATOR_SYMBOL
= 1;
98 const PATTERN_SEPARATOR_SYMBOL
= 2;
99 const PERCENT_SYMBOL
= 3;
100 const ZERO_DIGIT_SYMBOL
= 4;
101 const DIGIT_SYMBOL
= 5;
102 const MINUS_SIGN_SYMBOL
= 6;
103 const PLUS_SIGN_SYMBOL
= 7;
104 const CURRENCY_SYMBOL
= 8;
105 const INTL_CURRENCY_SYMBOL
= 9;
106 const MONETARY_SEPARATOR_SYMBOL
= 10;
107 const EXPONENTIAL_SYMBOL
= 11;
108 const PERMILL_SYMBOL
= 12;
109 const PAD_ESCAPE_SYMBOL
= 13;
110 const INFINITY_SYMBOL
= 14;
111 const NAN_SYMBOL
= 15;
112 const SIGNIFICANT_DIGIT_SYMBOL
= 16;
113 const MONETARY_GROUPING_SEPARATOR_SYMBOL
= 17;
115 /* Rounding mode values used by NumberFormatter::setAttribute() with NumberFormatter::ROUNDING_MODE attribute */
116 const ROUND_CEILING
= 0;
117 const ROUND_FLOOR
= 1;
118 const ROUND_DOWN
= 2;
120 const ROUND_HALFEVEN
= 4;
121 const ROUND_HALFDOWN
= 5;
122 const ROUND_HALFUP
= 6;
124 /* Pad position values used by NumberFormatter::setAttribute() with NumberFormatter::PADDING_POSITION attribute */
125 const PAD_BEFORE_PREFIX
= 0;
126 const PAD_AFTER_PREFIX
= 1;
127 const PAD_BEFORE_SUFFIX
= 2;
128 const PAD_AFTER_SUFFIX
= 3;
131 * The error code from the last operation
135 protected $errorCode = IntlGlobals
::U_ZERO_ERROR
;
138 * The error message from the last operation
142 protected $errorMessage = 'U_ZERO_ERROR';
150 * Default values for the en locale
154 private $attributes = array(
155 self
::FRACTION_DIGITS
=> 0,
156 self
::GROUPING_USED
=> 1,
157 self
::ROUNDING_MODE
=> self
::ROUND_HALFEVEN
161 * Holds the initialized attributes code
165 private $initializedAttributes = array();
168 * The supported styles to the constructor $styles argument
172 private static $supportedStyles = array(
173 'CURRENCY' => self
::CURRENCY
,
174 'DECIMAL' => self
::DECIMAL
178 * Supported attributes to the setAttribute() $attr argument
182 private static $supportedAttributes = array(
183 'FRACTION_DIGITS' => self
::FRACTION_DIGITS
,
184 'GROUPING_USED' => self
::GROUPING_USED
,
185 'ROUNDING_MODE' => self
::ROUNDING_MODE
189 * The available rounding modes for setAttribute() usage with
190 * NumberFormatter::ROUNDING_MODE. NumberFormatter::ROUND_DOWN
191 * and NumberFormatter::ROUND_UP does not have a PHP only equivalent
195 private static $roundingModes = array(
196 'ROUND_HALFEVEN' => self
::ROUND_HALFEVEN
,
197 'ROUND_HALFDOWN' => self
::ROUND_HALFDOWN
,
198 'ROUND_HALFUP' => self
::ROUND_HALFUP
202 * The mapping between NumberFormatter rounding modes to the available
203 * modes in PHP's round() function.
205 * @see http://www.php.net/manual/en/function.round.php
209 private static $phpRoundingMap = array(
210 self
::ROUND_HALFDOWN
=> \PHP_ROUND_HALF_DOWN
,
211 self
::ROUND_HALFEVEN
=> \PHP_ROUND_HALF_EVEN
,
212 self
::ROUND_HALFUP
=> \PHP_ROUND_HALF_UP
216 * The maximum values of the integer type in 32 bit platforms.
220 private static $int32Range = array(
221 'positive' => 2147483647,
222 'negative' => -2147483648
226 * The maximum values of the integer type in 64 bit platforms.
230 private static $int64Range = array(
231 'positive' => 9223372036854775807,
232 'negative' => -9223372036854775808
238 * @param string $locale The locale code. The only currently supported locale is "en".
239 * @param int $style Style of the formatting, one of the format style constants.
240 * The only supported styles are NumberFormatter::DECIMAL
241 * and NumberFormatter::CURRENCY.
242 * @param string $pattern Not supported. A pattern string in case $style is NumberFormat::PATTERN_DECIMAL or
243 * NumberFormat::PATTERN_RULEBASED. It must conform to the syntax
244 * described in the ICU DecimalFormat or ICU RuleBasedNumberFormat documentation
246 * @see http://www.php.net/manual/en/numberformatter.create.php
247 * @see http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details
248 * @see http://www.icu-project.org/apiref/icu4c/classRuleBasedNumberFormat.html#_details
250 * @throws MethodArgumentValueNotImplementedException When $locale different than "en" is passed
251 * @throws MethodArgumentValueNotImplementedException When the $style is not supported
252 * @throws MethodArgumentNotImplementedException When the pattern value is different than null
254 public function __construct($locale = 'en', $style = null, $pattern = null)
256 if ('en' != $locale) {
257 throw new MethodArgumentValueNotImplementedException(__METHOD__
, 'locale', $locale, 'Only the locale "en" is supported');
260 if (!in_array($style, self
::$supportedStyles)) {
261 $message = sprintf('The available styles are: %s.', implode(', ', array_keys(self
::$supportedStyles)));
262 throw new MethodArgumentValueNotImplementedException(__METHOD__
, 'style', $style, $message);
265 if (null !== $pattern) {
266 throw new MethodArgumentNotImplementedException(__METHOD__
, 'pattern');
269 $this->style
= $style;
273 * Static constructor.
275 * @param string $locale The locale code. The only supported locale is "en".
276 * @param int $style Style of the formatting, one of the format style constants.
277 * The only currently supported styles are NumberFormatter::DECIMAL
278 * and NumberFormatter::CURRENCY.
279 * @param string $pattern Not supported. A pattern string in case $style is NumberFormat::PATTERN_DECIMAL or
280 * NumberFormat::PATTERN_RULEBASED. It must conform to the syntax
281 * described in the ICU DecimalFormat or ICU RuleBasedNumberFormat documentation
283 * @return NumberFormatter
285 * @see http://www.php.net/manual/en/numberformatter.create.php
286 * @see http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details
287 * @see http://www.icu-project.org/apiref/icu4c/classRuleBasedNumberFormat.html#_details
289 * @throws MethodArgumentValueNotImplementedException When $locale different than "en" is passed
290 * @throws MethodArgumentValueNotImplementedException When the $style is not supported
291 * @throws MethodArgumentNotImplementedException When the pattern value is different than null
293 public static function create($locale = 'en', $style = null, $pattern = null)
295 return new self($locale, $style, $pattern);
299 * Format a currency value
301 * @param float $value The numeric currency value
302 * @param string $currency The 3-letter ISO 4217 currency code indicating the currency to use
304 * @return string The formatted currency value
306 * @see http://www.php.net/manual/en/numberformatter.formatcurrency.php
307 * @see http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm
309 public function formatCurrency($value, $currency)
311 if ($this->style
== self
::DECIMAL
) {
312 return $this->format($value);
315 $symbol = Intl
::getCurrencyBundle()->getCurrencySymbol($currency, 'en');
316 $fractionDigits = Intl
::getCurrencyBundle()->getFractionDigits($currency);
318 $value = $this->roundCurrency($value, $currency);
326 $value = $this->formatNumber($value, $fractionDigits);
328 $ret = $symbol.$value;
330 return $negative ? '('.$ret.')' : $ret;
336 * @param number $value The value to format
337 * @param int $type Type of the formatting, one of the format type constants.
338 * Only type NumberFormatter::TYPE_DEFAULT is currently supported.
340 * @return Boolean|string The formatted value or false on error
342 * @see http://www.php.net/manual/en/numberformatter.format.php
344 * @throws NotImplementedException If the method is called with the class $style 'CURRENCY'
345 * @throws MethodArgumentValueNotImplementedException If the $type is different than TYPE_DEFAULT
347 public function format($value, $type = self
::TYPE_DEFAULT
)
349 // The original NumberFormatter does not support this format type
350 if ($type == self
::TYPE_CURRENCY
) {
351 trigger_error(__METHOD__
.'(): Unsupported format type '.$type, \E_USER_WARNING
);
356 if ($this->style
== self
::CURRENCY
) {
357 throw new NotImplementedException(sprintf(
358 '%s() method does not support the formatting of currencies (instance with CURRENCY style). %s',
359 __METHOD__
, NotImplementedException
::INTL_INSTALL_MESSAGE
363 // Only the default type is supported.
364 if ($type != self
::TYPE_DEFAULT
) {
365 throw new MethodArgumentValueNotImplementedException(__METHOD__
, 'type', $type, 'Only TYPE_DEFAULT is supported');
368 $fractionDigits = $this->getAttribute(self
::FRACTION_DIGITS
);
370 $value = $this->round($value, $fractionDigits);
371 $value = $this->formatNumber($value, $fractionDigits);
373 // behave like the intl extension
380 * Returns an attribute value
382 * @param int $attr An attribute specifier, one of the numeric attribute constants
384 * @return Boolean|int The attribute value on success or false on error
386 * @see http://www.php.net/manual/en/numberformatter.getattribute.php
388 public function getAttribute($attr)
390 return isset($this->attributes
[$attr]) ? $this->attributes
[$attr] : null;
394 * Returns formatter's last error code. Always returns the U_ZERO_ERROR class constant value
396 * @return int The error code from last formatter call
398 * @see http://www.php.net/manual/en/numberformatter.geterrorcode.php
400 public function getErrorCode()
402 return $this->errorCode
;
406 * Returns formatter's last error message. Always returns the U_ZERO_ERROR_MESSAGE class constant value
408 * @return string The error message from last formatter call
410 * @see http://www.php.net/manual/en/numberformatter.geterrormessage.php
412 public function getErrorMessage()
414 return $this->errorMessage
;
418 * Returns the formatter's locale
420 * The parameter $type is currently ignored.
422 * @param int $type Not supported. The locale name type to return (Locale::VALID_LOCALE or Locale::ACTUAL_LOCALE)
424 * @return string The locale used to create the formatter. Currently always
427 * @see http://www.php.net/manual/en/numberformatter.getlocale.php
429 public function getLocale($type = Locale
::ACTUAL_LOCALE
)
435 * Not supported. Returns the formatter's pattern
437 * @return Boolean|string The pattern string used by the formatter or false on error
439 * @see http://www.php.net/manual/en/numberformatter.getpattern.php
441 * @throws MethodNotImplementedException
443 public function getPattern()
445 throw new MethodNotImplementedException(__METHOD__
);
449 * Not supported. Returns a formatter symbol value
451 * @param int $attr A symbol specifier, one of the format symbol constants
453 * @return Boolean|string The symbol value or false on error
455 * @see http://www.php.net/manual/en/numberformatter.getsymbol.php
457 * @throws MethodNotImplementedException
459 public function getSymbol($attr)
461 throw new MethodNotImplementedException(__METHOD__
);
465 * Not supported. Returns a formatter text attribute value
467 * @param int $attr An attribute specifier, one of the text attribute constants
469 * @return Boolean|string The attribute value or false on error
471 * @see http://www.php.net/manual/en/numberformatter.gettextattribute.php
473 * @throws MethodNotImplementedException
475 public function getTextAttribute($attr)
477 throw new MethodNotImplementedException(__METHOD__
);
481 * Not supported. Parse a currency number
483 * @param string $value The value to parse
484 * @param string $currency Parameter to receive the currency name (reference)
485 * @param int $position Offset to begin the parsing on return this value will hold the offset at which the parsing ended
487 * @return Boolean|string The parsed numeric value of false on error
489 * @see http://www.php.net/manual/en/numberformatter.parsecurrency.php
491 * @throws MethodNotImplementedException
493 public function parseCurrency($value, &$currency, &$position = null)
495 throw new MethodNotImplementedException(__METHOD__
);
501 * @param string $value The value to parse
502 * @param int $type Type of the formatting, one of the format type constants.
503 * The only currently supported types are NumberFormatter::TYPE_DOUBLE,
504 * NumberFormatter::TYPE_INT32 and NumberFormatter::TYPE_INT64.
505 * @param int $position Not supported. Offset to begin the parsing on return this value will hold the offset at which the parsing ended
507 * @return Boolean|string The parsed value of false on error
509 * @see http://www.php.net/manual/en/numberformatter.parse.php
511 * @throws MethodArgumentNotImplementedException When $position different than null, behavior not implemented
513 public function parse($value, $type = self
::TYPE_DOUBLE
, &$position = null)
515 if ($type == self
::TYPE_DEFAULT
|| $type == self
::TYPE_CURRENCY
) {
516 trigger_error(__METHOD__
.'(): Unsupported format type '.$type, \E_USER_WARNING
);
521 // We don't calculate the position when parsing the value
522 if (null !== $position) {
523 throw new MethodArgumentNotImplementedException(__METHOD__
, 'position');
526 preg_match('/^([^0-9\-]{0,})(.*)/', $value, $matches);
528 // Any string before the numeric value causes error in the parsing
529 if (isset($matches[1]) && !empty($matches[1])) {
530 IntlGlobals
::setError(IntlGlobals
::U_PARSE_ERROR
, 'Number parsing failed');
531 $this->errorCode
= IntlGlobals
::getErrorCode();
532 $this->errorMessage
= IntlGlobals
::getErrorMessage();
537 // Remove everything that is not number or dot (.)
538 $value = preg_replace('/[^0-9\.\-]/', '', $value);
539 $value = $this->convertValueDataType($value, $type);
541 // behave like the intl extension
550 * @param int $attr An attribute specifier, one of the numeric attribute constants.
551 * The only currently supported attributes are NumberFormatter::FRACTION_DIGITS,
552 * NumberFormatter::GROUPING_USED and NumberFormatter::ROUNDING_MODE.
553 * @param int $value The attribute value. The only currently supported rounding modes are
554 * NumberFormatter::ROUND_HALFEVEN, NumberFormatter::ROUND_HALFDOWN and
555 * NumberFormatter::ROUND_HALFUP.
557 * @return Boolean true on success or false on failure
559 * @see http://www.php.net/manual/en/numberformatter.setattribute.php
561 * @throws MethodArgumentValueNotImplementedException When the $attr is not supported
562 * @throws MethodArgumentValueNotImplementedException When the $value is not supported
564 public function setAttribute($attr, $value)
566 if (!in_array($attr, self
::$supportedAttributes)) {
568 'The available attributes are: %s',
569 implode(', ', array_keys(self
::$supportedAttributes))
572 throw new MethodArgumentValueNotImplementedException(__METHOD__
, 'attr', $value, $message);
575 if (self
::$supportedAttributes['ROUNDING_MODE'] == $attr && $this->isInvalidRoundingMode($value)) {
577 'The supported values for ROUNDING_MODE are: %s',
578 implode(', ', array_keys(self
::$roundingModes))
581 throw new MethodArgumentValueNotImplementedException(__METHOD__
, 'attr', $value, $message);
584 if (self
::$supportedAttributes['GROUPING_USED'] == $attr) {
585 $value = $this->normalizeGroupingUsedValue($value);
588 if (self
::$supportedAttributes['FRACTION_DIGITS'] == $attr) {
589 $value = $this->normalizeFractionDigitsValue($value);
592 $this->attributes
[$attr] = $value;
593 $this->initializedAttributes
[$attr] = true;
599 * Not supported. Set the formatter's pattern
601 * @param string $pattern A pattern string in conformance with the ICU DecimalFormat documentation
603 * @return Boolean true on success or false on failure
605 * @see http://www.php.net/manual/en/numberformatter.setpattern.php
606 * @see http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details
608 * @throws MethodNotImplementedException
610 public function setPattern($pattern)
612 throw new MethodNotImplementedException(__METHOD__
);
616 * Not supported. Set the formatter's symbol
618 * @param int $attr A symbol specifier, one of the format symbol constants
619 * @param string $value The value for the symbol
621 * @return Boolean true on success or false on failure
623 * @see http://www.php.net/manual/en/numberformatter.setsymbol.php
625 * @throws MethodNotImplementedException
627 public function setSymbol($attr, $value)
629 throw new MethodNotImplementedException(__METHOD__
);
633 * Not supported. Set a text attribute
635 * @param int $attr An attribute specifier, one of the text attribute constants
636 * @param int $value The attribute value
638 * @return Boolean true on success or false on failure
640 * @see http://www.php.net/manual/en/numberformatter.settextattribute.php
642 * @throws MethodNotImplementedException
644 public function setTextAttribute($attr, $value)
646 throw new MethodNotImplementedException(__METHOD__
);
650 * Set the error to the default U_ZERO_ERROR
652 protected function resetError()
654 IntlGlobals
::setError(IntlGlobals
::U_ZERO_ERROR
);
655 $this->errorCode
= IntlGlobals
::getErrorCode();
656 $this->errorMessage
= IntlGlobals
::getErrorMessage();
660 * Rounds a currency value, applying increment rounding if applicable
662 * When a currency have a rounding increment, an extra round is made after the first one. The rounding factor is
663 * determined in the ICU data and is explained as of:
665 * "the rounding increment is given in units of 10^(-fraction_digits)"
667 * The only actual rounding data as of this writing, is CHF.
669 * @param float $value The numeric currency value
670 * @param string $currency The 3-letter ISO 4217 currency code indicating the currency to use
672 * @return string The rounded numeric currency value
674 * @see http://en.wikipedia.org/wiki/Swedish_rounding
675 * @see http://www.docjar.com/html/api/com/ibm/icu/util/Currency.java.html#1007
677 private function roundCurrency($value, $currency)
679 $fractionDigits = Intl
::getCurrencyBundle()->getFractionDigits($currency);
680 $roundingIncrement = Intl
::getCurrencyBundle()->getRoundingIncrement($currency);
682 // Round with the formatter rounding mode
683 $value = $this->round($value, $fractionDigits);
686 if (0 < $roundingIncrement && 0 < $fractionDigits) {
687 $roundingFactor = $roundingIncrement / pow(10, $fractionDigits);
688 $value = round($value / $roundingFactor) * $roundingFactor;
697 * @param integer|float $value The value to round
698 * @param int $precision The number of decimal digits to round to
700 * @return integer|float The rounded value
702 private function round($value, $precision)
704 $precision = $this->getUnitializedPrecision($value, $precision);
706 $roundingMode = self
::$phpRoundingMap[$this->getAttribute(self
::ROUNDING_MODE
)];
707 $value = round($value, $precision, $roundingMode);
715 * @param integer|float $value The numeric value to format
716 * @param int $precision The number of decimal digits to use
718 * @return string The formatted number
720 private function formatNumber($value, $precision)
722 $precision = $this->getUnitializedPrecision($value, $precision);
724 return number_format($value, $precision, '.', $this->getAttribute(self
::GROUPING_USED
) ? ',' : '');
728 * Returns the precision value if the DECIMAL style is being used and the FRACTION_DIGITS attribute is unitialized.
730 * @param integer|float $value The value to get the precision from if the FRACTION_DIGITS attribute is unitialized
731 * @param int $precision The precision value to returns if the FRACTION_DIGITS attribute is initialized
733 * @return int The precision value
735 private function getUnitializedPrecision($value, $precision)
737 if ($this->style
== self
::CURRENCY
) {
741 if (!$this->isInitializedAttribute(self
::FRACTION_DIGITS
)) {
742 preg_match('/.*\.(.*)/', (string) $value, $digits);
743 if (isset($digits[1])) {
744 $precision = strlen($digits[1]);
752 * Check if the attribute is initialized (value set by client code).
754 * @param string $attr The attribute name
756 * @return Boolean true if the value was set by client, false otherwise
758 private function isInitializedAttribute($attr)
760 return isset($this->initializedAttributes
[$attr]);
764 * Returns the numeric value using the $type to convert to the right data type.
766 * @param mixed $value The value to be converted
767 * @param int $type The type to convert. Can be TYPE_DOUBLE (float) or TYPE_INT32 (int)
769 * @return integer|float The converted value
771 private function convertValueDataType($value, $type)
773 if ($type == self
::TYPE_DOUBLE
) {
774 $value = (float) $value;
775 } elseif ($type == self
::TYPE_INT32
) {
776 $value = $this->getInt32Value($value);
777 } elseif ($type == self
::TYPE_INT64
) {
778 $value = $this->getInt64Value($value);
785 * Convert the value data type to int or returns false if the value is out of the integer value range.
787 * @param mixed $value The value to be converted
789 * @return int The converted value
791 private function getInt32Value($value)
793 if ($value > self
::$int32Range['positive'] || $value < self
::$int32Range['negative']) {
801 * Convert the value data type to int or returns false if the value is out of the integer value range.
803 * @param mixed $value The value to be converted
805 * @return int|float The converted value
807 * @see https://bugs.php.net/bug.php?id=59597 Bug #59597
809 private function getInt64Value($value)
811 if ($value > self
::$int64Range['positive'] || $value < self
::$int64Range['negative']) {
815 if (PHP_INT_SIZE
!== 8 && ($value > self
::$int32Range['positive'] || $value <= self
::$int32Range['negative'])) {
816 // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4
817 // The negative PHP_INT_MAX was being converted to float
819 $value == self
::$int32Range['negative'] &&
821 (version_compare(PHP_VERSION
, '5.4.0', '<') && version_compare(PHP_VERSION
, '5.3.14', '>=')) ||
822 version_compare(PHP_VERSION
, '5.4.4', '>=')
828 return (float) $value;
831 if (PHP_INT_SIZE
=== 8) {
832 // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4
833 // A 32 bit integer was being generated instead of a 64 bit integer
835 ($value > self
::$int32Range['positive'] || $value < self
::$int32Range['negative']) &&
837 (version_compare(PHP_VERSION
, '5.3.14', '<')) ||
838 (version_compare(PHP_VERSION
, '5.4.0', '>=') && version_compare(PHP_VERSION
, '5.4.4', '<'))
841 $value = (-2147483648 - ($value %
-2147483648)) * ($value / abs($value));
849 * Check if the rounding mode is invalid.
851 * @param int $value The rounding mode value to check
853 * @return Boolean true if the rounding mode is invalid, false otherwise
855 private function isInvalidRoundingMode($value)
857 if (in_array($value, self
::$roundingModes, true)) {
865 * Returns the normalized value for the GROUPING_USED attribute. Any value that can be converted to int will be
866 * cast to Boolean and then to int again. This way, negative values are converted to 1 and string values to 0.
868 * @param mixed $value The value to be normalized
870 * @return int The normalized value for the attribute (0 or 1)
872 private function normalizeGroupingUsedValue($value)
874 return (int) (Boolean
) (int) $value;
878 * Returns the normalized value for the FRACTION_DIGITS attribute. The value is converted to int and if negative,
879 * the returned value will be 0.
881 * @param mixed $value The value to be normalized
883 * @return int The normalized value for the attribute
885 private function normalizeFractionDigitsValue($value)
887 $value = (int) $value;
889 return (0 > $value) ? 0 : $value;