Порт Случайного генератора от C до Java?

Я смог воспроизвести это поведение с помощью Vista и Cygwin 1.7.0.

  • Две обратные черты вызывают ошибку
  • либо три или работают четыре обратной косой черты
  • Пять дают ту же ошибку

Две обратные косые черты становятся одной обратной косой чертой в оболочке, которая затем в sed ускользает от косой черты который является средним разделителем.

\\/ -> \/ (which makes the forward slash a regular character instead of a delimiter)

Три из них: первые два становятся едиными в оболочке, которые затем выходят из третьего в sed

\\\/ -> \\/

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

\\\\/ -> \\/ 

Edit:

О, я забыл сказать, что как одинарные кавычки, так и двойные кавычки работали то же самое для меня (cmd.exe не делает различия, которые делает Bash и др.).

19
задан martinus 29 December 2008 в 17:21
поделиться

6 ответов

действительно ли кто-либо может портировать это на Java? Как это работает, когда Вы только имеете числа со знаком в наличии?

Никакое Напряжение! a=18782, таким образом, самое большое t могло когда-либо быть, не является достаточно большим для порождения подписанный по сравнению с неподписанными проблемами. Необходимо было бы "обновить" результат использования Q к значению, равному 32-разрядному неподписанному числу перед использованием его где угодно. например, если бы Q int (32-разрядный подписанный) затем, необходимо было бы сделать это перед использованием его в t=a*Q[i]+c оператор, например,

t=a*(((long)Q[i])&0xffffffffL)+c

где это (((длинный) Q [я]) & 0xffffffffL) бизнес продвигает Q [я] 64-разрядный # и гарантирует, что его высокие 32 бита являются 0. (редактирование:Примечание: Вам нужен 0xffffffffL здесь. Java делает неправильную вещь при использовании 0xffffffff кажется, что это "оптимизирует" себя к неправильному ответу & Вы получаете отрицательное число, если Q [я] высоко бит равняется 1.)

необходимо смочь проверить это путем выполнения алгоритмов в C++ и Java для сравнения выводов.

редактирование: вот выстрел в него. Я пытался выполнить его в C++ и Java для N=100000; они оба соответствие. Извинения, если я использовал плохие идиомы Java, я все еще довольно плохо знаком с Java.

C++:

// marsaglia2003.cpp 

#include <stdio.h>
#include <stdlib.h> // for atoi

class m2003
{
    enum {c0=362436, sz=4096, mask=4095};
    unsigned long Q[sz];
    unsigned long c;
    short i;

public:
    m2003()
    {
        // a real program would seed this with a good random seed
        // i'm just putting in something that makes the output interesting
        for (int j = 0; j < sz; ++j)
            Q[j] = j + (j << 16);
        i = 4095;
        c = c0;
    }

    unsigned long next()
    {
        unsigned long long t, a=18782LL;
        unsigned long x;
        unsigned long r=0xfffffffe;
        i = (i+1)&mask;
        t=a*Q[i]+c;
        c=(unsigned long)(t>>32);
        x=(unsigned long)t + c;
        if (x<c)
        {
            x++;
            c++;
        }
        return (Q[i]=r-x);
    }
};

int main(int argc, char *argv[])
{
    m2003 generator;
    int n = 100;
    if (argc > 1)
        n = atoi(argv[1]);

    for (int i = 0; i < n; ++i)
    {
        printf("%08x\n", generator.next());
    }
    return 0;
}

Java: (медленнее, чем скомпилированный C++, но это соответствует для N=100000)

// Marsaglia2003.java

import java.util.*;

class Marsaglia2003
{
    final static private int sz=4096;
    final static private int mask=4095;
    final private int[] Q = new int[sz];
    private int c=362436;
    private int i=sz-1;

    public Marsaglia2003()
    {
        // a real program would seed this with a good random seed
        // i'm just putting in something that makes the output interesting
        for (int j = 0; j < sz; ++j)
            Q[j] = j + (j << 16);
    }

