Learning C ++. Before that, I studied Java. For learning purposes, I port part of the standard java.util.Random class in C ++.

public class Random { private long seed; private long multiplier; private long addend; private long mask; private final double DOUBLE_UNIT; public Random(long seed) { this.seed = seed; multiplier = 0x5DEECE66DL; addend = 0xBL; mask = (1L << 48) - 1; DOUBLE_UNIT = 0x1.0p-53; } public double nextValue() { return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT; } private int next(int bits) { long nextSeed = (seed * multiplier + addend) & mask; seed = nextSeed; return (int)(nextSeed >>> (48 - bits)); } } 

corresponding C ++ class:

 class Random { private: long long seed; long long multiplier; long long addend; long long mask; const double DOUBLE_UNIT = 0x1.0p-53; int next(int bits) { long long nextSeed = (seed * multiplier + addend) & mask; seed = nextSeed; return (int)(nextSeed >> (48 - bits)); } public: Random(long long seed):seed(seed) { multiplier = 0x5DEECE66DLL; addend = 0xBLL; mask = (1LL << 48) - 1; } double nextValue() { return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT; } }; 

What does not work: the Java class, as it should, gives the result in the range from 0 to 1. The C ++ class gives the result outside this range. When creating objects of these classes, they are given identical keys.

As I tried to solve the problem: as far as I can tell, the data types of the variables (integer or real) and their bit width I picked up the same for the java and c ++ classes; java >>> operator and C ++ operator >> have the same behavior.

What tools used: For java - JDK11, the class java.util.Random was taken from this version. For c ++, compiled with g ++ (MinGW.org GCC-6.3.0-1) 6.3.0 using the g ++ command main.cpp -o main.exe.

Question: Tell me please - where did I make a mistake when porting a java class in C ++? What is the cause of different behavior?

  • one
    Listen, do not open America through the window ... Oh, where, where, but in C ++, random numbers are implemented very carefully and reliably ... - Harry
  • one
    Yes, carefully and reliably. And implemented better than I can do at the moment. But as I wrote - this is for training purposes. I was looking at PRNG code implemented in C ++. But I understood badly. Therefore, I decided to touch the topic in practice, on some very simple example. Since I know Java more or less, I decided to "get closer to understanding" through copying and comparing. - Bakuard 2:44 pm

1 answer 1

Perhaps the fact is that one long not replaced by long long

 return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT; 

use int64_t type for reliability