Эмуляция переполнений int64 в Ruby - PullRequest
0 голосов
/ 31 августа 2011

Я давний программист, но плохо знаком с Ruby. Я пытаюсь перенести алгоритм CheckRevision, используемый для проверки целостности игровых файлов перед входом в онлайн-сервис Battle.net.

Алгоритм создает хэш файлов с заданной формулой. Без скучных подробностей, он постоянно изменяет значения a, b и c, которые являются 64-битными целыми числами, или в эталонной реализации, из которой я портирую, Java long. Моя реализация верна для первых нескольких итераций, но когда int64 должен обернуться вокруг него, вместо этого он становится BigNum.

Как правильно ограничить FixNum до 64 бит, или я должен использовать другой тип?

Ответы [ 2 ]

2 голосов
/ 31 августа 2011

64-битные целые числа представлены в Ruby MRI как Bignums внутри, даже в некоторых случаях на 64-битных платформах (из-за подробностей реализации Fixnums имеют длину всего 63 бит на 64-битной платформе и песок 31 бит на 32-битных платформах)).Следовательно, будет гораздо быстрее использовать двоичные операторы "и" &:

ruby-1.9.2-p290 :001 > a = 2**128 + 1256231
 => 340282366920938463463374607431769467687 
ruby-1.9.2-p290 :002 > a & (2 ** 64 - 1)
 => 1256231 
ruby-1.9.2-p290 :003 > a & 0xffffffffffffffff
 => 1256231 

Последний вариант немного уродливее, но и быстрее, поскольку в Ruby MRI отсутствуют постоянные папки.Если вы сделаете предложение 002 в цикле, оно будет вычислять 2**64 - 1 каждый раз.

Ruby MRI - это официальный ("реализация Matz Ruby") вариант Ruby, то есть "обычный"Рубин, который использует большинство из нас.Детали, которые я перечислил здесь, могут или не могут применяться таким образом к другим реализациям, но двоичное «и» обычно быстрее или быстрее, чем оператор по модулю на любой платформе или языке.

1 голос
/ 31 августа 2011

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

...