В соответствии со стандартом ECMAScript все числа в JavaScript являются (64-разрядными IEEE 754) числами с плавающей запятой.
Однако все 32-разрядные целые числа могут быть точно представлены как числа с плавающей запятой. Вы можете форсировать результат до 32 бит, используя соответствующий побитовый оператор, например:
x = (a * b) >>> 0; // force to unsigned int32
x = (a * b) | 0; // force to signed int32
Странно, но это стандарт.
(Между прочим, это поведение округления одна из наиболее часто сообщаемых "ошибок" в движке JavaScript Firefox. Похоже, об этом уже было сообщено 3 раза в этом году ...)
Что касается воспроизводимых случайных чисел в JavaScript, тест V8 использует это:
// To make the benchmark results predictable, we replace Math.random
// with a 100% deterministic alternative.
Math.random = (function() {
var seed = 49734321;
return function() {
// Robert Jenkins' 32 bit integer hash function.
seed = ((seed + 0x7ed55d16) + (seed << 12)) & 0xffffffff;
seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff;
seed = ((seed + 0x165667b1) + (seed << 5)) & 0xffffffff;
seed = ((seed + 0xd3a2646c) ^ (seed << 9)) & 0xffffffff;
seed = ((seed + 0xfd7046c5) + (seed << 3)) & 0xffffffff;
seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff;
return (seed & 0xfffffff) / 0x10000000;
};
})();