Skip to content

Commit cf8fa90

Browse files
committed
fixed issue with negative integer seed for MT (https://issues.apache.org/jira/browse/MATH-1322)
1 parent bf7b6d5 commit cf8fa90

File tree

5 files changed

+16
-7
lines changed

5 files changed

+16
-7
lines changed

samples/mt-rand.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
echo mt_getrandmax(), "\n";
3+
mt_srand(1234567890, MT_RAND_MT19937);
4+
for ($i = 0; $i < 10; $i++) {
5+
echo mt_rand(0, 16), "\n";
6+
}
7+
?>

samples/odities.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@ Odities
33
2. .Net nextInt(int) allows 0 as a bound(maxValue).
44

55
3. FreePascal's nextInt(int) generates value between bound(exclusive) and 0 (exclusive) if bound is negative.
6+
4. FreePascal does implicit downcast for int64 to integer, thus, when using a 64 bit seed, the high 32 bits are lost.
67

7-
4. Delphi's considers bound as unsigned even if signed and generates value
8+
5. Python, for negative int seed drops the sign, while in java implementation we consider that
9+
seed as unsigned and work with it as is. This is similar to using the unsigned version of the seed in
10+
python. For instance value 0xbe991a15, as signed it is -1097262571 and as unsigned 3197704725.
11+
Java generates for -1097262571 same values python generates for 3197704725. But Python, for value
12+
-1097262571 drops the sign and generates the same values as for seed 1097262571.
13+
14+
6. Delphi's considers bound as unsigned even if signed and generates value
815
between 0 and the received parameter, returning it as a signed it after that.
916
(seems was done on purpose, to allow Math.RandomRange to function properly for a wide range).
1017
The java implementation of nextInt(int) throws exception if bound is negative.

src/main/java/ro/derbederos/untwist/ReverseRandomGenerator.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,4 @@ public interface ReverseRandomGenerator extends RandomGenerator, Serializable {
128128
* {@code 0} (inclusive) and {@code bound} (exclusive).
129129
*/
130130
long prevLong(long bound);
131-
132-
// long nextLong(long origin, long bound);
133-
//
134-
// long prevLong(long origin, long bound);
135131
}

src/main/java/ro/derbederos/untwist/ReversibleMersenneTwister.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public ReversibleMersenneTwister(long seed) {
155155
*/
156156
private void initGenRand(int seed) {
157157
// we use a long masked by 0xFFFFFFFFL as a poor man unsigned int
158-
long longMT = seed;
158+
long longMT = Integer.toUnsignedLong(seed);
159159
// NB: unlike original C code, we are working with java longs, the cast below makes masking unnecessary
160160
mt[0] = (int) longMT;
161161
for (mti = 1; mti < N; ++mti) {

src/main/java/ro/derbederos/untwist/TurboPascalRandom.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package ro.derbederos.untwist;
1818

1919
import static java.lang.Integer.toUnsignedLong;
20-
import static java.lang.Math.abs;
2120

2221
/**
2322
* Java implementation of the random number generator from Turbo Pascal 7/Delphi.

0 commit comments

Comments
 (0)