2013-03-17 21 views
5

Sto provando a generare un numero basato su un seme in C#. L'unico problema è che il seed è troppo grande per essere un int32. C'è un modo in cui posso usare a lungo il seme?C# casuale (lungo)

E sì, il seme DEVE essere lungo.

+0

Abbiate il coraggio di spiegare perché il seme * DEVE * essere "lungo"? :) Sembra che tu stia cercando di fare qualcosa in un modo sbagliato. – J0HN

+0

Perché hai bisogno di un seme lungo per un numero pseudocasuale? – tomsv

+0

@ J0HN Sto calcolando il punto in cui si producono gli umidi in minecraft. – user1599078

risposta

2

Ecco una versione C# di Java.Util.Random che ho portato su from the Java Specification.

La cosa migliore da fare è scrivere un programma Java per generare un carico di numeri e verificare che questa versione C# generi gli stessi numeri.

public sealed class JavaRng 
{ 
    public JavaRng(long seed) 
    { 
     _seed = (seed^LARGE_PRIME) & ((1L << 48) - 1); 
    } 

    public int NextInt(int n) 
    { 
     if (n <= 0) 
      throw new ArgumentOutOfRangeException("n", n, "n must be positive"); 

     if ((n & -n) == n) // i.e., n is a power of 2 
      return (int)((n * (long)next(31)) >> 31); 

     int bits, val; 

     do 
     { 
      bits = next(31); 
      val = bits % n; 
     } while (bits - val + (n-1) < 0); 
     return val; 
    } 

    private int next(int bits) 
    { 
     _seed = (_seed*LARGE_PRIME + SMALL_PRIME) & ((1L << 48) - 1); 
     return (int) (((uint)_seed) >> (48 - bits)); 
    } 

    private long _seed; 

    private const long LARGE_PRIME = 0x5DEECE66DL; 
    private const long SMALL_PRIME = 0xBL; 
} 
0

mi piacerebbe andare per la risposta fornita da qui @Dyppl: Random number in long range, is this the way?

Metti questa funzione in cui è accessibile al codice che deve generare il numero casuale:

long LongRandom(long min, long max, Random rand) 
{ 
    byte[] buf = new byte[8]; 
    rand.NextBytes(buf); 
    long longRand = BitConverter.ToInt64(buf, 0); 
    return (Math.Abs(longRand % (max - min)) + min); 
} 

Poi chiama la funzione in questo modo:

long r = LongRandom(100000000000000000, 100000000000000050, new Random()); 
+5

Per commenti nel collegamento (e testare me stesso), questo metodo non funziona: "Non funziona correttamente. LongRandom (long.MinValue, long.MaxValue, new Random()), restituisce sempre -9223372036854775808. In ogni caso, Math .Abs() distrugge un bit, lasciandoti 63 bit casuali. Non puoi fornire un numero casuale a 64 bit se hai solo 63 bit casuali. " –