如果可能的话,如何在 C 中定义 2 位数字?

发布于 2024-08-26 09:19:52 字数 696 浏览 7 评论 0原文

对于我的大学过程,我正在模拟一个称为随机顺序吸附的过程。 我必须做的一件事包括将正方形(不能重叠)随机放置到格子上,直到没有更多空间为止,重复该过程几次以找到平均“干扰”覆盖率%。

基本上我正在对一个大的整数数组执行操作,其中存在 3 个可能的值:0、1 和 2。标有“0”的站点是空的,标有“1”的站点已满。最初数组是这样定义的:

int i, j;
int n = 1000000000;
int array[n][n];

for(j = 0; j < n; j++)
{
    for(i = 0; i < n; i++)
    {
        array[i][j] = 0;
    }
}

假设我想在数组上随机放置 5*5 个正方形(不能重叠),以便这些正方形用“1”表示。这可以通过随机选择 x 和 y 坐标,然后创建一个 5*5 的“1”正方形来完成,该正方形的左上角点从该点开始。然后我会将广场附近的站点标记为“2”。这些代表不可用的站点,因为在这些站点上放置正方形会导致其与现有正方形重叠。这个过程将继续下去,直到阵列上没有足够的空间来存放方块(基本上,阵列上不再剩下“0”)。

无论如何,言归正传。我想通过使用按位运算使这个过程尽可能高效。如果我不必标记广场附近的站点,这会很容易。我想知道是否可以创建一个 2 位数字,以便我可以解释标有“2”的站点。

抱歉,如果这听起来真的很复杂,我只是想解释一下为什么我想这样做。

For my university process I'm simulating a process called random sequential adsorption.
One of the things I have to do involves randomly depositing squares (which cannot overlap) onto a lattice until there is no more room left, repeating the process several times in order to find the average 'jamming' coverage %.

Basically I'm performing operations on a large array of integers, of which 3 possible values exist: 0, 1 and 2. The sites marked with '0' are empty, the sites marked with '1' are full. Initially the array is defined like this:

int i, j;
int n = 1000000000;
int array[n][n];

for(j = 0; j < n; j++)
{
    for(i = 0; i < n; i++)
    {
        array[i][j] = 0;
    }
}

Say I want to deposit 5*5 squares randomly on the array (that cannot overlap), so that the squares are represented by '1's. This would be done by choosing the x and y coordinates randomly and then creating a 5*5 square of '1's with the topleft point of the square starting at that point. I would then mark sites near the square as '2's. These represent the sites that are unavailable since depositing a square at those sites would cause it to overlap an existing square. This process would continue until there is no more room left to deposit squares on the array (basically, no more '0's left on the array)

Anyway, to the point. I would like to make this process as efficient as possible, by using bitwise operations. This would be easy if I didn't have to mark sites near the squares. I was wondering whether creating a 2-bit number would be possible, so that I can account for the sites marked with '2'.

Sorry if this sounds really complicated, I just wanted to explain why I want to do this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

白日梦 2024-09-02 09:19:52

您无法创建 2 位大小的数据类型,因为它无法寻址。您可以做的是将几个 2 位数字打包到一个更大的单元格中:

   struct Cell {
      a : 2;
      b : 2;
      c : 2;
      d : 2;
   };

这指定每个成员 abcd 应在内存中占用两位。

编辑:这只是如何创建 2 位变量的示例,对于所讨论的实际问题,最有效的实现可能是创建一个 int 数组和将位摆弄封装在几个 set/get 方法中。

You can't create a datatype that is 2-bits in size since it wouldn't be addressable. What you can do is pack several 2-bit numbers into a larger cell:

   struct Cell {
      a : 2;
      b : 2;
      c : 2;
      d : 2;
   };

This specifies that each of the members a, b, c and d should occupy two bits in memory.

EDIT: This is just an example of how to create 2-bit variables, for the actual problem in question the most efficient implementation would probably be to create an array of int and wrap up the bit fiddling in a couple of set/get methods.

神爱温柔 2024-09-02 09:19:52

您可以使用两个单独的 1 位数组来代替两位数组。一个持有填充的方块,一个持有相邻的方块(或可用的方块,如果这样更有效)。

我不太确定这相对于将 2 位字段打包到单词中是否有任何好处。
除非你真的内存不足,否则我会选择字节数组。

