Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Component/Utility/Number.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Component\Utility; | |
4 | |
5 /** | |
6 * Provides helper methods for manipulating numbers. | |
7 * | |
8 * @ingroup utility | |
9 */ | |
10 class Number { | |
11 | |
12 /** | |
13 * Verifies that a number is a multiple of a given step. | |
14 * | |
15 * The implementation assumes it is dealing with IEEE 754 double precision | |
16 * floating point numbers that are used by PHP on most systems. | |
17 * | |
18 * This is based on the number/range verification methods of webkit. | |
19 * | |
20 * @param float $value | |
21 * The value that needs to be checked. | |
22 * @param float $step | |
23 * The step scale factor. Must be positive. | |
24 * @param float $offset | |
25 * (optional) An offset, to which the difference must be a multiple of the | |
26 * given step. | |
27 * | |
28 * @return bool | |
29 * TRUE if no step mismatch has occurred, or FALSE otherwise. | |
30 * | |
31 * @see http://opensource.apple.com/source/WebCore/WebCore-1298/html/NumberInputType.cpp | |
32 */ | |
33 public static function validStep($value, $step, $offset = 0.0) { | |
34 $double_value = (double) abs($value - $offset); | |
35 | |
36 // The fractional part of a double has 53 bits. The greatest number that | |
37 // could be represented with that is 2^53. If the given value is even bigger | |
38 // than $step * 2^53, then dividing by $step will result in a very small | |
39 // remainder. Since that remainder can't even be represented with a single | |
40 // precision float the following computation of the remainder makes no sense | |
41 // and we can safely ignore it instead. | |
42 if ($double_value / pow(2.0, 53) > $step) { | |
43 return TRUE; | |
44 } | |
45 | |
46 // Now compute that remainder of a division by $step. | |
47 $remainder = (double) abs($double_value - $step * round($double_value / $step)); | |
48 | |
49 // $remainder is a double precision floating point number. Remainders that | |
50 // can't be represented with single precision floats are acceptable. The | |
51 // fractional part of a float has 24 bits. That means remainders smaller than | |
52 // $step * 2^-24 are acceptable. | |
53 $computed_acceptable_error = (double) ($step / pow(2.0, 24)); | |
54 | |
55 return $computed_acceptable_error >= $remainder || $remainder >= ($step - $computed_acceptable_error); | |
56 } | |
57 | |
58 /** | |
59 * Generates a sorting code from an integer. | |
60 * | |
61 * Consists of a leading character indicating length, followed by N digits | |
62 * with a numerical value in base 36 (alphadecimal). These codes can be sorted | |
63 * as strings without altering numerical order. | |
64 * | |
65 * It goes: | |
66 * 00, 01, 02, ..., 0y, 0z, | |
67 * 110, 111, ... , 1zy, 1zz, | |
68 * 2100, 2101, ..., 2zzy, 2zzz, | |
69 * 31000, 31001, ... | |
70 * | |
71 * @param int $i | |
72 * The integer value to convert. | |
73 * | |
74 * @return string | |
75 * The alpha decimal value. | |
76 * | |
77 * @see \Drupal\Component\Utility\Number::alphadecimalToInt | |
78 */ | |
79 public static function intToAlphadecimal($i = 0) { | |
80 $num = base_convert((int) $i, 10, 36); | |
81 $length = strlen($num); | |
82 | |
83 return chr($length + ord('0') - 1) . $num; | |
84 } | |
85 | |
86 /** | |
87 * Decodes a sorting code back to an integer. | |
88 * | |
89 * @param string $string | |
90 * The alpha decimal value to convert | |
91 * | |
92 * @return int | |
93 * The integer value. | |
94 * | |
95 * @see \Drupal\Component\Utility\Number::intToAlphadecimal | |
96 */ | |
97 public static function alphadecimalToInt($string = '00') { | |
98 return (int) base_convert(substr($string, 1), 36, 10); | |
99 } | |
100 | |
101 } |