1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.Integer;
13 
14 import hunt.Byte;
15 import hunt.Exceptions;
16 import hunt.Nullable;
17 import hunt.Number;
18 import hunt.util.Comparator;
19 
20 import std.conv;
21 
22 class Integer : AbstractNumber!int
23 {
24 
25     /**
26      * Returns the number of one-bits in the two's complement binary
27      * representation of the specified {@code int} value.  This function is
28      * sometimes referred to as the <i>population count</i>.
29      *
30      * @param i the value whose bits are to be counted
31      * @return the number of one-bits in the two's complement binary
32      *     representation of the specified {@code int} value.
33      */
34     enum int MIN_VALUE = int.min; // 0x80000000;
35 
36     /**
37      * A constant holding the maximum value an {@code int} can
38      * have, 2!(sup)31</sup>-1.
39      */
40     enum int MAX_VALUE = int.max; // 0x7fffffff;
41 
42     static int bitCount(int i)
43     {
44         // HD, Figure 5-2
45         i = i - ((i >>> 1) & 0x55555555);
46         i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
47         i = (i + (i >>> 4)) & 0x0f0f0f0f;
48         i = i + (i >>> 8);
49         i = i + (i >>> 16);
50         return i & 0x3f;
51     }
52 
53     enum char[] digits = [
54             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',
55             'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
56             'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
57         ];
58 
59     /**
60      * Returns the number of zero bits preceding the highest-order
61      * ("leftmost") one-bit in the two's complement binary representation
62      * of the specified {@code int} value.  Returns 32 if the
63      * specified value has no one-bits in its two's complement representation,
64      * in other words if it is equal to zero.
65      *
66      * <p>Note that this method is closely related to the logarithm base 2.
67      * For all positive {@code int} values x:
68      * <ul>
69      * <li>floor(log!(sub)2</sub>(x)) = {@code 31 - numberOfLeadingZeros(x)}
70      * <li>ceil(log!(sub)2</sub>(x)) = {@code 32 - numberOfLeadingZeros(x - 1)}
71      * </ul>
72      *
73      * @param i the value whose number of leading zeros is to be computed
74      * @return the number of zero bits preceding the highest-order
75      *     ("leftmost") one-bit in the two's complement binary representation
76      *     of the specified {@code int} value, or 32 if the value
77      *     is equal to zero.
78      */
79     static int numberOfLeadingZeros(int i)
80     {
81         // HD, Figure 5-6
82         if (i == 0)
83             return 32;
84         int n = 1;
85         if (i >>> 16 == 0)
86         {
87             n += 16;
88             i <<= 16;
89         }
90         if (i >>> 24 == 0)
91         {
92             n += 8;
93             i <<= 8;
94         }
95         if (i >>> 28 == 0)
96         {
97             n += 4;
98             i <<= 4;
99         }
100         if (i >>> 30 == 0)
101         {
102             n += 2;
103             i <<= 2;
104         }
105         n -= i >>> 31;
106         return n;
107     }
108 
109     /**
110      * Returns the number of zero bits following the lowest-order ("rightmost")
111      * one-bit in the two's complement binary representation of the specified
112      * {@code int} value.  Returns 32 if the specified value has no
113      * one-bits in its two's complement representation, in other words if it is
114      * equal to zero.
115      *
116      * @param i the value whose number of trailing zeros is to be computed
117      * @return the number of zero bits following the lowest-order ("rightmost")
118      *     one-bit in the two's complement binary representation of the
119      *     specified {@code int} value, or 32 if the value is equal
120      *     to zero.
121      */
122     static int numberOfTrailingZeros(int i)
123     {
124         // HD, Figure 5-14
125         int y;
126         if (i == 0)
127             return 32;
128         int n = 31;
129         y = i << 16;
130         if (y != 0)
131         {
132             n = n - 16;
133             i = y;
134         }
135         y = i << 8;
136         if (y != 0)
137         {
138             n = n - 8;
139             i = y;
140         }
141         y = i << 4;
142         if (y != 0)
143         {
144             n = n - 4;
145             i = y;
146         }
147         y = i << 2;
148         if (y != 0)
149         {
150             n = n - 2;
151             i = y;
152         }
153         return n - ((i << 1) >>> 31);
154     }
155 
156     override int opCmp(Object o)
157     {
158         if (o is null)
159             throw new NullPointerException();
160         Number n = cast(Number) o;
161         if (n is null)
162             throw new Exception("Number needed.");
163         return compare(this.value, n.intValue());
164     }
165 
166     int opCmp(long n)
167     {
168         return compare(this.value, n);
169     }
170 
171     /**
172      * Returns a hash code for a {@code double} value; compatible with
173      * {@code Double.hashCode()}.
174      *
175      * @param value the value to hash
176      * @return a hash code value for a {@code double} value.
177      */
178     override size_t toHash() @safe nothrow
179     {
180         return cast(size_t) value;
181     }
182 
183     /**
184      * Compares this object against the specified object.  The result
185      * is {@code true} if and only if the argument is not
186      * {@code null} and is a {@code Double} object that
187      * represents a {@code double} that has the same value as the
188      * {@code double} represented by this object. For this
189      * purpose, two {@code double} values are considered to be
190      * the same if and only if the method {@link
191      * #doubleToLongBits(double)} returns the identical
192      * {@code long} value when applied to each.
193      *
194      * <p>Note that in most cases, for two instances of class
195      * {@code Double}, {@code d1} and {@code d2}, the
196      * value of {@code d1.equals(d2)} is {@code true} if and
197      * only if
198      *
199      * <blockquote>
200      *  {@code d1.doubleValue() == d2.doubleValue()}
201      * </blockquote>
202      *
203      * <p>also has the value {@code true}. However, there are two
204      * exceptions:
205      * <ul>
206      * <li>If {@code d1} and {@code d2} both represent
207      *     {@code Double.NaN}, then the {@code equals} method
208      *     returns {@code true}, even though
209      *     {@code Double.NaN==Double.NaN} has the value
210      *     {@code false}.
211      * <li>If {@code d1} represents {@code +0.0} while
212      *     {@code d2} represents {@code -0.0}, or vice versa,
213      *     the {@code equal} test has the value {@code false},
214      *     even though {@code +0.0==-0.0} has the value {@code true}.
215      * </ul>
216      * This definition allows hash tables to operate properly.
217      * @param   obj   the object to compare with.
218      * @return  {@code true} if the objects are the same;
219      *          {@code false} otherwise.
220      * @see java.lang.Double#doubleToLongBits(double)
221      */
222     // override bool opEquals(Object obj) {
223     //     auto dl = cast(Integer)obj;
224     //     if(dl !is null)
225     //         return value == dl.intValue;
226 
227     //     return false;
228     // }
229 
230     // alias opEquals = Nullable!int.opEquals;
231 
232     /**
233      * The value of the {@code Integer}.
234      *
235      * @serial
236      */
237     // private  int value;
238 
239     /**
240      * Constructs a newly allocated {@code Integer} object that
241      * represents the specified {@code int} value.
242      *
243      * @param   value   the value to be represented by the
244      *                  {@code Integer} object.
245      */
246     this(int value)
247     {
248         super(value);
249     }
250 
251     static int parseInt(string s)
252     {
253         auto i = to!long(s);
254         if (i < MIN_VALUE || i > MAX_VALUE)
255         {
256             throw new Exception("Value " ~ s ~ " out of range from input ");
257         }
258 
259         return cast(int) i;
260     }
261 
262     /**
263      * Parses the string argument as a signed integer in the radix
264      * specified by the second argument. The characters in the string
265      * must all be digits of the specified radix (as determined by
266      * whether {@link java.lang.Character#digit(char, int)} returns a
267      * nonnegative value), except that the first character may be an
268      * ASCII minus sign {@code '-'} ({@code '\u005Cu002D'}) to
269      * indicate a negative value or an ASCII plus sign {@code '+'}
270      * ({@code '\u005Cu002B'}) to indicate a positive value. The
271      * resulting integer value is returned.
272      *
273      * <p>An exception of type {@code NumberFormatException} is
274      * thrown if any of the following situations occurs:
275      * <ul>
276      * <li>The first argument is {@code null} or is a string of
277      * length zero.
278      *
279      * <li>The radix is either smaller than
280      * {@link java.lang.Character#MIN_RADIX} or
281      * larger than {@link java.lang.Character#MAX_RADIX}.
282      *
283      * <li>Any character of the string is not a digit of the specified
284      * radix, except that the first character may be a minus sign
285      * {@code '-'} ({@code '\u005Cu002D'}) or plus sign
286      * {@code '+'} ({@code '\u005Cu002B'}) provided that the
287      * string is longer than length 1.
288      *
289      * <li>The value represented by the string is not a value of type
290      * {@code int}.
291      * </ul>
292      *
293      * <p>Examples:
294      * <blockquote><pre>
295      * parseInt("0", 10) returns 0
296      * parseInt("473", 10) returns 473
297      * parseInt("+42", 10) returns 42
298      * parseInt("-0", 10) returns 0
299      * parseInt("-FF", 16) returns -255
300      * parseInt("1100110", 2) returns 102
301      * parseInt("2147483647", 10) returns 2147483647
302      * parseInt("-2147483648", 10) returns -2147483648
303      * parseInt("2147483648", 10) throws a NumberFormatException
304      * parseInt("99", 8) throws a NumberFormatException
305      * parseInt("Kona", 10) throws a NumberFormatException
306      * parseInt("Kona", 27) returns 411787
307      * </pre></blockquote>
308      *
309      * @param      s   the {@code String} containing the integer
310      *                  representation to be parsed
311      * @param      radix   the radix to be used while parsing {@code s}.
312      * @return     the integer represented by the string argument in the
313      *             specified radix.
314      * @exception  NumberFormatException if the {@code String}
315      *             does not contain a parsable {@code int}.
316      */
317     static int parseInt(string s, int radix)
318     {
319         return to!int(s, radix);
320     }
321 
322     /**
323      * Cache to support the object identity semantics of autoboxing for values between
324      * -128 and 127 (inclusive) as required by JLS.
325      *
326      * The cache is initialized on first usage.  The size of the cache
327      * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
328      * During VM initialization, java.lang.Integer.IntegerCache.high property
329      * may be set and saved in the private system properties in the
330      * sun.misc.VM class.
331      */
332 
333     private static class IntegerCache
334     {
335         static int low = -128;
336         static int high;
337         static Integer[] cache;
338 
339         static this()
340         {
341             // high value may be configured by property
342             int h = 127;
343             // string integerCacheHighPropValue =
344             //     sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
345             // if (integerCacheHighPropValue !is null) {
346             //     try {
347             //         int i = parseInt(integerCacheHighPropValue);
348             //         i = Math.max(i, 127);
349             //         // Maximum array size is Integer.MAX_VALUE
350             //         h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
351             //     } catch( NumberFormatException nfe) {
352             //         // If the property cannot be parsed into an int, ignore it.
353             //     }
354             // }
355             high = h;
356 
357             cache = new Integer[(high - low) + 1];
358             int j = low;
359             for (int k = 0; k < cache.length; k++)
360                 cache[k] = new Integer(j++);
361 
362             // range [-128, 127] must be interned (JLS7 5.1.7)
363             assert(IntegerCache.high >= 127);
364         }
365 
366         private this()
367         {
368         }
369     }
370 
371     /**
372      * Returns an {@code Integer} instance representing the specified
373      * {@code int} value.  If a new {@code Integer} instance is not
374      * required, this method should generally be used in preference to
375      * the constructor {@link #Integer(int)}, as this method is likely
376      * to yield significantly better space and time performance by
377      * caching frequently requested values.
378      *
379      * This method will always cache values in the range -128 to 127,
380      * inclusive, and may cache other values outside of this range.
381      *
382      * @param  i an {@code int} value.
383      * @return an {@code Integer} instance representing {@code i}.
384      */
385     static Integer valueOf(int i)
386     {
387         if (i >= IntegerCache.low && i <= IntegerCache.high)
388             return IntegerCache.cache[i + (-IntegerCache.low)];
389         return new Integer(i);
390     }
391 
392     /**
393      * Returns an {@code Integer} object holding the value
394      * extracted from the specified {@code String} when parsed
395      * with the radix given by the second argument. The first argument
396      * is interpreted as representing a signed integer in the radix
397      * specified by the second argument, exactly as if the arguments
398      * were given to the {@link #parseInt(java.lang.String, int)}
399      * method. The result is an {@code Integer} object that
400      * represents the integer value specified by the string.
401      *
402      * <p>In other words, this method returns an {@code Integer}
403      * object equal to the value of:
404      *
405      * <blockquote>
406      *  {@code new Integer(Integer.parseInt(s, radix))}
407      * </blockquote>
408      *
409      * @param      s   the string to be parsed.
410      * @param      radix the radix to be used in interpreting {@code s}
411      * @return     an {@code Integer} object holding the value
412      *             represented by the string argument in the specified
413      *             radix.
414      * @exception NumberFormatException if the {@code String}
415      *            does not contain a parsable {@code int}.
416      */
417     static Integer valueOf(string s, int radix)
418     {
419         return Integer.valueOf(parseInt(s, radix));
420     }
421 
422     /**
423      * Returns an {@code Integer} object holding the
424      * value of the specified {@code String}. The argument is
425      * interpreted as representing a signed decimal integer, exactly
426      * as if the argument were given to the {@link
427      * #parseInt(java.lang.String)} method. The result is an
428      * {@code Integer} object that represents the integer value
429      * specified by the string.
430      *
431      * <p>In other words, this method returns an {@code Integer}
432      * object equal to the value of:
433      *
434      * <blockquote>
435      *  {@code new Integer(Integer.parseInt(s))}
436      * </blockquote>
437      *
438      * @param      s   the string to be parsed.
439      * @return     an {@code Integer} object holding the value
440      *             represented by the string argument.
441      * @exception  NumberFormatException  if the string cannot be parsed
442      *             as an integer.
443      */
444     static Integer valueOf(string s)
445     {
446         return Integer.valueOf(parseInt(s, 10));
447     }
448 
449     // Bit twiddling
450 
451     /**
452      * The number of bits used to represent an {@code int} value in two's
453      * complement binary form.
454      *
455      */
456     enum int SIZE = BYTES * Byte.SIZE; // 32;
457 
458     /**
459      * The number of bytes used to represent an {@code int} value in two's
460      * complement binary form.
461      *
462      */
463     enum int BYTES = int.sizeof; 
464 
465     /**
466      * Returns the value obtained by rotating the two's complement binary
467      * representation of the specified {@code int} value left by the
468      * specified number of bits.  (Bits shifted out of the left hand, or
469      * high-order, side reenter on the right, or low-order.)
470      *
471      * <p>Note that left rotation with a negative distance is equivalent to
472      * right rotation: {@code rotateLeft(val, -distance) == rotateRight(val,
473      * distance)}.  Note also that rotation by any multiple of 32 is a
474      * no-op, so all but the last five bits of the rotation distance can be
475      * ignored, even if the distance is negative: {@code rotateLeft(val,
476      * distance) == rotateLeft(val, distance & 0x1F)}.
477      *
478      * @param i the value whose bits are to be rotated left
479      * @param distance the number of bit positions to rotate left
480      * @return the value obtained by rotating the two's complement binary
481      *     representation of the specified {@code int} value left by the
482      *     specified number of bits.
483      */
484     static int rotateLeft(int i, int distance)
485     {
486         return (i << distance) | (i >>> -distance);
487     }
488 
489     /**
490      * Returns the value obtained by rotating the two's complement binary
491      * representation of the specified {@code int} value right by the
492      * specified number of bits.  (Bits shifted out of the right hand, or
493      * low-order, side reenter on the left, or high-order.)
494      *
495      * <p>Note that right rotation with a negative distance is equivalent to
496      * left rotation: {@code rotateRight(val, -distance) == rotateLeft(val,
497      * distance)}.  Note also that rotation by any multiple of 32 is a
498      * no-op, so all but the last five bits of the rotation distance can be
499      * ignored, even if the distance is negative: {@code rotateRight(val,
500      * distance) == rotateRight(val, distance & 0x1F)}.
501      *
502      * @param i the value whose bits are to be rotated right
503      * @param distance the number of bit positions to rotate right
504      * @return the value obtained by rotating the two's complement binary
505      *     representation of the specified {@code int} value right by the
506      *     specified number of bits.
507      */
508     static int rotateRight(int i, int distance)
509     {
510         return (i >>> distance) | (i << -distance);
511     }
512 
513     /**
514      * Returns the value obtained by reversing the order of the bytes in the
515      * two's complement representation of the specified {@code int} value.
516      *
517      * @param i the value whose bytes are to be reversed
518      * @return the value obtained by reversing the bytes in the specified
519      *     {@code int} value.
520      */
521     static int reverseBytes(int i) {
522         return (i << 24)            |
523                ((i & 0xff00) << 8)  |
524                ((i >>> 8) & 0xff00) |
525                (i >>> 24);
526     }
527 }