2015-08-17 17:00:26 -07:00
< ? php
/**
* @ file
* Contains \Drupal\Component\Utility\Number .
*/
namespace Drupal\Component\Utility ;
/**
* Provides helper methods for manipulating numbers .
*
* @ ingroup utility
*/
class Number {
/**
* Verifies that a number is a multiple of a given step .
*
* The implementation assumes it is dealing with IEEE 754 double precision
* floating point numbers that are used by PHP on most systems .
*
* This is based on the number / range verification methods of webkit .
*
2016-01-06 16:31:26 -08:00
* @ param float $value
2015-08-17 17:00:26 -07:00
* The value that needs to be checked .
2016-01-06 16:31:26 -08:00
* @ param float $step
2015-08-17 17:00:26 -07:00
* The step scale factor . Must be positive .
2016-01-06 16:31:26 -08:00
* @ param float $offset
2015-08-17 17:00:26 -07:00
* ( optional ) An offset , to which the difference must be a multiple of the
* given step .
*
* @ return bool
* TRUE if no step mismatch has occurred , or FALSE otherwise .
*
* @ see http :// opensource . apple . com / source / WebCore / WebCore - 1298 / html / NumberInputType . cpp
*/
public static function validStep ( $value , $step , $offset = 0.0 ) {
$double_value = ( double ) abs ( $value - $offset );
// The fractional part of a double has 53 bits. The greatest number that
// could be represented with that is 2^53. If the given value is even bigger
// than $step * 2^53, then dividing by $step will result in a very small
// remainder. Since that remainder can't even be represented with a single
// precision float the following computation of the remainder makes no sense
// and we can safely ignore it instead.
if ( $double_value / pow ( 2.0 , 53 ) > $step ) {
return TRUE ;
}
// Now compute that remainder of a division by $step.
$remainder = ( double ) abs ( $double_value - $step * round ( $double_value / $step ));
// $remainder is a double precision floating point number. Remainders that
// can't be represented with single precision floats are acceptable. The
// fractional part of a float has 24 bits. That means remainders smaller than
// $step * 2^-24 are acceptable.
$computed_acceptable_error = ( double )( $step / pow ( 2.0 , 24 ));
return $computed_acceptable_error >= $remainder || $remainder >= ( $step - $computed_acceptable_error );
}
/**
* Generates a sorting code from an integer .
*
* Consists of a leading character indicating length , followed by N digits
* with a numerical value in base 36 ( alphadecimal ) . These codes can be sorted
* as strings without altering numerical order .
*
* It goes :
* 00 , 01 , 02 , ... , 0 y , 0 z ,
* 110 , 111 , ... , 1 zy , 1 zz ,
* 2100 , 2101 , ... , 2 zzy , 2 zzz ,
* 31000 , 31001 , ...
*
* @ param int $i
* The integer value to convert .
*
* @ return string
* The alpha decimal value .
*
* @ see \Drupal\Component\Utility\Number :: alphadecimalToInt
*/
public static function intToAlphadecimal ( $i = 0 ) {
$num = base_convert (( int ) $i , 10 , 36 );
$length = strlen ( $num );
return chr ( $length + ord ( '0' ) - 1 ) . $num ;
}
/**
* Decodes a sorting code back to an integer .
*
* @ param string $string
* The alpha decimal value to convert
*
* @ return int
* The integer value .
*
* @ see \Drupal\Component\Utility\Number :: intToAlphadecimal
*/
public static function alphadecimalToInt ( $string = '00' ) {
return ( int ) base_convert ( substr ( $string , 1 ), 36 , 10 );
}
}