2016-05-30 4 views
0

Я реализую свой собственный генератор случайных чисел, и алгоритм, который я использую, дает мне метод nextLong(). Однако, используя этот основной метод, мне нужно реализовать другие стандартные методы, такие как nextLong(long), nextInt(), nextDouble() и т. Д., С точки зрения nextLong(). Например:Использование случайного долго для генерации случайных удвоений

public long nextLong(long n) { 
    long bits, val; 
    do { 
     bits = (nextLong() << 1) >>> 1; 
     val = bits % n; 
    } while (bits - val + n - 1 < 0L); 
    return val; 
} 

public int nextInt() { 
    return (int)nextLong(); 
} 

Как можно использовать nextDouble?

ответ

3

Не знаю, что цель сделать это сами, но вы можете просто сделать это так же встроенный Random класса делает это для nextDouble(), как описано в Javadoc:

метод nextDouble реализуется классом Random как будто:

public double nextDouble() { 
    return (((long)next(26) << 27) + next(27)) 
    /(double)(1L << 53); 
} 

поскольку вы не имеете int next(int bits) метод, но вы есть nextLong() встретились hod, используйте тот факт, что ((long)next(26) << 27) + next(27) эквивалентен next(53). Это было сделано длинным путем, потому что метод next(int) возвращает int, то есть макс. 32 бит.

Чтобы получить 53 бит из длинных, вы можете использовать либо низкий или высокий 53 бит, ваш выбор:

long low53 = nextLong() & ((1L << 53) - 1); 
long high53 = nextLong() >>> (64 - 53); 

Таким образом, ваш код будет:

private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0/(1L << 53) 
public double nextDouble() { 
    return (nextLong() >>> (64 - 53)) * DOUBLE_UNIT; 
} 

В DOUBLE_UNIT материале как Random действительно делает это внутренне, потому что умножение происходит быстрее, чем деление, например см. Floating point division vs floating point multiplication.

+0

Целью этого является реализация ** обратимого генератора случайных чисел **, который реализует историю и методы для шага состояния генератора назад и вперед. Я исследовал подкласс «Случайный», чтобы сделать это, но казалось, что взломать попытку добавить все эти функции, просто переопределив «следующий». Отсюда отдельный класс. –

+0

'((long) next (26) << 27) + next (27)' логически совпадает с 'next (53)', за исключением того, что метод 'next()' в 'Random' возвращает' int' , т.е. максимум 32 бит. 'next (53)' является таким же, как 'nextLong() & ((1L << 53) - 1)' или 'nextLong() >>> (64 - 53)', в зависимости от того, хотите ли вы с низкой или высокой 53 бит длинного. – Andreas

Смежные вопросы