通过使用位掩码,可以在一个变量中存储多个值。例如,如果用户对项目具有读取,写入和执行权限,则可以通过说 read = 4(2 ^ 2),write = 2(2 ^ 1),execute =转换为单个数字。 1(2 ^ 0)然后将它们加在一起得到7。

我在几个Web应用程序中使用这种技术,我通常将变量存储到一个字段中,并为其提供一种MEDIUMINT或其他类型,具体取决于不同值的数量。

我感兴趣的是,您可以存储的值的数量是否存在实际限制?例如,如果数字超过64,则不能再使用(64位)整数。如果是这种情况,你会用什么?它会如何影响您的程序逻辑(即:您是否仍然可以使用按位比较)?

我知道,一旦你开始获得非常大的值集,一个不同的方法将是最佳解决方案,但我对这个方法的界限感兴趣。

有帮助吗?

解决方案

在我的脑海中,我写了一个 set_bit get_bit 函数,它可以获取数组中的字节数组和位偏移量,并使用一些在设置/获取数组中相应位的位。这样的事情(在C中,但希望你能得到这个想法):

// sets the n-th bit in |bytes|. num_bytes is the number of bytes in the array
// result is 0 on success, non-zero on failure (offset out-of-bounds)
int set_bit(char* bytes, unsigned long num_bytes, unsigned long offset)
{
  // make sure offset is valid
  if(offset < 0 || offset > (num_bytes<<3)-1) { return -1; }

  //set the right bit
  bytes[offset >> 3] |= (1 << (offset & 0x7));

  return 0; //success 
}

//gets the n-th bit in |bytes|. num_bytes is the number of bytes in the array
// returns (-1) on error, 0 if bit is "off", positive number if "on"
int get_bit(char* bytes, unsigned long num_bytes, unsigned long offset)
{
  // make sure offset is valid
  if(offset < 0 || offset > (num_bytes<<3)-1) { return -1; }

  //get the right bit
  return (bytes[offset >> 3] & (1 << (offset & 0x7));
}

其他提示

我在文件系统代码中使用了位掩码,其中位掩码比机器字大许多倍。把它想象成一个“布尔数组”;

(如果你想知道,请在闪存中记录掩码)

许多编译器知道如何为您执行 。添加一些OO代码,使其具有可操作的类型,然后您的代码开始看起来像它的意图,而不是一些比特敲打。

我的2美分。

使用64位整数,您可以存储最多2 ^ 64-1的值,64只是2 ^ 6。所以,是的,有一个限制,但如果你需要超过64个标志,我会非常有兴趣知道他们在做什么:)

您需要考虑多少个州?如果您有64个潜在状态,则它们可以存在的组合数是64位整数的完整大小。

如果你需要担心128个标志,那么一对位向量就足够了(2 ^ 64 * 2)。

加法:在编程Pearls中,对使用长度为10 ^ 7的位数组进行了扩展讨论,以整数实现(用于保存使用的800个数字) - 它非常快,非常合适对于该章中描述的任务。

有些语言(我相信perl确实如此,不确定)允许对字符串进行逐位算术运算。为您提供更大的有效范围。 ((strlen * 8bit chars)组合)

但是,我不会使用单个值来叠加多个/类型/数据。 3位整数的基本r / w / x三元组可能是较高的“实用”三元组。限制,不是出于空间效率的原因,而是出于实际发展的原因。

(Php使用这个系统来控制它的错误消息,我已经发现当你必须定义php的常量不是常驻的值并且你必须手动生成整数时它有点过顶了,说实话,如果chmod不支持'ugo + rwx'风格的语法,我永远不想用它,因为我永远不会记住神奇的数字)

你必须打开一个常量表来调试代码,你知道你已经走得太远了。

旧线程,但值得一提的是,有些情况需要膨胀的位掩码,例如分子指纹,它们通常生成为1024位数组,我们在32个bigint字段中打包(SQL Server不支持UInt32)。一点一点的操作工作正常 - 直到你的表开始增长,你意识到单独的函数调用的迟缓。二进制数据类型是否有效,如果不是T-SQL禁止具有两个二进制操作数的按位运算符。

例如,.NET使用整数数组作为其BitArray类的内部存储。 实际上没有别的办法了。

话虽如此,在SQL中,您需要多个列(或使用BLOBS)来存储所有状态。

您已将此问题标记为SQL,因此我认为您需要查阅数据库的文档以查找整数的大小。然后为符号减去一位,只是为了安全。

编辑:您的评论说您正在使用MySQL。 MySQL 5.0数字类型的文档指出NUMERIC的最大大小为64或65位。那是64位的212位数。

请记住,您选择的语言必须能够使用这些数字,因此您可能无论如何都可以限制为64位整数。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top