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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 使用MySQL Workbench建立数据库,建立新的表,向表中添加数据

    使用MySQL Workbench建立数据库,建立新的表,向表中添加数据初学数据库,记录一下所学的知识。我用的MySQL数据库,使用MySQLWorkbench管理。下面简单介绍一下如何使用MySQLWorkbench建立数据库,建立新的表,为表添加数据。  点击上图中的“加号”图标,新建一个连接,    如上图,先输入数据库的账号密码,帐号默认为root,填好密码后点击“OK”,连接就建立好了,建立完成后,会出现一个长方

    2022年9月24日
  • Ant下载及配置安装

    Ant下载及配置安装Ant下载及配置安装

    2022年7月13日
  • kettle工具的介绍和使用

    kettle工具的介绍和使用kettle详解(数据抽取、转换、装载)原文地址链接:https://blog.csdn.net/qq_35731570/article/details/71123413文件资源库模式的调度命令:job:$kitchen路径-file=$job路径kitchen.sh-file=/opt/dpbs/kettlefile/pan_quality_indicator….

    2022年10月16日
  • 中文情感词典的构建与使用_文本情感识别

    中文情感词典的构建与使用_文本情感识别首先,国外英文的情感分析已经取得了很好的效果,得益于英文单词自身分析的便捷性与英文大量的数据集WordNet。但由于中文的多变性,语义的多重性与数据集的缺乏,使得国内的情感分析暂落后于国外。本文将记录博主在项目中构建情感词典的经验,欢迎大家指正。我们首先将情感词典分为通用情感词典与专用情感词典。1.通用情感词典的构建通用情感词典的构建主要是通过将目前开源的情感词典整合起来,筛去重复和无…

    2022年8月23日
  • USB接口定义

    USB接口定义USB接口标准USB是电脑的常见接口,有4根线,两根电源线和两个信号线,电源线正负极供电,接烦可能导致USB设备或电脑的南桥芯片烧坏。typeA即我们常见的标准USB大口,主流的可以分为USB2.0速度(几十M/S)和USB3.0速度(上百M/S),事实上目前有少量Type-A为USB3.110Gbps速度,常见于新的台式机主板上。typeB常见于打印机以及带触摸和U…

    2022年5月30日
  • haxm intel庐_如何开启Intel HAXM功能「建议收藏」

    haxm intel庐_如何开启Intel HAXM功能「建议收藏」1.启用BIOS中的Intel(R)VirtualizationTechnology选项2.设置成功后,在控制台中输入scqueryintelhaxm。出现下图即为成功3.启动androidSDK,在Extras目录的最下边,勾选IntelHAXM项,并下载4.下载完成后,打开目录:Sdk\extras\intel\Hardware_Accelerated_Execution_…

    2022年6月28日

发表回复

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

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