48-битные побитовые операции в Javascript? - PullRequest
6 голосов
/ 04 апреля 2010

Мне было поручено перенести Java Java.util.Random() на JavaScript, и я столкнулся с огромной ошибкой / неточностью в производительности, используя побитовые операторы в Javascript для достаточно больших чисел. Некоторые беглые исследования утверждают, что «побитовые операторы в JavaScript по своей природе медленны», потому что внутренне кажется, что JavaScript преобразует все свои двойные значения в 32-битные целые числа со знаком для выполнения побитовых операций ( см. Здесь , чтобы узнать больше на этом.) Из-за этого я не могу сделать прямой порт генератора случайных чисел Java, и мне нужно получить те же числовые результаты, что и Java.util.Random(). Пишу что-то вроде

  this.next = function(bits) {
    if (!bits) {
       bits = 48;
    }
    this.seed = (this.seed * 25214903917 + 11) & ((1 << 48) - 1);
    return this.seed >>> (48 - bits);
  };
Код

(который является почти прямым портом Java.util.Random()) не будет работать должным образом, поскольку Javascript не может выполнять побитовые операции с целым числом такого размера.)

Я выяснил, что я могу просто создать генератор случайных чисел в 32-битном пространстве, используя алгоритм Лемера, но хитрость в том, что мне нужно получить те же значения, что и при Java.util.Random(). Что я должен сделать, чтобы сделать более быстрый и функциональный порт?

Ответы [ 4 ]

4 голосов
/ 04 апреля 2010

Вместо foo & ((1 << 48) - 1) вы можете использовать foo % Math.pow(2,48).

Все числа в Javascript являются 64-битными числами с плавающей запятой, что достаточно для представления любого 48-битного целого числа.

0 голосов
/ 04 апреля 2010

Альтернативой является использование логического массива из 48 логических значений и выполнение сдвига самостоятельно. Я не знаю, если это быстрее, хотя; но я сомневаюсь в этом, поскольку все логические значения хранятся как двойные числа.

0 голосов
/ 04 апреля 2010

Имейте в виду, что битовый сдвиг прямо эквивалентен умножению или делению на степень 2.

1 << x == 1 * Math.pow(2,x)

Это медленнее, чем битовое смещение, но позволяет вам выйти за пределы 32 бит. Это может быть более быстрым решением для bits > 32, после того как вы добавите дополнительный код, вам нужно будет поддерживать большее число битов, но вам придется выполнить некоторое профилирование, чтобы выяснить это.

0 голосов
/ 04 апреля 2010

48-битные побитовые операции невозможны в JavaScript. Вы можете использовать два числа, чтобы смоделировать это.

...