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