NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #41 most downloaded on Packagist
Arbitrary-precision arithmetic library
Last release 26 days ago
12 Sep 2026
Ships fairly regularly
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
12 years old
80 releases · first in 2014
No changes from version 0.20.0 .
First stable release 🎉
No changes from version 0.20.0.
The following breaking change only affects you if you specifically catch DivisionByZeroException around calls to of() or to any method accepting strin…
💥 Breaking changes
UnsupportedPlatformException has been removed, catch PlatformException insteadThe following breaking change only affects you if you specifically catch DivisionByZeroException around calls to of() or to any method accepting strings:
of() now throws NumberFormatException instead of DivisionByZeroException when the string is a fraction with a denominator of zero, such as '2/0'✨ New features
parse() and parseNullable() safely parse untrusted input, by restricting the allowed syntax and limiting the number of digitsNumberSyntax lists the syntax features that parse() can accept, with constants for the most common combinations🐛 Bug fixes
of() no longer throws PlatformException on malformed input with many digits, crafted to trigger heavy backtracking in its parser; such input now throws NumberFormatException as documented👌 Improvements
NumberFormatException messages now escape control and non-ASCII characters, and truncate values longer than 40 bytes, instead of copying the raw input into the messageOne column per quarter.
Exception class UnsupportedPlatformException is deprecated; catch PlatformException instead
✨ New features
PlatformException (replaces UnsupportedPlatformException)PlatformException is now thrown when preg_match() fails due to improper PHP configurationPlatformException is now thrown when PHP_INT_SIZE is an unsupported value🗑️ Deprecations
UnsupportedPlatformException is deprecated; catch PlatformException insteadNew rounding mode: RoundingMode::HalfOdd
✨ New features
RoundingMode::HalfOddRoundingMode::fromNativeRoundingMode() converts from a native PHP RoundingMode enum (PHP 8.4+)The following breaking change only affects you if you're using named arguments:
💥 Breaking changes
The following breaking change only affects you if you're using named arguments:
BigInteger::fromBytes() now uses $bytes as the parameter name🐛 Bug fixes
of() no longer accepts a trailing newline (\n) in the input string; such input now throws NumberFormatExceptionof() now consistently throws NumberFormatException for exponents too large to process, instead of IntegerOverflowException in some casesBigInteger::fromBase() now reports the invalid character with its original case in the NumberFormatException message, instead of lower-casing it⚡️ Performance improvements
BigInteger::gcd() no longer exhausts memory on large inputs when the GMP extension is not installedBigInteger::modInverse() no longer exhausts memory on large inputs, and is faster when the GMP extension is not installed👌 Static analysis improvements
nthRoot()'s $n is now positive-intBigInteger::toBase(), toArbitraryBase(), toBytes() and BigRational::toRepeatingDecimalString() now return non-empty-stringNew methods: BigInteger::nthRoot() and BigDecimal::nthRoot() compute the nth root of a number ( #113 by @Pablo1Gustavo )
✨ New features
BigInteger::nthRoot() and BigDecimal::nthRoot() compute the nth root of a number (#113 by @Pablo1Gustavo)More precise float approximations in BigRational::toFloat()
👌 Improvements
float approximations in BigRational::toFloat()Deprecated method BigDecimal::hasNonZeroFractionalPart() has been removed, use ! $number->getFractionalPart()->isZero() instead
💥 Breaking changes
BigDecimal::hasNonZeroFractionalPart() has been removed, use ! $number->getFractionalPart()->isZero() instead@internal✨ Compatibility improvements
BigDecimal::fromFloatExact() now supports 32-bit PHP💥 Breaking changes
BigDecimal::hasNonZeroFractionalPart() has been removed, use ! $number->getFractionalPart()->isZero() instead@internal✨ Compatibility improvements
BigDecimal::fromFloatExact() now supports 32-bit PHPNew methods to create a BigDecimal from a float value:
✨ New features
New methods to create a BigDecimal from a float value:
BigDecimal::fromFloatExact()BigDecimal::fromFloatShortest()Add @return non-empty-string to toString() , jsonSerialize() and __toString() ( #111 by @vudaltsov )
👌 Improvements
@return non-empty-string to toString(), jsonSerialize() and __toString() (#111 by @vudaltsov)Deprecated method BigRational::simplified() has been removed, as it is now a no-op
💥 Breaking changes
BigInteger::getLowestSetBit() now returns null instead of -1 when the number is zeroBigRational::simplified() has been removed, as it is now a no-op✨ New features
BigDecimal::getIntegralPart() returns the integral part as BigInteger (this method existed with a different signature in version 0.14, and was removed in 0.15)BigDecimal::getFractionalPart() returns the fractional part as BigDecimal (this method existed with a different signature and meaning in version 0.14, and was removed in 0.15)🗑️ Deprecations
BigDecimal::hasNonZeroFractionalPart() is deprecated, use ->getFractionalPart()->isZero() insteadThe following breaking changes only affect you if you're using named arguments:
💥 Breaking changes
of() and arithmetic methods, use of((string) $float) to get the same behaviour as before (#105)BigRational is now always simplified to lowest terms: all operations, including of() and ofFraction(), now return a fraction in its simplest form (e.g. 2/3 instead of 4/6)BigDecimal::dividedBy() now requires the $scale parameterBigInteger::sqrt() and BigDecimal::sqrt() now default to RoundingMode::Unnecessary, explicitly pass RoundingMode::Down to get the previous behaviourBigInteger::mod() now uses Euclidean modulo semantics: the modulus must be strictly positive, and the result is always non-negative; this change aligns with Java's BigInteger.mod() behaviourBigInteger::mod(), modInverse() and modPow() now throw InvalidArgumentException (instead of NegativeNumberException) for negative modulus/exponent argumentsMathException is now an interface instead of a classBigDecimal::getPrecision() now returns 1 for zero valuesBigNumber::min(), max() and sum() now throw an ArgumentCountError when called with no arguments (previously threw InvalidArgumentException)BigInteger::randomBits() and randomRange() now throw RandomSourceException when random byte generation fails or returns invalid dataDeprecated API elements removed:
BigInteger::testBit() has been removed, use isBitSet() insteadBigInteger::gcdMultiple() has been removed, use gcdAll() insteadBigDecimal::exactlyDividedBy() has been removed, use dividedByExact() insteadBigDecimal::getIntegralPart() has been removed (will be re-introduced as returning BigInteger in 0.16)BigDecimal::getFractionalPart() has been removed (will be re-introduced as returning BigDecimal with a different meaning in 0.16)BigDecimal::stripTrailingZeros() has been removed, use strippedOfTrailingZeros() insteadBigRational::nd() has been removed, use ofFraction() insteadBigRational::quotient() has been removed, use getIntegralPart() insteadBigRational::remainder() has been removed, use $number->getNumerator()->remainder($number->getDenominator()) insteadBigRational::quotientAndRemainder() has been removed, use $number->getNumerator()->quotientAndRemainder($number->getDenominator()) insteadRoundingMode upper snake case constants (e.g. HALF_UP) have been removed, use the pascal case version (e.g. HalfUp) insteadThe following breaking changes only affect you if you're using named arguments:
BigInteger::mod() now uses $modulus as the parameter nameBigInteger::modInverse() now uses $modulus as the parameter nameBigInteger::modPow() now uses $exponent and $modulus as parameter namesBigInteger::shiftedLeft() now uses $bits as the parameter nameBigInteger::shiftedRight() now uses $bits as the parameter nameBigInteger::isBitSet() now uses $bitIndex as the parameter nameBigInteger::randomBits() now uses $bitCount as the parameter nameBigDecimal::withPointMovedLeft() now uses $places as the parameter nameBigDecimal::withPointMovedRight() now uses $places as the parameter nameThe following breaking changes are unlikely to affect you:
DivisionByZeroException::modulusMustNotBeZero() has been renamed to zeroModulus()DivisionByZeroException::denominatorMustNotBeZero() has been renamed to zeroDenominator()IntegerOverflowException::toIntOverflow() has been renamed to integerOutOfRange()RoundingNecessaryException::roundingNecessary() has been removed🗑️ Deprecations
BigRational::simplified() is deprecated, as it is now a no-op✨ New features
BigInteger::power(), BigDecimal::power() and BigRational::power() no longer enforce an exponent limitBigInteger::shiftedLeft() and BigInteger::shiftedRight() no longer enforce a limit on the number of bitsBigRational::power() now accepts negative exponentsInvalidArgumentException for invalid argument errorsNoInverseException for modular inverse errorsRandomSourceException for random source errors👌 Improvements
Method BigInteger::testBit() is deprecated, use isBitSet() instead
🗑️ Deprecations
BigInteger::testBit() is deprecated, use isBitSet() instead✨ New features
BigInteger::isBitSet() (replaces testBit())BigNumber::toString() (alias of magic method __toString())👌 Improvements
BigRational comparison methods@throws annotationsclamp() is now available on the base BigNumber class
✨ New features
clamp() is now available on the base BigNumber class👌 Improvements
@throws exception documentationNot passing a $scale to BigDecimal::dividedBy() is deprecated; `$scale` will be required in 0.15
🗑️ Deprecations
$scale to BigDecimal::dividedBy() is deprecated; $scale will be required in 0.15👌 Improvements
BigRational::toFloat() never returns NAN anymoreNot passing a rounding mode to BigInteger::sqrt() and BigDecimal::sqrt() triggers a deprecation notice: the default rounding mode will change from `Do…
🗑️ Deprecations
BigInteger::sqrt() and BigDecimal::sqrt() triggers a deprecation notice: the default rounding mode will change from Down to Unnecessary in 0.15✨ New features
BigInteger::sqrt() and BigDecimal::sqrt() now support roundingabs() and negated() methods are now available on the base BigNumber class👌 Improvements
BigInteger::(from|to)ArbitraryBase()BigNumber::ofNullable() is now marked as @purePassing a negative modulus to BigInteger::mod() is deprecated to align with Euclidean modulo semantics; it will throw InvalidArgumentException in 0.15
🗑️ Deprecations
BigInteger::mod() is deprecated to align with Euclidean modulo semantics; it will throw InvalidArgumentException in 0.15BigDecimal::stripTrailingZeros() is deprecated, use strippedOfTrailingZeros() instead✨ New features
BigInteger::modPow() now accepts negative basesBigDecimal::strippedOfTrailingZeros() (replaces stripTrailingZeros())👌 Improvements
clamp() methods are now marked as @pureNew method: BigInteger::lcmAll()
✨ New features
BigInteger::lcm()BigInteger::lcmAll()BigRational::toRepeatingDecimalString()🐛 Bug fixes
BigInteger::gcdAll() / gcdMultiple() could return a negative result when used with a single negative numberPassing `float` values to `of()` or arithmetic methods is deprecated and will be removed in 0.15; cast to string explicitly to preserve the previous b…
🗑️ Deprecations
float values to of() or arithmetic methods is deprecated and will be removed in 0.15; cast to string explicitly to preserve the previous behaviour (#105)RoundingMode enum cases through upper snake case (e.g. HALF_UP) is deprecated, use the pascal case version (e.g. HalfUp) insteadBigInteger::gcdMultiple() is deprecated, use gcdAll() insteadBigDecimal::exactlyDividedBy() is deprecated, use dividedByExact() insteadBigDecimal::getIntegralPart() is deprecated (will be removed in 0.15, and re-introduced as returning BigInteger in 0.16)BigDecimal::getFractionalPart() is deprecated (will be removed in 0.15, and re-introduced as returning BigDecimal with a different meaning in 0.16)BigRational::nd() is deprecated, use ofFraction() insteadBigRational::quotient() is deprecated, use getIntegralPart() insteadBigRational::remainder() is deprecated, use $number->getNumerator()->remainder($number->getDenominator()) insteadBigRational::quotientAndRemainder() is deprecated, use $number->getNumerator()->quotientAndRemainder($number->getDenominator()) instead✨ New features
BigInteger::gcdAll() (replaces gcdMultiple())BigRational::clamp()BigRational::ofFraction() (replaces nd())BigRational::getIntegralPart() (replaces quotient())BigRational::getFractionalPart()👌 Improvements
MathException interfaceBigInteger::modInverse() now accepts BigNumber|int|float|string instead of just BigIntegerBigInteger::gcdMultiple() now accepts BigNumber|int|float|string instead of just BigInteger🐛 Bug fixes
BigInteger::clamp() and BigDecimal::clamp() now throw an exception on inverted bounds, instead of returning an incorrect resultNew method: BigNumber::ofNullable() (#94 by @mrkh995)
✨ New features
BigNumber::ofNullable() (#94 by @mrkh995)✨ Compatibility fixes
New methods: BigInteger::clamp() and BigDecimal::clamp() (#96 by @JesterIruka)
✨ New features
BigInteger::clamp() and BigDecimal::clamp() (#96 by @JesterIruka)✨ Improvements
BigNumber classes are now marked as @pure for better static analysis💥 Breaking changes
BigNumber classes are now readonlyBigNumber is now marked as sealed: it must not be extended outside of this packagefinal__toString() methods of BigInteger and BigDecimal are now type-hinted as returning numeric-string instead of string (#90 by @vudaltsov)
✨ Improvements
__toString() methods of BigInteger and BigDecimal are now type-hinted as returning numeric-string instead of string (#90 by @vudaltsov)BigDecimal::ofUnscaledValue() no longer throws an exception if the scale is negative
💥 Breaking changes
BigDecimal::ofUnscaledValue() no longer throws an exception if the scale is negativeMathException now extends RuntimeException instead of Exception; this reverts the change introduced in version 0.11.0 (#82)✨ New features
BigDecimal::ofUnscaledValue() allows a negative scale (and converts the values to create a zero scale number)BigDecimal::getPrecision() Returns the number of significant digits in a decimal number
✨ New features
BigDecimal::getPrecision() Returns the number of significant digits in a decimal numberDivision in NativeCalculator is now faster for small divisors, thanks to @Izumi-kun in #87.
⚡️ Performance improvements
NativeCalculator is now faster for small divisors, thanks to @Izumi-kun in #87.👌 Improvements
RoundingNecessaryException to the @throws annotation of BigNumber::of()BigNumber::of() is now faster, thanks to @SebastienDug in #77.
⚡️ Performance improvements
BigNumber::of() is now faster, thanks to @SebastienDug in #77.The following breaking changes only affect you if you're creating your own BigNumber subclasses:
💥 Breaking changes
RoundingMode is now an enum; if you're type-hinting rounding modes, you need to type-hint against RoundingMode instead of int nowBigNumber classes do not implement the Serializable interface anymore (they use the new custom object serialization mechanism)BigNumber subclasses:
BigNumber::of() is now staticBigNumber has a new abstract method from()public and protected functions of BigNumber are now finalMethods accepting a union of types are now strongly typed *
💥 Breaking changes
MathException now extends Exception instead of RuntimeException<sup>* You may now run into type errors if you were passing Stringable objects to of() or any of the methods
internally calling of(), with strict_types enabled. You can fix this by casting Stringable objects to string
first.</sup>
BigRational::toFloat() now simplifies the fraction before performing division (#73) thanks to @olsavmic
👌 Improvements
BigRational::toFloat() now simplifies the fraction before performing division (#73) thanks to @olsavmicBigInteger::gcdMultiple() returns the GCD of multiple BigInteger numbers
✨ New features
BigInteger::gcdMultiple() returns the GCD of multiple BigInteger numbers💥 Breaking changes - Minimum PHP version is now 7.4
💥 Breaking changes
Support for custom object serialization; this removes a warning on PHP 8.1 due to the Serializable interface being deprecated (#60) thanks @TRowbotham
🚀 Compatibility with PHP 8.1
Serializable interface being deprecated (#60) thanks @TRowbothamIncorrect results could be returned when using the BCMath calculator, with a default scale set with bcscale(), on PHP >= 7.2 (#55).
🐛 Bug fix
bcscale(), on PHP >= 7.2 (#55).BigInteger::not() returns the bitwise NOT value
✨ New features
BigInteger::not() returns the bitwise NOT value🐛 Bug fixes
BigInteger::toBytes() could return an incorrect binary representation for some numbersand(), or(), xor() on BigInteger could return an incorrect result when the GMP extension is not availableDeprecated method BigInteger::powerMod() has been removed - use modPow() instead
👌 Improvements
BigNumber::of() now accepts .123 and 123. formats, both of which return a BigDecimal💥 Breaking changes
BigInteger::powerMod() has been removed - use modPow() insteadBigInteger::parse() has been removed - use fromBase() insteadBigInteger::toBytes() could return an incorrect binary representation for some numbers
🐛 Bug fix
BigInteger::toBytes() could return an incorrect binary representation for some numbersand(), or(), xor() on BigInteger could return an incorrect result when the GMP extension is not availableThis version reintroduces the deprecated BigInteger::parse() method, that has been removed by mistake in version 0.8.9 and should have lasted for the…
🚑 Critical fix
BigInteger::parse() method, that has been removed by mistake in version 0.8.9 and should have lasted for the whole 0.8 release cycle.✨ New features
BigInteger::modInverse() calculates a modular multiplicative inverseBigInteger::fromBytes() creates a BigInteger from a byte stringBigInteger::toBytes() converts a BigInteger to a byte stringBigInteger::randomBits() creates a pseudo-random BigInteger of a given bit lengthBigInteger::randomRange() creates a pseudo-random BigInteger between two bounds💩 Deprecations
BigInteger::powerMod() is now deprecated in favour of modPow()added missing ext-json requirement, due to BigNumber implementing JsonSerializable
🐛 Fixes
ext-json requirement, due to BigNumber implementing JsonSerializable⚡️ Optimizations
BigInteger::remainder()BigInteger::getLowestSetBit() returns the index of the rightmost one bit
✨ New features
BigInteger::getLowestSetBit() returns the index of the rightmost one bitBigInteger::isEven() tests whether the number is even
✨ New features
BigInteger::isEven() tests whether the number is evenBigInteger::isOdd() tests whether the number is oddBigInteger::testBit() tests if a bit is setBigInteger::getBitLength() returns the number of bits in the minimal representation of the numberThis is a maintenance release: no bug fixes, no new features, no breaking changes.
🛠️ Maintenance release
Classes are now annotated for better static analysis with psalm.
This is a maintenance release: no bug fixes, no new features, no breaking changes.
BigInteger::powerMod() performs a power-with-modulo operation. Useful for crypto.
✨ New feature
BigInteger::powerMod() performs a power-with-modulo operation. Useful for crypto.
BigInteger::mod() returns the modulo of two numbers. The *modulo* differs from the *remainder* when the signs of the operands are different.
✨ New feature
BigInteger::mod() returns the modulo of two numbers. The modulo differs from the remainder when the signs of the operands are different.
A few additional optimizations in BigInteger and BigDecimal when one of the operands can be returned as is. Thanks to @tomtomsen in #24.
⚡️ Performance improvements
A few additional optimizations in BigInteger and BigDecimal when one of the operands can be returned as is. Thanks to @tomtomsen in #24.
BigInteger::parse() is now deprecated in favour of fromBase()
🐛 Bug fixes
BigInteger::toBase() could return an empty string for zero values (BCMath & Native calculators only, GMP calculator unaffected)✨ New features
BigInteger::toArbitraryBase() converts a number to an arbitrary base, using a custom alphabetBigInteger::fromArbitraryBase() converts a string in an arbitrary base, using a custom alphabet, back to a numberThese methods can be used as the foundation to convert strings between different bases/alphabets, using BigInteger as an intermediate representation.
💩 Deprecations
BigInteger::parse() is now deprecated in favour of fromBase()BigInteger::fromBase() works the same way as parse(), with 2 minor differences:
$base parameter is required, it does not default to 10NumberFormatException instead of an InvalidArgumentException when the number is malformedSafer conversion from float when using custom locales
Improvements
float when using custom localesNativeCalculator implementation 🚀You can expect at least a 3x performance improvement for common arithmetic operations when using the library on systems without GMP or BCMath; it gets exponentially faster on multiplications with a high number of digits. This is due to calculations now being performed on whole blocks of digits (the block size depending on the platform, 32-bit or 64-bit) instead of digit-by-digit as before.
BigNumber::sum() returns the sum of one or more numbers.
New method
BigNumber::sum() returns the sum of one or more numbers.
Bug fix: of() factory methods could fail when passing a float in environments using a LC_NUMERIC locale with a decimal separator other than '.' (#20).
Bug fix: of() factory methods could fail when passing a float in environments using a LC_NUMERIC locale with a decimal separator other than '.' (#20).
Thanks @manowark 👍
BigDecimal::sqrt() calculates the square root of a decimal number, to a given scale.
New method
BigDecimal::sqrt() calculates the square root of a decimal number, to a given scale.
BigInteger::sqrt() calculates the square root of a number (thanks @peter279k).
New method
BigInteger::sqrt() calculates the square root of a number (thanks @peter279k).
New exception
NegativeNumberException is thrown when calling sqrt() on a negative number.
Further improvement of toInt() performance
Performance update
toInt() performanceNativeCalculator can now perform some multiplications more efficientlyPerformance optimization of toInt() methods.
Performance optimization of toInt() methods.
The following deprecated methods have been removed. Use the new method name instead:
Breaking changes
The following deprecated methods have been removed. Use the new method name instead:
| Method removed | Replacement method |
|---|---|
BigDecimal::getIntegral() |
BigDecimal::getIntegralPart() |
BigDecimal::getFraction() |
BigDecimal::getFractionalPart() |
New features
BigInteger has been augmented with 5 new methods for bitwise operations:
| New method | Description |
|---|---|
and() |
performs a bitwise AND operation on two numbers |
or() |
performs a bitwise OR operation on two numbers |
xor() |
performs a bitwise XOR operation on two numbers |
shiftedLeft() |
returns the number shifted left by a number of bits |
shiftedRight() |
returns the number shifted right by a number of bits |
Thanks to @DASPRiD 👍
BigDecimal::getIntegral() has been renamed to getIntegralPart() and is now deprecated
New method: BigDecimal::hasNonZeroFractionalPart()
Renamed/deprecated methods:
BigDecimal::getIntegral() has been renamed to getIntegralPart() and is now deprecatedBigDecimal::getFraction() has been renamed to getFractionalPart() and is now deprecatedBigInteger::parse() and toBase() now use GMP's built-in base conversion features when available.
Performance update
BigInteger::parse() and toBase() now use GMP's built-in base conversion features when available.
This is a maintenance release, no code has been changed.
This is a maintenance release, no code has been changed.
--no-dev, the autoloader does not autoload tests anymoreThis will help make installations more compact.
BigNumber:sign() has been renamed to getSign()
Methods renamed:
BigNumber:sign() has been renamed to getSign()BigDecimal::unscaledValue() has been renamed to getUnscaledValue()BigDecimal::scale() has been renamed to getScale()BigDecimal::integral() has been renamed to getIntegral()BigDecimal::fraction() has been renamed to getFraction()BigRational::numerator() has been renamed to getNumerator()BigRational::denominator() has been renamed to getDenominator()Classes renamed:
ArithmeticException has been renamed to MathExceptionThe base class for all exceptions is now MathException. ArithmeticException has been deprecated, and will be removed in 0.7.0.
The base class for all exceptions is now MathException.
ArithmeticException has been deprecated, and will be removed in 0.7.0.
BigNumber:sign() is deprecated; use getSign() instead
A number of methods have been renamed:
BigNumber:sign() is deprecated; use getSign() insteadBigDecimal::unscaledValue() is deprecated; use getUnscaledValue() insteadBigDecimal::scale() is deprecated; use getScale() insteadBigDecimal::integral() is deprecated; use getIntegral() insteadBigDecimal::fraction() is deprecated; use getFraction() insteadBigRational::numerator() is deprecated; use getNumerator() insteadBigRational::denominator() is deprecated; use getDenominator() insteadThe old methods will be removed in version 0.7.0.
Deprecated method BigDecimal::withScale() has been removed; use toScale() instead
0.5BigDecimal::withScale() has been removed; use toScale() insteadBigNumber::toInteger() has been renamed to toInt()Your coding agent can read these notes before it upgrades. Set up the MCP server →