Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
951 changes: 702 additions & 249 deletions brick/math/src/BigDecimal.php

Large diffs are not rendered by default.

1,045 changes: 735 additions & 310 deletions brick/math/src/BigInteger.php

Large diffs are not rendered by default.

734 changes: 466 additions & 268 deletions brick/math/src/BigNumber.php

Large diffs are not rendered by default.

467 changes: 324 additions & 143 deletions brick/math/src/BigRational.php

Large diffs are not rendered by default.

54 changes: 46 additions & 8 deletions brick/math/src/Exception/DivisionByZeroException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,70 @@

namespace Brick\Math\Exception;

use RuntimeException;

/**
* Exception thrown when a division by zero occurs.
*/
class DivisionByZeroException extends MathException
final class DivisionByZeroException extends RuntimeException implements MathException
{
/**
* @psalm-pure
* @internal
*
* @pure
*/
public function __construct(string $message)
{
parent::__construct($message);
}

/**
* @internal
*
* @pure
*/
public static function divisionByZero() : DivisionByZeroException
public static function divisionByZero(): self
{
return new self('Division by zero.');
}

/**
* @psalm-pure
* @internal
*
* @pure
*/
public static function modulusMustNotBeZero() : DivisionByZeroException
public static function zeroModulus(): self
{
return new self('The modulus must not be zero.');
}

/**
* @psalm-pure
* @internal
*
* @pure
*/
public static function zeroDenominator(): self
{
return new self('The denominator of a rational number must not be zero.');
}

/**
* @internal
*
* @pure
*/
public static function reciprocalOfZero(): self
{
return new self('The reciprocal of zero is undefined.');
}

/**
* @internal
*
* @pure
*/
public static function denominatorMustNotBeZero() : DivisionByZeroException
public static function zeroToNegativePower(): self
{
return new self('The denominator of a rational number cannot be zero.');
return new self('Cannot raise zero to a negative power.');
}
}
45 changes: 39 additions & 6 deletions brick/math/src/Exception/IntegerOverflowException.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,52 @@
namespace Brick\Math\Exception;

use Brick\Math\BigInteger;
use RuntimeException;

use function sprintf;

use const PHP_INT_MAX;
use const PHP_INT_MIN;

/**
* Exception thrown when an integer overflow occurs.
* Exception thrown when a native integer overflow occurs.
*/
class IntegerOverflowException extends MathException
final class IntegerOverflowException extends RuntimeException implements MathException
{
/**
* @psalm-pure
* @internal
*
* @pure
*/
public function __construct(string $message)
{
parent::__construct($message);
}

/**
* @internal
*
* @pure
*/
public static function toIntOverflow(BigInteger $value) : IntegerOverflowException
public static function integerOutOfRange(BigInteger $value): self
{
$message = '%s is out of range %d to %d and cannot be represented as an integer.';
$message = '%s is out of range [%d, %d] and cannot be represented as an integer.';

return new self(sprintf($message, $value->toString(), PHP_INT_MIN, PHP_INT_MAX));
}

return new self(\sprintf($message, (string) $value, PHP_INT_MIN, PHP_INT_MAX));
/**
* @internal
*
* @pure
*/
public static function nativeIntegerOverflow(string $expression): self
{
return new self(sprintf(
'Cannot compute %s because the result is outside the native integer range [%d, %d].',
$expression,
PHP_INT_MIN,
PHP_INT_MAX,
));
}
}
133 changes: 133 additions & 0 deletions brick/math/src/Exception/InvalidArgumentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php

declare(strict_types=1);

namespace Brick\Math\Exception;

use function sprintf;

/**
* Exception thrown when an invalid argument is provided.
*/
final class InvalidArgumentException extends \InvalidArgumentException implements MathException
{
/**
* @internal
*
* @pure
*/
public function __construct(string $message)
{
parent::__construct($message);
}

/**
* @internal
*
* @pure
*/
public static function baseOutOfRange(int $base): self
{
return new self(sprintf('Base %d is out of range [2, 36].', $base));
}

/**
* @internal
*
* @pure
*/
public static function negativeScale(): self
{
return new self('The scale must not be negative.');
}

/**
* @internal
*
* @pure
*/
public static function negativeBitIndex(): self
{
return new self('The bit index must not be negative.');
}

/**
* @internal
*
* @pure
*/
public static function negativeBitCount(): self
{
return new self('The bit count must not be negative.');
}

/**
* @internal
*
* @pure
*/
public static function alphabetTooShort(): self
{
return new self('The alphabet must contain at least 2 characters.');
}

/**
* @internal
*
* @pure
*/
public static function duplicateCharsInAlphabet(): self
{
return new self('The alphabet must not contain duplicate characters.');
}

/**
* @internal
*
* @pure
*/
public static function minGreaterThanMax(): self
{
return new self('The minimum value must be less than or equal to the maximum value.');
}

/**
* @internal
*
* @pure
*/
public static function cannotConvertFloat(string $type): self
{
return new self(sprintf('Cannot convert %s to a BigDecimal.', $type));
}

/**
* @internal
*
* @pure
*/
public static function negativeExponent(): self
{
return new self('The exponent must not be negative.');
}

/**
* @internal
*
* @pure
*/
public static function negativeModulus(): self
{
return new self('The modulus must not be negative.');
}

/**
* @internal
*
* @pure
*/
public static function nonPositiveNthRootDegree(): self
{
return new self('The degree of an nth root must be a positive integer.');
}
}
6 changes: 4 additions & 2 deletions brick/math/src/Exception/MathException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

namespace Brick\Math\Exception;

use Throwable;

/**
* Base class for all math exceptions.
* Base interface for all math exceptions.
*/
class MathException extends \Exception
interface MathException extends Throwable
{
}
53 changes: 52 additions & 1 deletion brick/math/src/Exception/NegativeNumberException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,60 @@

namespace Brick\Math\Exception;

use RuntimeException;

/**
* Exception thrown when attempting to perform an unsupported operation, such as a square root, on a negative number.
*/
class NegativeNumberException extends MathException
final class NegativeNumberException extends RuntimeException implements MathException
{
/**
* @internal
*
* @pure
*/
public function __construct(string $message)
{
parent::__construct($message);
}

/**
* @internal
*
* @pure
*/
public static function squareRootOfNegativeNumber(): self
{
return new self('Cannot calculate the square root of a negative number.');
}

/**
* @internal
*
* @pure
*/
public static function nthRootOfNegativeNumber(): self
{
return new self('Cannot take an even nth root of a negative number.');
}

/**
* @internal
*
* @pure
*/
public static function toArbitraryBaseOfNegativeNumber(): self
{
return new self('Cannot convert a negative number to an arbitrary base.');
}

/**
* @internal
*
* @pure
*/
public static function unsignedBytesOfNegativeNumber(): self
{
return new self('Cannot convert a negative number to a byte string in unsigned mode.');
}
}
33 changes: 33 additions & 0 deletions brick/math/src/Exception/NoInverseException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Brick\Math\Exception;

use RuntimeException;

/**
* Exception thrown when attempting to compute a modular inverse that does not exist.
*/
final class NoInverseException extends RuntimeException implements MathException
{
/**
* @internal
*
* @pure
*/
public function __construct(string $message)
{
parent::__construct($message);
}

/**
* @internal
*
* @pure
*/
public static function noModularInverse(): self
{
return new self('This number has no multiplicative inverse modulo the given modulus (they are not coprime).');
}
}
Loading