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 */
020 package org.jenetics.util;
021
022 import static java.lang.String.format;
023 import static java.util.Objects.requireNonNull;
024
025 import 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 */
034 public 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 * [code]
255 * double a = 0.0;
256 * for (int i = 0; i < 10; ++i) {
257 * a = Math.nextAfter(a, Double.POSITIVE_INFINITY);
258 * }
259 *
260 * for (int i = 0; i < 19; ++i) {
261 * a = Math.nextAfter(a, Double.NEGATIVE_INFINITY);
262 * System.out.println(
263 * a + "\t" + ulpPosition(a) + "\t" + ulpDistance(0.0, a)
264 * );
265 * }
266 * [/code]
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 * [code]
797 * public static long seed() {
798 * return seed(System.nanoTime());
799 * }
800 * [/code]
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 * [code]
823 * public static long seed(final long base) {
824 * final long objectHashSeed = ((long)(new Object().hashCode()) << 32) |
825 * new Object().hashCode();
826 * long seed = base ^ objectHashSeed;
827 * seed ^= seed << 17;
828 * seed ^= seed >>> 31;
829 * seed ^= seed << 8;
830 * return seed;
831 * }
832 * [/code]
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 }
|