在 JavaScript 中使用整数作为位域
作为项目的一部分,我有一串 0 到 3 之间的数字,例如: 2030000000000000000030000000000000000003333212111221121301
我想通过 URL 传递这个字符串,所以我想我可以尝试使用位字段,因为每个数字最多只使用 2 位。我在类中编写了以下函数,将这样的字符串与用作数据位字段的整数数组相互转换:
makeBuildBitfield: function(build) {
var b = build.split('');
var f = [3, 0]; // the "3" is there for future purposes
var i = 1;
var j = 0;
for (var t in b) {
if (j < 14) {
f[i] |= b[t];
f[i] = f[i] << 2;
++j;
} else {
f[i] |= b[t];
++i;
f[i] = 0;
j = 0;
}
}
return f.join('.');
},
getBuildFromBitfield: function(bitfield) {
b = bitfield.split('.');
var ba = [];
for (var x = 1; x < b.length; ++x) { //start from 1 to skip the "3"
ba[x] = [];
var n = b[x];
for (var y = 14; y >= 0; --y) {
ba[x][y] = n & 3;
n = n >>> 2;
}
}
build = '';
for (var a in ba) build += ba[a].join('');
return build;
},
它们似乎确实有效,但是......不完全是。当我在开始时从示例中传递字符串时:
2030000000000000000030000000000000000003333212111221121301
我得到以下输出:
3.587202560.786432.4089.156916164
但是,当我将其传递给应该将其转换回来的函数时,它会给我这个:
203000000000000000003000000000000000000333321021112211213010
请注意第二个字符串中的额外零。现在,我对位操作很陌生,这是我第一次尝试,但我已经四处搜索并阅读了我能找到的关于该主题的文章,并且我尝试在一张纸上写下随着循环的进行,尝试理解正在发生的事情,但我似乎无法弄清楚为什么会出错以及这些额外的零在那里做了什么。要么我的 string->bitfield 函数关闭,要么另一个函数关闭,或者很可能两者都关闭。但我真的无法弄清楚,所以有人对我如何解决出现的问题有任何建议吗?
提前致谢!
As part of a project I have a string of numbers between 0 and 3, for example:2030000000000000000030000000000000000003333212111221121301
I want to pass this string through an URL, so I figured I could try using a bitfield since each number only uses a maximum of 2 bits each. I wrote the following functions in my class to convert such a string to and from an array of integers used as bitfields for the data:
makeBuildBitfield: function(build) {
var b = build.split('');
var f = [3, 0]; // the "3" is there for future purposes
var i = 1;
var j = 0;
for (var t in b) {
if (j < 14) {
f[i] |= b[t];
f[i] = f[i] << 2;
++j;
} else {
f[i] |= b[t];
++i;
f[i] = 0;
j = 0;
}
}
return f.join('.');
},
getBuildFromBitfield: function(bitfield) {
b = bitfield.split('.');
var ba = [];
for (var x = 1; x < b.length; ++x) { //start from 1 to skip the "3"
ba[x] = [];
var n = b[x];
for (var y = 14; y >= 0; --y) {
ba[x][y] = n & 3;
n = n >>> 2;
}
}
build = '';
for (var a in ba) build += ba[a].join('');
return build;
},
They do seem to be working, but... not quite. When i pass the string from my example at the start:
2030000000000000000030000000000000000003333212111221121301
I get the following output:
3.587202560.786432.4089.156916164
However, when I pass this to the function that is supposed to convert it back, it gives me this:
203000000000000000003000000000000000000333321021112211213010
Note the extra zeros in the second string. Now, I'm new to operating on bits and this is my first attempt at it, but I've searched around and read the articles I could find on the subject, and I've tried to write down on a sheet of paper the state of the bits as the loop progresses to try and understand what is going on, but I just can't seem to figure out why it goes wrong and what those extra zeros are doing there. Either my string->bitfield
function is off, or the other one, or quite possibly both. But I really can't figure it out, so does anyone have any suggestions as to how I could fix whatever it is that's going wrong?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一个很好的简短方法,可将位域缩小为 36 进制字符串。它也适用于以 10 为基数的字符串,但它更加简洁。它也适用于位字段中的前导零。
编辑 - 我假设您的目标是缩小位字段,通过 url (GET 请求)发送它,然后在另一侧扩展它。这将允许您做到这一点,尽管除了传输和扩展它之外,您将无法对缩小的数据执行任何有用的操作。
编辑 2 - 现在这是一个“无点”变体。这是一个测试:
Here's a nice short approach that shrinks the bitfields to base-36 strings. It would work with base-10 strings too, but this is a little more condensed. It also works with leading zeros in the bitfield.
Edit - I'm assuming your goal is to shrink the bitfield, send it through the url (a GET request), and then expand it on the other side. This will allow you to do that, although you won't be able to do anything useful with the shrunk data besides transport it and expand it.
Edit 2 - This is now a "no-dots" variation. Here's a test:
有几个问题:
迭代数组时不要使用“for (var x in y)”类型的循环。始终使用索引。
添加到位域字符串中的最后一个内容并不总是代表原始的 15 位数字。 “get”函数始终假定每个位域组件具有相同的位数。
您在某些局部变量声明中遗漏了
var
。这是我的版本,它至少适用于您的示例输入:
我窃取了您的“f[0]”作为最后一个条目的大小,但您可以将该值放在任何地方。
There are several problems:
Don't use the "for (var x in y)" type of loop when iterating over arrays. Always use an index.
The last thing added to the bitfield string won't always represent 15 digits from the original. The "get" function always assumes that each bitfield component has the same number of digits.
You've left out
var
in some of your local variable declarations.Here's my version, which works on your sample input at least:
I stole your "f[0]" for the size of the last entry, but you could put the value anywhere.
好吧,因为我已经编写了一些位图代码,所以这里有一个使用它的解决方案。
Bitmap.js
测试.js
Well since I already have some bitmap code already written, here's a solution using it.
Bitmap.js
Test.js