001/* 002 * Java Genetic Algorithm Library (jenetics-1.6.0). 003 * Copyright (c) 2007-2014 Franz Wilhelmstötter 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 * Author: 018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at) 019 */ 020package org.jenetics.util; 021 022import static java.lang.String.format; 023import static java.util.Objects.requireNonNull; 024 025import java.util.Random; 026 027/** 028 * This object contains mathematical helper functions. 029 * 030 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> 031 * @since 1.0 032 * @version 1.4 — <em>$Date: 2014-02-15 $</em> 033 */ 034public final class math extends StaticObject { 035 private math() {} 036 037 /** 038 * Add to long values and throws an ArithmeticException in the case of an 039 * overflow. 040 * 041 * @param a the first summand. 042 * @param b the second summand. 043 * @return the sum of the given values. 044 * @throws ArithmeticException if the summation would lead to an overflow. 045 */ 046 public static long plus(final long a, final long b) { 047 final long z = a + b; 048 if (((a^z) & (b^z)) < 0) { 049 throw new ArithmeticException(format("Overflow: %d + %d", a, b)); 050 } 051 052 return z; 053 } 054 055 /** 056 * Subtracts to long values and throws an ArithmeticException in the case of 057 * an overflow. 058 * 059 * @param a the minuend. 060 * @param b the subtrahend. 061 * @return the difference of the given values. 062 * @throws ArithmeticException if the subtraction would lead to an overflow. 063 */ 064 public static long minus(final long a, final long b) { 065 final long z = a - b; 066 if (((a^b) & (a^z)) < 0) { 067 throw new ArithmeticException(format("Overflow: %d - %d", a, b)); 068 } 069 070 return z; 071 } 072 073 /** 074 * Implementation of the <a href="http://en.wikipedia.org/wiki/Kahan_summation_algorithm"> 075 * Kahan summation algorithm</a>. 076 * 077 * @param values the values to sum up. 078 * @return the sum of the given {@code values}. 079 * @throws NullPointerException if the given array is {@code null}. 080 * 081 * @deprecated Use {@link math.statistics#sum(double[])} instead. 082 */ 083 @Deprecated 084 public static double sum(final double[] values) { 085 return statistics.sum(values); 086 } 087 088 /** 089 * Add the values of the given array. 090 * 091 * @param values the values to add. 092 * @return the values sum. 093 * @throws NullPointerException if the values are null; 094 * 095 * @deprecated Use {@link math.statistics#sum(long[])} instead. 096 */ 097 @Deprecated 098 public static long sum(final long[] values) { 099 return statistics.sum(values); 100 } 101 102 /** 103 * Normalize the given double array, so that it sum to one. The 104 * normalization is performed in place and the same {@code values} are 105 * returned. 106 * 107 * @param values the values to normalize. 108 * @return the {@code values} array. 109 * @throws NullPointerException if the given double array is {@code null}. 110 */ 111 public static double[] normalize(final double[] values) { 112 final double sum = 1.0/statistics.sum(values); 113 for (int i = values.length; --i >= 0;) { 114 values[i] = values[i]*sum; 115 } 116 117 return values; 118 } 119 120 /** 121 * Return the minimum value of the given double array. 122 * 123 * @param values the double array. 124 * @return the minimum value or {@link Double#NaN} if the given array is 125 * empty. 126 * @throws NullPointerException if the given array is {@code null}. 127 * 128 * @deprecated Use {@link math.statistics#min(double[])} instead. 129 */ 130 @Deprecated 131 public static double min(final double[] values) { 132 return statistics.min(values); 133 } 134 135 /** 136 * Return the maximum value of the given double array. 137 * 138 * @param values the double array. 139 * @return the maximum value or {@link Double#NaN} if the given array is 140 * empty. 141 * @throws NullPointerException if the given array is {@code null}. 142 * 143 * @deprecated Use {@link math.statistics#max(double[])} instead. 144 */ 145 @Deprecated 146 public static double max(final double[] values) { 147 return statistics.max(values); 148 } 149 150 /** 151 * <i>Clamping</i> a value between a pair of boundary values. 152 * <i>Note: using clamp with floating point numbers may give unexpected 153 * results if one of the values is {@code NaN}.</i> 154 * 155 * @param v the value to <i>clamp</i> 156 * @param lo the lower bound. 157 * @param hi the upper bound. 158 * @return The clamped value: 159 * <ul> 160 * <li>{@code lo if v < lo}</li> 161 * <li>{@code hi if hi < v}</li> 162 * <li>{@code otherwise, v}</li> 163 * </ul> 164 */ 165 public static double clamp(final double v, final double lo, final double hi) { 166 return v < lo ? lo : (v > hi ? hi : v); 167 } 168 169 /** 170 * Component wise multiplication of the given double array. 171 * 172 * @param values the double values to multiply. 173 * @param multiplier the multiplier. 174 * @throws NullPointerException if the given double array is {@code null}. 175 */ 176 public static void times(final double[] values, final double multiplier) { 177 for (int i = values.length; --i >= 0;) { 178 values[i] *= multiplier; 179 } 180 } 181 182 /** 183 * Component wise division of the given double array. 184 * 185 * @param values the double values to divide. 186 * @param divisor the divisor. 187 * @throws NullPointerException if the given double array is {@code null}. 188 */ 189 public static void divide(final double[] values, final double divisor) { 190 for (int i = values.length; --i >= 0;) { 191 values[i] /= divisor; 192 } 193 } 194 195 /** 196 * Binary exponentiation algorithm. 197 * 198 * @param b the base number. 199 * @param e the exponent. 200 * @return {@code b^e}. 201 */ 202 public static long pow(final long b, final long e) { 203 long base = b; 204 long exp = e; 205 long result = 1; 206 207 while (exp != 0) { 208 if ((exp & 1) != 0) { 209 result *= base; 210 } 211 exp >>>= 1; 212 base *= base; 213 } 214 215 return result; 216 } 217 218 static int gcd(final int a, final int b) { 219 int x = a; 220 int y = b; 221 int mod = x%y; 222 223 while (mod != 0) { 224 x = y; 225 y = mod; 226 mod = x%y; 227 } 228 229 return y; 230 } 231 232 static boolean isMultiplicationSave(final int a, final int b) { 233 final long m = (long)a*(long)b; 234 return ((int)m) == m; 235 } 236 237 /** 238 * Return the <a href="http://en.wikipedia.org/wiki/Unit_in_the_last_place">ULP</a> 239 * distance of the given two double values. 240 * 241 * @param a first double. 242 * @param b second double. 243 * @return the ULP distance. 244 * @throws ArithmeticException if the distance doesn't fit in a long value. 245 */ 246 public static long ulpDistance(final double a, final double b) { 247 return minus(ulpPosition(a), ulpPosition(b)); 248 } 249 250 /** 251 * Calculating the <a href="http://en.wikipedia.org/wiki/Unit_in_the_last_place">ULP</a> 252 * position of a double number. 253 * 254 *267 * 268 * The code fragment above will create the following output: 269 * <pre> 270 * 4.4E-323 9 9 271 * 4.0E-323 8 8 272 * 3.5E-323 7 7 273 * 3.0E-323 6 6 274 * 2.5E-323 5 5 275 * 2.0E-323 4 4 276 * 1.5E-323 3 3 277 * 1.0E-323 2 2 278 * 4.9E-324 1 1 279 * 0.0 0 0 280 * -4.9E-324 -1 1 281 * -1.0E-323 -2 2 282 * -1.5E-323 -3 3 283 * -2.0E-323 -4 4 284 * -2.5E-323 -5 5 285 * -3.0E-323 -6 6 286 * -3.5E-323 -7 7 287 * -4.0E-323 -8 8 288 * -4.4E-323 -9 9 289 * </pre> 290 * 291 * @param a the double number. 292 * @return the ULP position. 293 */ 294 public static long ulpPosition(final double a) { 295 long t = Double.doubleToLongBits(a); 296 if (t < 0) { 297 t = Long.MIN_VALUE - t; 298 } 299 return t; 300 } 301 302 /** 303 * Selects a random subset of size {@code k} from a set of size {@code n}. 304 * 305 * @see #subset(int, int[]) 306 * 307 * @param n the size of the set. 308 * @param k the size of the subset. 309 * @throws IllegalArgumentException if {@code n < k}, {@code k == 0} or if 310 * {@code n*k} will cause an integer overflow. 311 * @return the subset array. 312 */ 313 public static int[] subset(final int n, final int k) { 314 return subset(n, k, RandomRegistry.getRandom()); 315 } 316 317 /** 318 * Selects a random subset of size {@code k} from a set of size {@code n}. 319 * 320 * @see #subset(int, int[], Random) 321 * 322 * @param n the size of the set. 323 * @param k the size of the subset. 324 * @param random the random number generator used. 325 * @throws NullPointerException if {@code random} is {@code null}. 326 * @throws IllegalArgumentException if {@code n < k}, {@code k == 0} or if 327 * {@code n*k} will cause an integer overflow. 328 * @return the subset array. 329 */ 330 public static int[] subset(final int n, final int k, final Random random) { 331 requireNonNull(random, "Random"); 332 if (k <= 0) { 333 throw new IllegalArgumentException(format( 334 "Subset size smaller or equal zero: %s", k 335 )); 336 } 337 if (n < k) { 338 throw new IllegalArgumentException(format( 339 "n smaller than k: %s < %s.", n, k 340 )); 341 } 342 343 final int[] sub = new int[k]; 344 subset(n, sub,random); 345 return sub; 346 } 347 348 /** 349 * <p> 350 * Selects a random subset of size {@code sub.length} from a set of size 351 * {@code n}. 352 * </p> 353 * 354 * <p> 355 * <em>Authors:</em> 356 * FORTRAN77 original version by Albert Nijenhuis, Herbert Wilf. This 357 * version based on the C++ version by John Burkardt. 358 * </p> 359 * 360 * <p><em><a href="https://people.scs.fsu.edu/~burkardt/c_src/subset/subset.html"> 361 * Reference:</a></em> 362 * Albert Nijenhuis, Herbert Wilf, 363 * Combinatorial Algorithms for Computers and Calculators, 364 * Second Edition, 365 * Academic Press, 1978, 366 * ISBN: 0-12-519260-6, 367 * LC: QA164.N54. 368 * </p> 369 * 370 * @param n the size of the set. 371 * @param sub the sub set array. 372 * @throws NullPointerException if {@code sub} is {@code null}. 373 * @throws IllegalArgumentException if {@code n < sub.length}, 374 * {@code sub.length == 0} or {@code n*sub.length} will cause an 375 * integer overflow. 376 */ 377 public static void subset(final int n, final int sub[]) { 378 subset(n, sub, RandomRegistry.getRandom()); 379 } 380 381 /** 382 * <p> 383 * Selects a random subset of size {@code sub.length} from a set of size 384 * {@code n}. 385 * </p> 386 * 387 * <p> 388 * <em>Authors:</em> 389 * FORTRAN77 original version by Albert Nijenhuis, Herbert Wilf. This 390 * version based on the C++ version by John Burkardt. 391 * </p> 392 * 393 * <p><em><a href="https://people.scs.fsu.edu/~burkardt/c_src/subset/subset.html"> 394 * Reference:</a></em> 395 * Albert Nijenhuis, Herbert Wilf, 396 * Combinatorial Algorithms for Computers and Calculators, 397 * Second Edition, 398 * Academic Press, 1978, 399 * ISBN: 0-12-519260-6, 400 * LC: QA164.N54. 401 * </p> 402 * 403 * @param n the size of the set. 404 * @param sub the sub set array. 405 * @param random the random number generator used. 406 * @throws NullPointerException if {@code sub} or {@code random} is 407 * {@code null}. 408 * @throws IllegalArgumentException if {@code n < sub.length}, 409 * {@code sub.length == 0} or {@code n*sub.length} will cause an 410 * integer overflow. 411 */ 412 public static int[] subset(final int n, final int sub[], final Random random) { 413 requireNonNull(random, "Random"); 414 requireNonNull(sub, "Sub set array"); 415 416 final int k = sub.length; 417 if (k <= 0) { 418 throw new IllegalArgumentException(format( 419 "Subset size smaller or equal zero: %s", k 420 )); 421 } 422 if (n < k) { 423 throw new IllegalArgumentException(format( 424 "n smaller than k: %s < %s.", n, k 425 )); 426 } 427 if (!math.isMultiplicationSave(n, k)) { 428 throw new IllegalArgumentException(format( 429 "n*sub.length > Integer.MAX_VALUE (%s*%s = %s > %s)", 430 n, sub.length, (long)n*(long)k, Integer.MAX_VALUE 431 )); 432 } 433 434 if (sub.length == n) { 435 for (int i = 0; i < sub.length; ++i) { 436 sub[i] = i; 437 } 438 return sub; 439 } 440 441 for (int i = 0; i < k; ++i) { 442 sub[i] = (i*n)/k; 443 } 444 445 int l = 0; 446 int ix = 0; 447 for (int i = 0; i < k; ++i) { 448 do { 449 ix = nextInt(random, 1, n); 450 l = (ix*k - 1)/n; 451 } while (sub[l] >= ix); 452 453 sub[l] = sub[l] + 1; 454 } 455 456 int m = 0; 457 int ip = 0; 458 int is = k; 459 for (int i = 0; i < k; ++i) { 460 m = sub[i]; 461 sub[i] = 0; 462 463 if (m != (i*n)/k) { 464 ip = ip + 1; 465 sub[ip - 1] = m; 466 } 467 } 468 469 int ihi = ip; 470 int ids = 0; 471 for (int i = 1; i <= ihi; ++i) { 472 ip = ihi + 1 - i; 473 l = 1 + (sub[ip - 1]*k - 1)/n; 474 ids = sub[ip - 1] - ((l - 1)*n)/k; 475 sub[ip - 1] = 0; 476 sub[is - 1] = l; 477 is = is - ids; 478 } 479 480 int ir = 0; 481 int m0 = 0; 482 for (int ll = 1; ll <= k; ++ll) { 483 l = k + 1 - ll; 484 485 if (sub[l - 1] != 0) { 486 ir = l; 487 m0 = 1 + ((sub[l - 1] - 1)*n)/k; 488 m = (sub[l-1]*n)/k - m0 + 1; 489 } 490 491 ix = nextInt(random, m0, m0 + m - 1); 492 493 int i = l + 1; 494 while (i <= ir && ix >= sub[i - 1]) { 495 ix = ix + 1; 496 sub[ i- 2] = sub[i - 1]; 497 i = i + 1; 498 } 499 500 sub[i - 2] = ix; 501 --m; 502 } 503 504 return sub; 505 } 506 507 private static int nextInt(final Random random, final int a, final int b) { 508 return a == b ? a - 1 : random.nextInt(b - a) + a; 509 } 510 511 /** 512 * Some helper method concerning statistics. 513 * 514 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> 515 * @since 1.3 516 * @version 1.3 — <em>$Date: 2014-02-15 $</em> 517 */ 518 public static final class statistics extends StaticObject { 519 private statistics() {} 520 521 /** 522 * Return the minimum value of the given double array. 523 * 524 * @param values the double array. 525 * @return the minimum value or {@link Double#NaN} if the given array is 526 * empty. 527 * @throws NullPointerException if the given array is {@code null}. 528 */ 529 public static double min(final double[] values) { 530 double min = Double.NaN; 531 if (values.length > 0) { 532 min = values[0]; 533 534 for (int i = values.length; --i >= 1;) { 535 if (values[i] < min) { 536 min = values[i]; 537 } 538 } 539 } 540 541 return min; 542 } 543 544 /** 545 * Return the maximum value of the given double array. 546 * 547 * @param values the double array. 548 * @return the maximum value or {@link Double#NaN} if the given array is 549 * empty. 550 * @throws NullPointerException if the given array is {@code null}. 551 */ 552 public static double max(final double[] values) { 553 double max = Double.NaN; 554 if (values.length > 0) { 555 max = values[0]; 556 557 for (int i = values.length; --i >= 1;) { 558 if (values[i] > max) { 559 max = values[i]; 560 } 561 } 562 } 563 564 return max; 565 } 566 567 /** 568 * Implementation of the <a href="http://en.wikipedia.org/wiki/Kahan_summation_algorithm"> 569 * Kahan summation algorithm</a>. 570 * 571 * @param values the values to sum up. 572 * @return the sum of the given {@code values}. 573 * @throws NullPointerException if the given array is {@code null}. 574 */ 575 public static double sum(final double[] values) { 576 double sum = 0.0; 577 double c = 0.0; 578 double y = 0.0; 579 double t = 0.0; 580 581 for (int i = values.length; --i >= 0;) { 582 y = values[i] - c; 583 t = sum + y; 584 c = t - sum - y; 585 sum = t; 586 } 587 588 return sum; 589 } 590 591 /** 592 * Add the values of the given array. 593 * 594 * @param values the values to add. 595 * @return the values sum. 596 * @throws NullPointerException if the values are null; 597 */ 598 public static long sum(final long[] values) { 599 long sum = 0; 600 for (int i = values.length; --i >= 0;) { 601 sum += values[i]; 602 } 603 return sum; 604 } 605 606 } 607 608 /** 609 * Some helper method concerning random numbers and random seed generation. 610 * 611 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> 612 * @since 1.1 613 * @version 1.2 — <em>$Date: 2014-02-15 $</em> 614 */ 615 public static final class random extends StaticObject { 616 private random() {} 617 618 /** 619 * Returns a pseudorandom, uniformly distributed int value between min 620 * and max (min and max included). 621 * 622 * @param min lower bound for generated integer 623 * @param max upper bound for generated integer 624 * @return a random integer greater than or equal to {@code min} and 625 * less than or equal to {@code max} 626 * @throws IllegalArgumentException if {@code min >= max} 627 */ 628 public static int nextInt( 629 final Random random, 630 final int min, final int max 631 ) { 632 if (min >= max) { 633 throw new IllegalArgumentException(format( 634 "Min >= max: %d >= %d", min, max 635 )); 636 } 637 638 final int diff = max - min + 1; 639 int result = 0; 640 641 if (diff <= 0) { 642 do { 643 result = random.nextInt(); 644 } while (result < min || result > max); 645 } else { 646 result = random.nextInt(diff) + min; 647 } 648 649 return result; 650 } 651 652 /** 653 * Returns a pseudorandom, uniformly distributed int value between min 654 * and max (min and max included). 655 * 656 * @param min lower bound for generated long integer 657 * @param max upper bound for generated long integer 658 * @return a random long integer greater than or equal to {@code min} 659 * and less than or equal to {@code max} 660 * @throws IllegalArgumentException if {@code min >= max} 661 */ 662 public static long nextLong( 663 final Random random, 664 final long min, final long max 665 ) { 666 if (min >= max) { 667 throw new IllegalArgumentException(format( 668 "min >= max: %d >= %d.", min, max 669 )); 670 } 671 672 final long diff = (max - min) + 1; 673 long result = 0; 674 675 if (diff <= 0) { 676 do { 677 result = random.nextLong(); 678 } while (result < min || result > max); 679 } else if (diff < Integer.MAX_VALUE) { 680 result = random.nextInt((int)diff) + min; 681 } else { 682 result = nextLong(random, diff) + min; 683 } 684 685 return result; 686 } 687 688 /** 689 * Returns a pseudorandom, uniformly distributed int value between 0 690 * (inclusive) and the specified value (exclusive), drawn from the given 691 * random number generator's sequence. 692 * 693 * @param random the random engine used for creating the random number. 694 * @param n the bound on the random number to be returned. Must be 695 * positive. 696 * @return the next pseudorandom, uniformly distributed int value 697 * between 0 (inclusive) and n (exclusive) from the given random 698 * number generator's sequence 699 * @throws IllegalArgumentException if n is smaller than 1. 700 */ 701 public static long nextLong(final Random random, final long n) { 702 if (n <= 0) { 703 throw new IllegalArgumentException(format( 704 "n is smaller than one: %d", n 705 )); 706 } 707 708 long bits; 709 long result; 710 do { 711 bits = random.nextLong() & 0x7fffffffffffffffL; 712 result = bits%n; 713 } while (bits - result + (n - 1) < 0); 714 715 return result; 716 } 717 718 /** 719 * Returns a pseudorandom, uniformly distributed double value between 720 * min (inclusively) and max (exclusively). 721 * 722 * @param random the random engine used for creating the random number. 723 * @param min lower bound for generated float value 724 * @param max upper bound for generated float value 725 * @return a random float greater than or equal to {@code min} and less 726 * than to {@code max} 727 */ 728 public static float nextFloat( 729 final Random random, 730 final float min, final float max 731 ) { 732 return random.nextFloat()*(max - min) + min; 733 } 734 735 /** 736 * Returns a pseudorandom, uniformly distributed double value between 737 * min (inclusively) and max (exclusively). 738 * 739 * @param random the random engine used for creating the random number. 740 * @param min lower bound for generated double value 741 * @param max upper bound for generated double value 742 * @return a random double greater than or equal to {@code min} and less 743 * than to {@code max} 744 */ 745 public static double nextDouble( 746 final Random random, 747 final double min, final double max 748 ) { 749 return random.nextDouble()*(max - min) + min; 750 } 751 752 /** 753 * Create a new <em>seed</em> byte array of the given length. 754 * 755 * @see #seed(byte[]) 756 * @see #seed() 757 * 758 * @param length the length of the returned byte array. 759 * @return a new <em>seed</em> byte array of the given length 760 * @throws NegativeArraySizeException if the given length is smaller 761 * than zero. 762 */ 763 public static byte[] seedBytes(final int length) { 764 return seed(new byte[length]); 765 } 766 767 /** 768 * Fills the given byte array with random bytes, created by successive 769 * calls of the {@link #seed()} method. 770 * 771 * @see #seed() 772 * 773 * @param seed the byte array seed to fill with random bytes. 774 * @return the given byte array, for method chaining. 775 * @throws NullPointerException if the {@code seed} array is 776 * {@code null}. 777 */ 778 public static byte[] seed(final byte[] seed) { 779 for (int i = 0, len = seed.length; i < len;) { 780 int n = Math.min(len - i, Long.SIZE/Byte.SIZE); 781 782 for (long x = seed(); n-- > 0; x >>= Byte.SIZE) { 783 seed[i++] = (byte)x; 784 } 785 } 786 787 return seed; 788 } 789 790 /** 791 * Calculating a 64 bit seed value which can be used for initializing 792 * PRNGs. This method uses a combination of {@code System.nanoTime()} 793 * and {@code new Object().hashCode()} calls to create a reasonable safe 794 * seed value: 795 * <p/> 796 *<a name="line.254"></a> <span class="sourceLineNo">255</span> * double a = 0.0;<a name="line.255"></a> <span class="sourceLineNo">256</span> * for (int i = 0; i < 10; ++i) {<a name="line.256"></a> <span class="sourceLineNo">257</span> * a = Math.nextAfter(a, Double.POSITIVE_INFINITY);<a name="line.257"></a> <span class="sourceLineNo">258</span> * }<a name="line.258"></a> <span class="sourceLineNo">259</span> *<a name="line.259"></a> <span class="sourceLineNo">260</span> * for (int i = 0; i < 19; ++i) {<a name="line.260"></a> <span class="sourceLineNo">261</span> * a = Math.nextAfter(a, Double.NEGATIVE_INFINITY);<a name="line.261"></a> <span class="sourceLineNo">262</span> * System.out.println(<a name="line.262"></a> <span class="sourceLineNo">263</span> * a + "\t" + ulpPosition(a) + "\t" + ulpDistance(0.0, a)<a name="line.263"></a> <span class="sourceLineNo">264</span> * );<a name="line.264"></a> <span class="sourceLineNo">265</span> * }<a name="line.265"></a>
801 * <p/> 802 * This method passes all of the statistical tests of the 803 * <a href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> 804 * dieharder</a> test suite—executed on a linux machine with 805 * JDK version 1.7. <em>Since there is no prove that this will the case 806 * for every Java version and OS, it is recommended to only use this 807 * method for seeding other PRNGs.</em> 808 * 809 * @see #seed(long) 810 * 811 * @return the random seed value. 812 */ 813 public static long seed() { 814 return seed(System.nanoTime()); 815 } 816 817 /** 818 * Uses the given {@code base} value to create a reasonable safe seed 819 * value. This is done by combining it with values of 820 * {@code new Object().hashCode()}: 821 * <p/> 822 *<a name="line.796"></a> <span class="sourceLineNo">797</span> * public static long seed() {<a name="line.797"></a> <span class="sourceLineNo">798</span> * return seed(System.nanoTime());<a name="line.798"></a> <span class="sourceLineNo">799</span> * }<a name="line.799"></a>
833 * 834 * @param base the base value of the seed to create 835 * @return the created seed value. 836 */ 837 public static long seed(final long base) { 838 return mix(base, objectHashSeed()); 839 } 840 841 private static long mix(final long a, final long b) { 842 long c = a^b; 843 c ^= c << 17; 844 c ^= c >>> 31; 845 c ^= c << 8; 846 return c; 847 } 848 849 private static long objectHashSeed() { 850 return ((long)(new Object().hashCode()) << 32) | 851 new Object().hashCode(); 852 } 853 854 } 855 856}<a name="line.822"></a> <span class="sourceLineNo">823</span> * public static long seed(final long base) {<a name="line.823"></a> <span class="sourceLineNo">824</span> * final long objectHashSeed = ((long)(new Object().hashCode()) << 32) |<a name="line.824"></a> <span class="sourceLineNo">825</span> * new Object().hashCode();<a name="line.825"></a> <span class="sourceLineNo">826</span> * long seed = base ^ objectHashSeed;<a name="line.826"></a> <span class="sourceLineNo">827</span> * seed ^= seed << 17;<a name="line.827"></a> <span class="sourceLineNo">828</span> * seed ^= seed >>> 31;<a name="line.828"></a> <span class="sourceLineNo">829</span> * seed ^= seed << 8;<a name="line.829"></a> <span class="sourceLineNo">830</span> * return seed;<a name="line.830"></a> <span class="sourceLineNo">831</span> * }<a name="line.831"></a>