All notable changes to this project will be documented in this file.
🗑️ 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 annotations✨ New features
clamp() is now available on the base BigNumber class👌 Improvements
@throws exception documentation🗑️ Deprecations
$scale to BigDecimal::dividedBy() is deprecated; $scale will be required in 0.15👌 Improvements
BigRational::toFloat() never returns NAN anymore🗑️ 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 @pure🗑️ Deprecations
BigInteger::mod() is deprecated to align with Euclidean modulo semantics; it will throw NegativeNumberException 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 @pure✨ New features
BigInteger::lcm()BigInteger::lcmAll()BigRational::toRepeatingDecimalString()🐛 Bug fixes
BigInteger::gcdAll() / gcdMultiple() could return a negative result when used with a single negative number🗑️ 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
BigInteger::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 result✨ New features
BigNumber::ofNullable() (#94 by @mrkh995)✨ Compatibility fixes
✨ 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✨ Improvements
__toString() methods of BigInteger and BigDecimal are now type-hinted as returning numeric-string instead of string (#90 by @vudaltsov)💥 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)✨ New features
BigDecimal::getPrecision() Returns the number of significant digits in a decimal number⚡️ Performance improvements
NativeCalculator is now faster for small divisors, thanks to @Izumi-kun in #87.👌 Improvements
RoundingNecessaryException to the @throws annotation of BigNumber::of()⚡️ Performance improvements
BigNumber::of() is now faster, thanks to @SebastienDug in #77.💥 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 final💥 Breaking changes
MathException now extends Exception instead of RuntimeException* 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.
👌 Improvements
BigRational::toFloat() now simplifies the fraction before performing division (#73) thanks to @olsavmic✨ New features
BigInteger::gcdMultiple() returns the GCD of multiple BigInteger numbers💥 Breaking changes
🚀 Compatibility with PHP 8.1
Serializable interface being deprecated (#60) thanks @TRowbotham🐛 Bug fix
bcscale(), on PHP >= 7.2 (#55).✨ 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 available👌 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() instead🐛 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 available🚑 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()🐛 Fixes
ext-json requirement, due to BigNumber implementing JsonSerializable⚡️ Optimizations
BigInteger::remainder()✨ New features
BigInteger::getLowestSetBit() returns the index of the rightmost one bit✨ 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 number🛠️ 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.
✨ New feature
BigInteger::powerMod() performs a power-with-modulo operation. Useful for crypto.
✨ New feature
BigInteger::mod() returns the modulo of two numbers. The modulo differs from the remainder when the signs of the operands are different.
⚡️ 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.
🐛 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 malformedImprovements
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.
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).
Thanks @manowark 👍
New method
BigDecimal::sqrt() calculates the square root of a decimal number, to a given scale.
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.
Performance update
toInt() performanceNativeCalculator can now perform some multiplications more efficientlyPerformance optimization of toInt() methods.
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 👍
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 deprecatedPerformance 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.
--no-dev, the autoloader does not autoload tests anymoreThis will help make installations more compact.
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.
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.
0.5BigDecimal::withScale() has been removed; use toScale() insteadBigNumber::toInteger() has been renamed to toInt()BigNumber classes now implement JsonSerializable.
The JSON output is always a string.
This is a bugfix release. Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6.
The $scale parameter of BigDecimal::dividedBy() is now optional again.
New method: BigNumber::toScale()
This allows to convert any BigNumber to a BigDecimal with a given scale, using rounding if necessary.
New features
- Common BigNumber interface for all classes, with the following methods:
- sign() and derived methods (isZero(), isPositive(), …)
- compareTo() and derived methods (isEqualTo(), isGreaterThan(), …) that work across different BigNumber types
- toBigInteger(), toBigDecimal(), toBigRational() conversion methods
- toInteger() and toFloat() conversion methods to native types
- Unified of() behaviour: every class now accepts any type of number, provided that it can be safely converted to the current type
- New method: BigDecimal::exactlyDividedBy(); this method automatically computes the scale of the result, provided that the division yields a finite number of digits
- New methods: BigRational::quotient() and remainder()
- Fine-grained exceptions: DivisionByZeroException, RoundingNecessaryException, NumberFormatException
- Factory methods zero(), one() and ten() available in all classes
- Rounding mode reintroduced in BigInteger::dividedBy()
This release also comes with many performance improvements.
Breaking changes
- BigInteger:
- getSign() is renamed to sign()
- toString() is renamed to toBase()
- BigInteger::dividedBy() now throws an exception by default if the remainder is not zero; use quotient() to get the previous behaviour
- BigDecimal:
- getSign() is renamed to sign()
- getUnscaledValue() is renamed to unscaledValue()
- getScale() is renamed to scale()
- getIntegral() is renamed to integral()
- getFraction() is renamed to fraction()
- divideAndRemainder() is renamed to quotientAndRemainder()
- dividedBy() now takes a mandatory $scale parameter before the rounding mode
- toBigInteger() does not accept a $roundingMode parameter anymore
- toBigRational() does not simplify the fraction anymore; explicitly add ->simplified() to get the previous behaviour
- BigRational:
- getSign() is renamed to sign()
- getNumerator() is renamed to numerator()
- getDenominator() is renamed to denominator()
- of() is renamed to nd(), while parse() is renamed to of()
- Miscellaneous:
- ArithmeticException is moved to an Exception\ sub-namespace
- of() factory methods now throw NumberFormatException instead of InvalidArgumentException
Backport of two bug fixes from the 0.5 branch:
- BigInteger::parse() did not always throw InvalidArgumentException as expected
- Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6.
New method: BigDecimal::stripTrailingZeros()
Introducing a BigRational class, to perform calculations on fractions of any size.
Rounding modes have been removed from BigInteger, and are now a concept specific to BigDecimal.
BigInteger::dividedBy() now always returns the quotient of the division.
Backport of two bug fixes from the 0.5 branch:
BigInteger::parse() did not always throw InvalidArgumentException as expectedNew methods:
- BigInteger::remainder() returns the remainder of a division only
- BigInteger::gcd() returns the greatest common divisor of two numbers
Fix toString() not handling negative numbers.
BigInteger and BigDecimal now have a getSign() method that returns:
- -1 if the number is negative
- 0 if the number is zero
- 1 if the number is positive
Minor performance improvements
The $roundingMode and $scale parameters have been swapped in BigDecimal::dividedBy().
Stronger immutability guarantee for BigInteger and BigDecimal.
So far, it would have been possible to break immutability of these classes by calling the unserialize() internal function. This release fixes that.
Added BigDecimal::divideAndRemainder()
min() and max() do not accept an array anymore, but a variable number of parametersBigInteger::power()First beta release.