Javascript 中的 16 位二进制算术
16-bit binary arithmetic in Javascript
Javascript 只有一种数字类型:64 位浮点数。
使用 Javascript,我需要实现一个散列算法,该算法旨在用 C
编写 16 位无符号整数。
主要操作是这样的(伪代码):
uint16 n = 0;
string s = "abcd1234";
for (int i = 0; i < s.length; i += 1) {
n ^= (n << 2) + (n >> 3) + s[i];
}
return n;
当然,当使用 uint16
值时会产生一个结果,如果 n
是 64 位浮点数,则会产生不同的结果。
到目前为止,我对这个问题的最佳解决方案是将每个按位运算的结果转换为 <= 16 位,使用这样的函数 (javascript):
function uint16 (n) {
return parseInt(n.toString(2).slice(-16), 2);
}
并执行类似这样的操作 (javascript):
for (var i = 0; i < s.length; i +=1 ) {
n ^= uint16(uint16(n << 2) + uint16(n >>> 3) + s.charCodeAt(i));
}
但我不是 100% 相信这将始终产生正确的结果。
是否有任何标准方法可以模拟 Javascript 中数字值的 16 位无符号按位运算?
您可以使用 bitwise AND。
它对 32 位整数进行运算,但您可以 "and" 加上 0xffff。
function uint16 (n) {
return n & 0xFFFF;
}
此外,移位操作(<<
、>>>
)也对32位整数进行操作,所以你只需要在赋值前调用uint16
函数:
for (var i = 0; i < s.length; i +=1 ) {
n ^= uint16((n << 2) + (n >>> 3) + s.charCodeAt(i));
}
我怀疑@Amit 的版本会执行得更快,但这是一个我已经成功解决的方法:
//create a typed container, we'll work only in the first index.
const idx = 0;
const n = new Uint16Array(1);
for (int i = 0; i < s.length; i += 1) {
n[idx] ^= (n[idx] << 2) + (n[idx] >> 3) + s[i];
}
Javascript 只有一种数字类型:64 位浮点数。
使用 Javascript,我需要实现一个散列算法,该算法旨在用 C
编写 16 位无符号整数。
主要操作是这样的(伪代码):
uint16 n = 0;
string s = "abcd1234";
for (int i = 0; i < s.length; i += 1) {
n ^= (n << 2) + (n >> 3) + s[i];
}
return n;
当然,当使用 uint16
值时会产生一个结果,如果 n
是 64 位浮点数,则会产生不同的结果。
到目前为止,我对这个问题的最佳解决方案是将每个按位运算的结果转换为 <= 16 位,使用这样的函数 (javascript):
function uint16 (n) {
return parseInt(n.toString(2).slice(-16), 2);
}
并执行类似这样的操作 (javascript):
for (var i = 0; i < s.length; i +=1 ) {
n ^= uint16(uint16(n << 2) + uint16(n >>> 3) + s.charCodeAt(i));
}
但我不是 100% 相信这将始终产生正确的结果。
是否有任何标准方法可以模拟 Javascript 中数字值的 16 位无符号按位运算?
您可以使用 bitwise AND。
它对 32 位整数进行运算,但您可以 "and" 加上 0xffff。
function uint16 (n) {
return n & 0xFFFF;
}
此外,移位操作(<<
、>>>
)也对32位整数进行操作,所以你只需要在赋值前调用uint16
函数:
for (var i = 0; i < s.length; i +=1 ) {
n ^= uint16((n << 2) + (n >>> 3) + s.charCodeAt(i));
}
我怀疑@Amit 的版本会执行得更快,但这是一个我已经成功解决的方法:
//create a typed container, we'll work only in the first index.
const idx = 0;
const n = new Uint16Array(1);
for (int i = 0; i < s.length; i += 1) {
n[idx] ^= (n[idx] << 2) + (n[idx] >> 3) + s[i];
}