Instead of a two-bit array you could use two separate 1-bit arrays. One holds filled squares and one holds adjacent squares (or available squares if this is more efficient).

I'm not really sure that this has any benefit though over packing 2-bit fields into words.
I'd go for byte arrays unless you are really short of memory.

雨的味道风的声音 2024-09-02 09:19:52

您可以将数组的一维压缩为子整数单元格。要将坐标(例如 x)转换为字节内的位置:

byte cell = array[i][ x / 4 ];
byte mask = 0x0004 << (x % 4);
byte data = (cell & mask) >> (x % 4);

要写入数据,请执行相反操作

You can compact one dimension of array into sub-integer cells. To convert coordinate (lets say x for example) to position inside byte:

byte cell = array[i][ x / 4 ];
byte mask = 0x0004 << (x % 4);
byte data = (cell & mask) >> (x % 4);

to write data do reverse

冷情妓 2024-09-02 09:19:52

基本思想

不幸的是,在 C 中无法做到这一点。您可以创建 1 字节、2 字节等数组,但无法创建位区域。

那么,你能做的最好的事情就是为自己编写一个新的库,这使得你看起来像是在处理 2 位数组,但实际上做了很多艰苦的工作。就像字符串库为您提供处理“字符串”(在 C 中只是数组)的函数一样,您将创建一个处理“位数组”(实际上是整数数组)的新库,使用一些特殊函数来处理它们,就好像它们是位数组一样)。

注意:如果您是 C 语言新手,并且尚未学习“创建新库/模块”的想法或“抽象”的概念,那么我建议您在继续此项目之前了解它们。在我看来,理解它们比优化程序以使用更少的空间更重要。

如何实现这个新的“库”或模块

根据您的需要,我将创建一个名为“2位数组”的新模块,它导出用于处理2位数组的函数,就像您一样需要他们。

它将有一些处理设置/读取位的函数,这样您就可以像有一个实际的位数组一样使用它(您实际上有一个整数数组或其他东西,但该模块会让它看起来像就像你有一个位数组)。

使用这个模块会像这样:

// This is just an example of how to use the functions in the twoBitArray library.
twoB my_array = Create2BitArray(size); // This will "create" a twoBitArray and return it.
SetBit(twoB, 5, 1); // Set bit 5 to 1 // 
bit b = GetBit(twoB, 5); // Where bit is typedefed to an int by your module.

该模块实际上要做的是使用常规旧整数数组来实现所有这些函数。

例如,函数 GetBit()(对于 GetBit(my_arr, 17))将计算出它是数组的第 4 个整数中的第 1 位(取决于 >sizeof(int),显然),并且您可以使用按位运算返回它。

The basic idea

Unfortunately, there is no way to do this in C. You can create arrays of 1 byte, 2 bytes, etc., but you can't create areas of bits.

The best thing you can do, then, is to write a new library for yourself, which makes it look like you're dealing with arrays of 2 bits, but in reality does a lot of hard work. The same way that the string libraries give you functions that work on "strings" (which in C are just arrays), you'll be creating a new library which works on "bit arrays" (which in reality will be arrays of integers, with a few special functions to deal with them as-if they were arrays of bits).

NOTE: If you're new to C, and haven't learned the ideas of "creating a new library/module", or the concept of "abstraction", then I'd recommend learning about them before you continue with this project. Understanding them is IMO more important than optimizing your program to use a little less space.

How to implement this new "library" or module

For your needs, I'd create a new module called "2-bit array", which exports functions for dealing with the 2-bit arrays, as you need them.

It would have a few functions that deal with setting/reading bits, so that you can work with it as if you have an actual array of bits (you'll actually have an array of integers or something, but the module will make it seem like you have an array of bits).

Using this module would like something like this:

// This is just an example of how to use the functions in the twoBitArray library.
twoB my_array = Create2BitArray(size); // This will "create" a twoBitArray and return it.
SetBit(twoB, 5, 1); // Set bit 5 to 1 // 
bit b = GetBit(twoB, 5); // Where bit is typedefed to an int by your module.

What the module will actually do is implement all these functions using regular-old arrays of integers.

For example, the function GetBit(), for GetBit(my_arr, 17), will calculate that it's the 1st bit in the 4th integer of your array (depending on sizeof(int), obviously), and you'd return it by using bitwise operations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文