  public int next() 
    // note: returns a SIGNED 32-bit number.
    // if you want to use as unsigned, cast to a (long), 
    // then AND it with 0xffffffffL
    {
        long t, a=18782;
        int x;
        int r=0xfffffffe;
        i = (i+1)&mask;
        long Qi = ((long)Q[i]) & 0xffffffffL; // treat as unsigned 32-bit
        t=a*Qi+c;
        c=(int)(t>>32); 
           // because "a" is relatively small this result is also small

        x=((int)t) + c;
        if (x<c && x>=0) // tweak to treat x as unsigned
        {
            x++;
            c++;
        }
        return (Q[i]=r-x);
    }

    public static void main(String args[])
    {
        Marsaglia2003 m2003 = new Marsaglia2003();

        int n = 100;
        if (args.length > 0)
            n = Integer.parseInt(args[0]);
        for (int i = 0; i < n; ++i)
        {
            System.out.printf("%08x\n", m2003.next());
        }
    }
};
14
ответ дан 30 November 2019 в 02:07
поделиться

Большую часть времени нет никакой потребности использовать большие числовые типы для моделирования неподписанных типов в Java.

Для дополнения, вычитания, умножения, оставленного сдвига, логические операции, равенство и бросающий к меньшему числовому типу не имеет значения, подписываются ли операнды или не подписаны, результатом будет то же независимо, просматриваемый как немного шаблона.

Для смещения к правильному использованию>> для со знаком,>>> для неподписанного.

Для кастинга со знаком к большему типу просто делают это.

Для неподписанного кастинга от меньшего типа до долгого использования & с маской типа жаждут меньшего типа. Например, короткий к долго: s & 0xffffL.

Для неподписанного кастинга от меньшего типа до международного использования & с маской интервала типа, Например, байт к интервалу: b & 0xff.

Иначе любят в международном случае и применяют бросок на вершину. Например, байт к короткому: (короткий) (b & 0xff).

Для операторов сравнения < и т.д. и подразделение самое легкое должно бросить к большему типу и сделать операцию там. Но там также существуют другие опции, например, делают сравнения после добавления соответствующего смещения.

43
ответ дан 30 November 2019 в 02:07
поделиться

Если Вы реализуете RNG в Java, лучше разделять на подклассы java.util. Случайный класс и переопределение защищенный следующий (интервал) метод (Ваш RNG является затем общедоступной заменой для java.util. Случайный). Следующий (международный) метод касается случайным образом сгенерированных битов, не, какие долины те биты могли бы представить. Другие (общедоступные) методы java.util. Случайное использование эти биты для построения случайных значений различных типов.

5
ответ дан 30 November 2019 в 02:07
поделиться

Так же, как быстрый ориентир, который может (или не может) помогают Вам, я нашел эту ссылку:

http://darksleep.com/player/JavaAndUnsignedTypes.html

1
ответ дан 30 November 2019 в 02:07
поделиться

Для обхождения отсутствия Java неподписанных типов, Вы обычно храните числа в большем типе переменной (таким образом, короткие замыкания обновлены до ints, ints к длинному). Так как Вы используете длинные переменные здесь, Вы оказываетесь перед необходимостью подходить к BigInteger, который, вероятно, разрушит любые выигрыши в быстродействии, что Вы выходите из алгоритма.

2
ответ дан 30 November 2019 в 02:07
поделиться

Можно использовать числа со знаком, если значения не переполняются..., например, долго в Java, целое число со знаком на 64 бита. Однако намерение в этом алгоритме, кажется, для использования неподписанного значения на 64 бита, и раз так я думаю, что Вам не повезло бы с основными типами.

Вы могли использовать целые числа мультиточности, обеспеченные в библиотеках классов Java ( BigInteger). Или Вы могли реализовать свой собственный неподписанный тип на 64 бита как Объект, содержащий два Java longs для представления младших значащих и старших значащих слов (но необходимо будет реализовать основные арифметические операции сами в классе).

0
ответ дан 30 November 2019 в 02:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: