php 0xffffffff,0xffffffff – 依睛(IT blog) 我回来了,PHPC/C++ LINUX – IT博客「建议收藏」

php 0xffffffff,0xffffffff – 依睛(IT blog) 我回来了,PHPC/C++ LINUX – IT博客「建议收藏」今早ssjjll问我一个位操作的问题,原本以为非常easy的,可是程式的输出总是不尽人意。开始认为是编译器的错误,后来看文件才知道是自己学业不精,乃功力不足所致。失望!对C我一直认为全掌控了,而C++也练到了7、8重的境界,不料今日还是阴沟翻船。记下来,勿忘瓜耻!先看出现问题的代码:inta=32;intx=0xFFFFFFFF;cout<<int(0xFFFFFFFF…

大家好,又见面了,我是你们的朋友全栈君。

今早ssjjll问我一个位操作的问题,原本以为非常easy的,可是程式的输出总是不尽人意。开始认为是编译器的错误,后来看文件才知道是自己学业不精,乃功力不足所致。失望!对C我一直认为全掌控了,而C++也练到了7、8重的境界,不料今日还是阴沟翻船。记下来,勿忘瓜耻!

先看出现问题的代码:int a = 32;

int x = 0xFFFFFFFF;

cout << int(0xFFFFFFFF >> 32) << endl;

cout << int(x >> 32) << endl;

cout << int(0xFFFFFFFF >> a) << endl;

输出:VC7.1 Debug 为 0,  -1,  -1.   Release为 0, 0, 0.疑点:sizeof(int)==4。所以左移32位后,我认为int变量应该被清0了。但输出结果却不一致,更奇怪的是debug/release的输出也不相同。我当时猜测是int应该改为unsigned int的问题,(后来发现直觉有一定道理,但不是问题关键)。把程式改为全用unsignedint,输出不变!也就是:

unsigned 0xFFFFFFFF 右移32次,居然还得到0xFFFFFFFF!更加想不通了。

解答:

仔细看了一下C/C++ Standard和MSDN,原来是我对位移操作的理解不够完备所致。

1. 所有的位移操作的右操作数必须小于左操作数的位长度,否则结果未定义。

2. 右移操作对于unsigned系列,高位一直补0。对于signed系列,高位补符号位。

3. 在操作过程当中,有可能产生Integral Promotions。这就比较复杂了。C++中采用和C相同的策略,提升后的的量总是“保值的”,即原有的bit值不变;但不一定是“保号的”。运算中,如果char/bit field不能保持全部的值,就会被提升到int型,如果int也不能保存全部的值就会被提升至unsigned。有几种罕见的情况,保值和保号的运算会导致不同的值:

(1) /, %, /=, %=, , >=运算依赖于符号,应用时可能导致不同结果。(2)>>, >>= 运算有时依赖于符号位。(3)函数重载参数可能依赖于符号。

由此可见,上述程式的位操作次数大于等于了整数的位数,输出结果不确定也是正常的。为了完全理解这个问题,再作下面的试验:int a = 31;

int x = 0xFFFFFFFF;

cout << typeid(0xFFFFFFFF).name() << endl;

cout << typeid(0x0FFFFFFF).name() << endl;

cout << int(0xFFFFFFFF >> 31) << endl;

cout << int(x >> 31) << endl;

cout << int(0xFFFFFFFF >> a) << endl;

输出:Debug/Release下均为 unsigned int, int, 1, -1, 1

这里能清晰地看到0xFFFFFFFF之内被unsigned int放下,所以其类型是unsigned int;而0x0FFFFFFF一个int就能放下了,所以类型是int。两个1的输出没什么好说的。-1的输出是因为x为有符号数,且符号位是1,所以高位补1,结果总不变。但这个1和-1的差异的确够隐晦的。

总结经验:当对变量进行位移操作时,逻辑上应该尽可能使用无符号数。位移长度应严格控制在字长以内。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/145302.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ECLIPSE软件安装MyBatis插件 MyBatis Generator

    ECLIPSE软件安装MyBatis插件 MyBatis GeneratorECLIPSE软件安装MyBatis插件打开Eclipse->导航栏Help->EclipseMarketplace会出现如下页面:搜索mybatis->安装我红框框的东西安装就是同意安装,然后install之类的…安装好之后会提示重启Eclipse…

    2022年9月13日
    0
  • 正规矩阵(酉矩阵)[通俗易懂]

    正规矩阵(酉矩阵)[通俗易懂]英文名:Unitarymatrix

    2025年5月28日
    0
  • mongodb数据库去重命名_数据库数据去重语句

    mongodb数据库去重命名_数据库数据去重语句  最近写爬虫的时候遇到了一个问题,爬一个专利网站,主要工作流是先把列表页下所有的专利包括专利号、专利名称、URL放到数据库的一个文档info中,再抽取info中的URL进行爬取详情页,爬取列表页的信息做了一个去重,爬一个就在数据库里查一个。。效率就不提了(另一种我能想到的方法是先用线程池爬取一遍,把单个字典放入一个列表中,再采用set去重,但是线程池似乎没法返回子线程的值?),之后在详情页爬取工…

    2022年9月30日
    1
  • 计算机专业的男生喜欢你,男生真心喜欢你的五个表现

    计算机专业的男生喜欢你,男生真心喜欢你的五个表现原标题:男生真心喜欢你的五个表现男生真心喜欢你的五个表现。不知从什么时候起,“爱”成了一个不太确切的词。像是,我们平时跟人业务联系,表达感谢都会直接说,“爱你哦”,情绪却未丝丝入扣地跟上。“爱”被滥用得廉价了,“喜欢”这个词才更小心翼翼了起来。而我也跟万千少女一样,饱受“他究竟喜欢我吗?”这一终极拷问的困扰。现代人的真心,被层层规则与圈套拢住,是要费点机灵脑筋,拨云才能见日的。每天翻新暧昧的说辞…

    2022年7月25日
    12
  • 1602驱动电路_lcd1602的a和k接哪里

    1602驱动电路_lcd1602的a和k接哪里       今天我也开博了,一个前辈的话对我触动很大:不会分享,不懂总结,就不要做技术。这也是我这博客的目的,望各路过高手菜鸟多多指教。          搞了几天的1062a终于调通了。前段时间把8位总线的调通了,这个简单,网上资料也多。以前写程序一般都是网上找资料后自已再改,这次1062a四位驱动的程序网上也有,我下了好多版本结果都不行,就这样我也堵在这几天了。这说明我的底层程序

    2022年9月22日
    0
  • 3分钟告诉你如何成为一名黑客?|零基础到黑客入门指南,你只需要掌握这五点能力

    3分钟告诉你如何成为一名黑客?|零基础到黑客入门指南,你只需要掌握这五点能力三分钟带各位揭秘黑客究竟是什么,以及想要成为黑客都需要具备哪些能力?

    2022年6月4日
    48

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号