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 }