访问字节中的位[,,]

时间:2018-08-21 14:07:12

标签: c# multidimensional-array hash 3d byte

我正在制作一个数据结构,让我们称之为位立方体。目的是为了节省bool [,,]上的空间,但具有相同类型的操作。

到目前为止,我可以设置一个位,看看是否设置了这样的位:

public class BitCube {
    private byte[,,] data;

    public BitCube(int size) {
        data = new byte[size, size, size];
    }

    public void SetBit(int x, int y, int z, int n) {
        data[x, y, z] |= (byte)(1 << n);
    }

    private bool GetBit(int x, int y, int z, int n) {
        return (data[x, y, z] & (1 << n)) >= 1;
    }
} 

这有效。不幸的是,这些操作与bool[,,]的操作不同。从用户的角度来看,bool[,,]BitCube的操作不应有差异。

我要做的是不使用参数n,而是使用xyz计算位的位置。

BitCube看起来像这样:

public class BitCube {
    private byte[,,] data;

    public BitCube(int size) {
        if (size % 8 != 0) {
            throw new ArgumentException("Size must to be divisable by 8");
        }
        data = new byte[size / 8, size / 8, size / 8];
    }

    public bool this[int x, int y, int z] {
        get {
            return GetBit(x, y, z);
        }
    }

    public void SetBit(int x, int y, int z) {
        int n = (x + y + z) % 8;
        if (x != 0) x /= 8;
        if (y != 0) y /= 8;
        if (z != 0) z /= 8;
        data[x, y, z] |= (byte)(1 << n);
    }

    private bool GetBit(int x, int y, int z) {
        int n = (x + y + z) % 8;
        if (x != 0) x /= 8;
        if (y != 0) y /= 8;
        if (z != 0) z /= 8;
        return (data[x, y, z] & (1 << n)) >= 1;
    }
}

计算所需字节的索引很容易。我遇到的问题是计算位的索引n。我意识到我必须使用某种哈希函数。我对这些不是很熟悉,在开始调查时,我感到自己无法做的事情。由于位索引(0,8)的范围较小。我以为我会在下兔子洞之前先问这里。

1 个答案:

答案 0 :(得分:1)

构成一个字节的8位可以看作一个2x2x2的小立方体。要访问每个位,请对每个索引进行 double 范围,并使用每个索引的最后一位作为每个微型位多维数据集/字节中的“子索引”:

public BitCube(int size)
{
    // new requirement
    if (size % 2 != 0) {
        throw new ArgumentException("Size must be even");
    }
    data = new byte[size / 2, size / 2, size / 2];
}

// calculate the index into the mini byte-cubes
private static int bytecubeIndex(int x, int y, int z)
{
    return (x % 2) * 4 + (y % 2) * 2 + (z % 2);
}

public void SetBit(int x, int y, int z)
{
    data[x / 2, y / 2, z / 2] |= (byte)(1 << bytecubeIndex(x, y, z));
}

private bool GetBit(int x, int y, int z)
{
    return (data[x / 2, y / 2, z / 2] & 
            (byte)(1 << bytecubeIndex(x, y, z))) != 0;
}