加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

使用位运算符将unsigned int转换为unsigned short int

发布时间:2020-12-16 09:31:11 所属栏目:百科 来源:网络整理
导读:我想以下列方式将unsigned int(32bit)A转换为unsigned short int(16bit)B: 如果A = 2 ^ 16-1则B = A. 如果A 2 ^ 16-1然后B = 2 ^ 16-1 换句话说,如果它是 16bit的最大允许值,将其设置为最大值. 如何通过位操作或其他非分支方法实现这一点? 解决方法 找到最
我想以下列方式将unsigned int(32bit)A转换为unsigned short int(16bit)B:

>如果A <= 2 ^ 16-1则B = A.
>如果A> 2 ^ 16-1然后B = 2 ^ 16-1

换句话说,如果它是> 16bit的最大允许值,将其设置为最大值.

如何通过位操作或其他非分支方法实现这一点?

解决方法

找到最少两个没有分支的整数:

http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax

On some rare machines where branching
is very expensive and no condition
move instructions exist,the above
expression might be faster than the
obvious approach,r = (x < y) ? x : y,
even though it involves two more
instructions. (Typically,the obvious
approach is best,though.)

只是为了解决问题,这是一个脑死亡的基准.我试图“随机”获得50/50的大小值组合:

#include <iostream>
#include <stdint.h>

int main() {
    uint32_t total = 0;
    uint32_t n = 27465;
    for (int i = 0; i < 1000*1000*500; ++i) {
        n *= 30029; // worst PRNG in the world
        uint32_t a = n & 0x1ffff;
        #ifdef EMPTY
            uint16_t b = a; // gives the wrong total,of course.
        #endif
        #ifdef NORMAL
            uint16_t b = (a > 0xffff) ? 0xffff : a;
        #endif
        #ifdef RUSLIK
            uint16_t b = (-(a >> 16) >> 16) | a;
        #endif
        #ifdef BITHACK
            uint16_t b = a ^ ((0xffff ^ a) & -(0xffff < a));
        #endif
        total += b;
    }
    std::cout << total << "n";
}

在我的编译器(gg 4.3.4 on cygwin with -O3)上,NORMAL获胜,然后是RUSLIK,然后是BITHACK,分别比空循环慢0.3,0.5和0.9秒.真的这个基准没什么意义,我甚至没有检查发出的代码,看看编译器的智能是否足以智胜我.但无论如何我喜欢ruslik.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读