c/c++语言开发共享C:设置变量范围内所有位的最有效方法

我们以int为例:

 int SetBitWithinRange(const unsigned from, const unsigned to) { //To be implemented } 

SetBitWithinRange应该返回一个int ,其中当from smaller to且两者都在032的范围内时,所有且仅仅从bit到bit的位开始被设置。

例如: int i = SetBitWithinRange(2,4)将导致i的值为0b00 … 01100

    这是一些方法。 首先,“设置n位,然后from移位”的一些变体。 我会用C#回答,我比它更熟悉它。应该很容易转换。

     uint nbits = 0xFFFFFFFFu >> -(to - from); return nbits << from; 

    下行:无法处理空范围,即to <= from

     uint nbits = ~(0xFFFFFFFFu << (to - from)); return nbits << from; 

    上行:可以处理to = from的情况,在这种情况下,它将不设置位。
    下行:无法处理全部范围,即设置所有位。

    应该明白这些是如何工作的。

    或者,您可以使用“减去两个2的幂”技巧,

     (1u << to) - (1u << from) 

    缺点:不能是32,所以你永远不能设置最高位。

    像这样工作:

     01000000 ^^^^^^ "to" zeroes 100 ^^ "from zeroes" -------- - 00111100 

    在“from”部分的1的右侧,它只是从零中减去零。 然后在“from”部分的1处,你将从1中减去(if to == from )并得到0作为结果,或者你将从0减去1并一直借用1在部分,将被重置。

    在撰写本文时提出的所有真正的按位方法都有其中一个缺点,这就提出了一个问题:它可以在没有缺点的情况下完成吗?

    不幸的是,答案令人失望。 它可以在没有缺点的情况下完成,但仅限于

    举一个例子,您可以选择任何以前的方法并添加一个特殊情况(使用if或三元运算符)来解决它们的缺点。

    举两个例子:(未经测试)

     uint uppermask = (((uint)to >> 5) ^ 1) << to; return uppermask - (1u << from); 

    上面的uppermask要么取一个1并将其向左移动(如通常那样),要么取一个0并向左移动(一个无关紧要的量,因为它是0被移位),如果to == 32 。 但它有点奇怪并且使用更多操作。

    举一个3的例子,当你按操作数大小移动时给出零的移位可以很容易地解决这个问题。 不幸的是,这种转变并不常见。

    我会选择这样的东西:

     int answer = 0; unsigned i = from; for (; i <= to; ++i) answer |= (1 << i); return answer; 

    易于实现和可读。

    我认为最快的方法是预先计算所有可能的值(从(0,0)到(32,32),如果你知道你只将它用于32位整数)。 事实上,其中大约有1000个。

    然后你最终得到O(1)解决方案:

     answer = precalcTable[from][to]; 

    好吧,我正在接受@JohnZwinck向我投掷的挑战。

    怎么样: return (to<32 ? (1<

    当然,这并没有完全检查fromto有效性。

    根据@JosephQuinsey的评论编辑。

    有效地执行此操作的常见方法是:

     uint32_t set_bits_32 (uint32_t data, uint8_t offset, uint8_t n) { uint32_t mask = 0xFFFFFFFF >> (32-n); return data | (mask << offset); } 

    也许: (( 1 << to ) - (1 << from)) | (1 << to) (( 1 << to ) - (1 << from)) | (1 << to)

    这也将根据请求设置to和from位

    这是我的答案。 ( 更新

     unsigned int SetBits(int from, int to) { return (UINT_MAX >> (CHAR_BIT*sizeof(int)-to)) & (UINT_MAX << (from-1)); } SetBits(9,16); ==> 0b 1111 1111 0000 0000 SetBits(1,1); ==> 0b 0000 0001 // Just Bit #1 SetBits(5,5); ==> 0b 0001 0000 // Just Bit #5 SetBits(1,4); ==> 0b 0000 1111 // Bits #1, #2, #3, and #4 (low 4 bits) SetBits(1,32); ==> 0b 1111 1111 1111 1111 // All Bits 

    但是, SetBits(0,0); 不能关闭所有位。

    我的假设:

    也可以这种方式完成,可以使用移位操作来实现pow。

     { unsigned int i =0; i = pow(2, (to-from))-1; i = i < 

      以上就是c/c++开发分享C:设置变量范围内所有位的最有效方法相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/560251.html

      (0)
      上一篇 2021年1月27日
      下一篇 2021年1月27日

      精彩推荐