Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

+32 -16
View File
@@ -11,7 +11,7 @@
namespace IPS\Math;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -47,17 +47,23 @@ class _Number implements \JsonSerializable
/**
* Constructor
*
* @string $number The number, as a string, using "." for decimal points
* @param string $number The number, as a string, using "." for decimal points
* @return void
* @throws \InvalidArgumentException
*/
public function __construct( $number )
{
/* Check it's valid */
if ( !is_string( $number ) )
if ( !\is_string( $number ) )
{
throw new \InvalidArgumentException('NOT_A_STRING');
}
if ( $number === '' )
{
throw new \InvalidArgumentException('NOT_VALID_NUMBER');
}
if ( !preg_match( '/^([+-])?(\d*)(\.(\d*))?$/', $number, $matches ) )
{
throw new \InvalidArgumentException('NOT_VALID_NUMBER');
@@ -68,9 +74,9 @@ class _Number implements \JsonSerializable
{
$this->positive = FALSE;
}
$this->beforeDecimalPoint = isset( $matches[2] ) ? intval( $matches[2] ) : 0;
$this->beforeDecimalPoint = isset( $matches[2] ) ? \intval( $matches[2] ) : 0;
$this->numberOfDecimalPlaces = isset( $matches[4] ) ? mb_strlen( $matches[4] ) : 0;
$this->afterDecimalPoint = isset( $matches[4] ) ? intval( $matches[4] ) : 0;
$this->afterDecimalPoint = isset( $matches[4] ) ? \intval( $matches[4] ) : 0;
/* If we have x.y00, simplify to x.y */
$this->_simplifyDecimalPlaces();
@@ -146,8 +152,8 @@ class _Number implements \JsonSerializable
}
/* Otherwise, add the two absolute values together */
$paddedThis = intval( "{$this->beforeDecimalPoint}" . str_pad( str_pad( $this->afterDecimalPoint, $this->numberOfDecimalPlaces, '0', STR_PAD_LEFT ), $biggerDecimalPlaces, '0' ) );
$paddedNumber = intval( "{$number->beforeDecimalPoint}" . str_pad( str_pad( $number->afterDecimalPoint, $number->numberOfDecimalPlaces, '0', STR_PAD_LEFT ), $biggerDecimalPlaces, '0' ) );
$paddedThis = \intval( "{$this->beforeDecimalPoint}" . str_pad( str_pad( $this->afterDecimalPoint, $this->numberOfDecimalPlaces, '0', STR_PAD_LEFT ), $biggerDecimalPlaces, '0' ) );
$paddedNumber = \intval( "{$number->beforeDecimalPoint}" . str_pad( str_pad( $number->afterDecimalPoint, $number->numberOfDecimalPlaces, '0', STR_PAD_LEFT ), $biggerDecimalPlaces, '0' ) );
$absoluteResult = $paddedThis + $paddedNumber;
/* ... and then add the decimal back in the correct place */
@@ -196,8 +202,8 @@ class _Number implements \JsonSerializable
}
/* Otherwise, add the two absolute values together */
$paddedThis = intval( "{$this->beforeDecimalPoint}" . str_pad( str_pad( $this->afterDecimalPoint, $this->numberOfDecimalPlaces, '0', STR_PAD_LEFT ), $biggerDecimalPlaces, '0' ) );
$paddedNumber = intval( "{$number->beforeDecimalPoint}" . str_pad( str_pad( $number->afterDecimalPoint, $number->numberOfDecimalPlaces, '0', STR_PAD_LEFT ), $biggerDecimalPlaces, '0' ) );
$paddedThis = \intval( "{$this->beforeDecimalPoint}" . str_pad( str_pad( $this->afterDecimalPoint, $this->numberOfDecimalPlaces, '0', STR_PAD_LEFT ), $biggerDecimalPlaces, '0' ) );
$paddedNumber = \intval( "{$number->beforeDecimalPoint}" . str_pad( str_pad( $number->afterDecimalPoint, $number->numberOfDecimalPlaces, '0', STR_PAD_LEFT ), $biggerDecimalPlaces, '0' ) );
$absoluteResult = $paddedThis - $paddedNumber;
/* ... and then add the decimal back in the correct place */
@@ -225,7 +231,7 @@ class _Number implements \JsonSerializable
public function multiply( $number )
{
/* Multiply the absolute numbers */
$absoluteResult = intval( "{$this->beforeDecimalPoint}" . ( $this->afterDecimalPoint ? str_pad( $this->afterDecimalPoint, $this->numberOfDecimalPlaces, '0', STR_PAD_LEFT ) : '' ) ) * intval( "{$number->beforeDecimalPoint}" . ( $number->afterDecimalPoint ? str_pad( $number->afterDecimalPoint, $number->numberOfDecimalPlaces, '0', STR_PAD_LEFT ) : '' ) );
$absoluteResult = \intval( "{$this->beforeDecimalPoint}" . ( $this->afterDecimalPoint ? str_pad( $this->afterDecimalPoint, $this->numberOfDecimalPlaces, '0', STR_PAD_LEFT ) : '' ) ) * \intval( "{$number->beforeDecimalPoint}" . ( $number->afterDecimalPoint ? str_pad( $number->afterDecimalPoint, $number->numberOfDecimalPlaces, '0', STR_PAD_LEFT ) : '' ) );
/* Work out where the decimal point goes */
$numberOfDecimalPlaces = $this->numberOfDecimalPlaces + $number->numberOfDecimalPlaces;
@@ -295,7 +301,7 @@ class _Number implements \JsonSerializable
/* Round it */
if ( $round !== static::ROUND_TRUNCATE )
{
$lastDigit = intval( mb_substr( $result, -1 ) );
$lastDigit = \intval( mb_substr( $result, -1 ) );
$result = mb_substr( $result, 0, -1 );
if ( $lastDigit !== 0 )
@@ -340,7 +346,7 @@ class _Number implements \JsonSerializable
* Modulus
*
* @param \IPS\Math\Number $number Number to get modulus of
* @param int $precision
* @param int $divides Dividend
* @return \IPS\Math\Number
*/
public function modulus( $number, &$divides = 0 )
@@ -382,7 +388,7 @@ class _Number implements \JsonSerializable
/**
* Compare
*
* @param \IPS\Math\Number $number Number to divide by
* @param \IPS\Math\Number $number Number to compare against
* @return int Returns 0 if the two numbers are equal, 1 if this number is larger than the $number, -1 otherwise
*/
public function compare( $number )
@@ -441,7 +447,7 @@ class _Number implements \JsonSerializable
/* If we don't know if we're going up or down, figure that out */
if ( $round === static::ROUND_NORMAL )
{
$numberToExamine = intval( \substr( str_pad( $this->afterDecimalPoint, $this->numberOfDecimalPlaces, '0', STR_PAD_LEFT ), $decimalPlaces, 1 ) );
$numberToExamine = \intval( \substr( str_pad( $this->afterDecimalPoint, $this->numberOfDecimalPlaces, '0', STR_PAD_LEFT ), $decimalPlaces, 1 ) );
if ( $numberToExamine >= 5 )
{
$round = static::ROUND_UP;
@@ -460,11 +466,11 @@ class _Number implements \JsonSerializable
{
if ( $this->positive )
{
$abs = intval( $abs ) + 1;
$abs = \intval( $abs ) + 1;
}
else
{
$abs = intval( $abs ) - 1;
$abs = \intval( $abs ) - 1;
}
}
@@ -494,6 +500,16 @@ class _Number implements \JsonSerializable
return $this->multiply( $percentage->divide( new static( '100' ) ) );
}
/**
* Get absolute value
*
* @return \IPS\Math\Number
*/
public function absolute()
{
return $this->positive ? $this : $this->multiply( new \IPS\Math\Number('-1') );
}
/* !Array math */