- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章移位的位数是负数,结果会怎样?由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
有过编程经验的同学,对于移位操作应该很熟悉了,日常工作中或多或少都有用到,当 移位位数是负数 或者 移位位数超过了 类型的最大二进制位时,和正常移位处理是不一样的,下面将详细说明这两种情况,在此之前,先了解下正常的移位操作 。
正数的左移是二进制位向左移动,右边留空的位置补 0,右移是二进制位向右移动,左边留空的位置补 0 ( 符号位为 0 ) 。
左移操作,最高位的符号位会出现 0 或 1 , 因此结果会出现正数和负数的情况 。
新建测试文件 base.cpp,代码如下 。
执行 g++ -g -Wall -std=c++11 -o base base.cpp 命令编译代码,再执行 ./base 运行程序,结果如下 。
上述代码中,变量 a 的值为 7,对应的二进制是 0000 0000 0000 0000 0000 0000 0000 0111 。
左移 2 位:二进制向左移动 2 位,右边补充 2 位 0 ,左边丢弃超出的 2 位二进制, 结果是 0000 0000 0000 0000 0000 0000 0001 1100, 对应的十进制数是 28 。
左移 30 位 的流程如下图 。
由上图可知,二进制向左移动 30 位后, 左边 30 位二进制 0000 0000 0000 0000 0000 0000 0000 01 因超出被丢弃,同时最右边剩下的 2 位二进制 11 左移 30 位,右边空的位置补充 30 位 0,最终的结果是 1100 0000 0000 0000 0000 0000 0000 0000, 对应的十进制数是 -1073741824 。
可以看出,正数 7 左移 30 位后,二进制的符号位变成了 1 ,也即正数变成了负数了 。
正数右移,最小为 0 , 不会出现负数,下面是右移的测试代码 。
修改 base.cpp 文件,代码如下 。
编译并运行上面程序,结果如下
上述实例代码中,变量 a 的值为 7,对应的二进制是 0000 0000 0000 0000 0000 0000 0000 0111 。
右移 1 位:二进制向右移动 1 位,左边补充一位 0 ,右边丢弃超出的一位二进制, 结果是 0000 0000 0000 0000 0000 0000 0000 0011, 对应的十进制数是 3 。
右移 31 位:二进制向右移动 31 位,左边补充 31 位 0 ,右边丢弃超出的 31 位二进制,结果是 0000 0000 0000 0000 0000 0000 0000 0000, 对应的十进制是 0 。
负数的左移是二进制位向左移动,右边留空的位置补 0,右移是二进制位向右移动,左边留空的位置补 1 ( 符号位为 1 ),这一点跟正数是不一样的 。
计算机中是用补码的形式进行各种运算的,正数的补码是其自身,负数的补码是将其正数按位取反加 1 。
负数左移,符号位可能会变成0,因此结果会出现正数和负数的情况,一直左移的话,最终会变成 0 。
修改 base.cpp文件,代码如下 。
编译并运行上面程序,结果如下
上面代码中,变量 b 的值为 -3,对应的二进制是 1111 1111 1111 1111 1111 1111 1111 1101 。
左移 1 位:整个二进制串向左移动 1 位,右边补充 0 ,左边丢弃超出的一位二进制,结果是 1111 1111 1111 1111 1111 1111 1111 1010,对应十进制数 -6 。
左移 30 位 的流程如下 。
由上图可知,左移 30 位,左边的 30 位二进制 1111 1111 1111 1111 1111 1111 1111 11 因超出数值最大位数而被丢弃,原来最右边的 01 移到了最左边,紧接着后面的 30 个空位全部补 0 ,最终的结果是 0100 0000 0000 0000 0000 0000 0000 0000 ,对应十进制是 1073741824 。
可以看出,负数 -3 左移 30 位后,二进制的符号位变成了 0 ,由开始的负数变成了正数了 。
负数右移是在左边补 1, 所以结果不会出现正数的情况,如果一直右移,最终二进制位会全部变成 1,即十进制的 -1 ( 二进制全 1 在补码中表示 -1 ) 。
修改 base.cpp,代码如下 。
编译并运行上面程序,结果如下
上面代码中,变量 b 的值为 -3,对应的二进制是 1111 1111 1111 1111 1111 1111 1111 1101 。
右移 1 位:二进制位向右移动 1 位,左边补充 1 ,右边丢弃一位超出的二进制,结果为 1111 1111 1111 1111 1111 1111 1111 1110,对应的十进制是 -2 。
右移 31 位 的流程如下 。
根据上图可知,右移 31 位,最右边的 31 位二进制 1111 1111 1111 1111 1111 1111 1111 110 因超出数值最大位数而被丢弃, 原来左边的 1 移到了最右边,左边补 31 位 1,最后结果为:1111 1111 1111 1111 1111 1111 1111 1111 , 对应的十进制数 -1 。
移位的位数大于等于数值类型的最大位数时,实际的移的位数是:移位的位数和该类型的最大位数做取模运算,余数就是要移的位数,不管左移还是右移,这种方法都适用 。
比如:类型为 int32_t,移位的位数是 34,实际移位的位数为:34 % 32 = 1 。
修改 base.cpp 文件,内容如下:
编译并执行,结果如下 。
变量 a 的值为 7,对应的二进制是 0000 0000 0000 0000 0000 0000 0000 0111 。
右移 32 位:因移位位数等于 int32_t 最大位数,所以实际移位数为 32 % 32 = 0,右移 0 位 表示没有移位,所以结果还是 7 。
右移 33 位:移位位数大于 int32_t 最大位数,故实际移位数为 33 % 32 = 1,右移 1 位,左边补 0 ,右边丢弃超出的位,结果是: 0000 0000 0000 0000 0000 0000 0000 0011,对应的十进制是 3 。
左移 34 位:移位位数大于 32 ,实际移位数为 34 % 32 = 2,左移 2 位,右边补 0 ,左边丢弃超出的位,结果是:0000 0000 0000 0000 0000 0000 0001 1100,对应的十进制是 28 。
正常情况下,在移位数相同时,分几次移位操作和单次移位操作的结果是一样的, 比如:一个 int32_t 变量,值为 7, 7 << 1 << 2 和 7 << 3 的结果相同的 。
当移位数大于等于数值类型最大位数时,上述的结果是不一样的,比如:一个 int32_t 变量,值为 7, 虽然 7 << 33 和 7 << 20 << 13 两者移位数都是 33,但结果却是不同的,前者是 14,而后者是 0 。
当移位的位数是负值时,实际移位的位数是:用被移位数值类型的最大位数和移位位数相加,如果结果还是负数,结果继续 加上被移位数值类型的最大位数,直到结果不为负数为止,此时的结果即为最终移位的位数 。
比如:被移位的数据类型是 int32_t,移位位数是 -31,最终移位的位数是:32 + ( -31 ) = 1 。
当移位位数是 -60,计算最终移位位数,32 + ( -60 ) = -28,由于结果还是负数,所以继续相加,32 + ( -28 ) = 4,此次结果不为负数了,所以最终移位的位数是 4 。
修改 base.cpp 文件,内容如下:
编译代码并执行,结果如下 。
变量 a 的值为 7,对应的二进制是 0000 0000 0000 0000 0000 0000 0000 0111 。
右移 -31 位:移位数是负数,实际右移 32 + ( -31 ) = 1 位,结果为:0000 0000 0000 0000 0000 0000 0000 0011,对应的十进制是 3 。
右移 -60 位:移位数是负数,实际右移 32 + 32 + ( -60 ) = 4 位,结果为:0000 0000 0000 0000 0000 0000 0000 0000,对应的十进制是 0 。
本文主要介绍了左移和右移操作,左移相当于乘以 2 的 N 次方,而右移相当于除以 2 的 N 次方,这里的 N 表示移位的位数,需要注意的是,当移位位数是负数或者大于等于类型最大位数时,编译器对他们的处理和正常的移位是不一样的 。
原文链接:https://mp.weixin.qq.com/s/-bBf6b0PcHuy8mo1Zl5mvg 。
最后此篇关于移位的位数是负数,结果会怎样?的文章就讲到这里了,如果你想了解更多关于移位的位数是负数,结果会怎样?的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
尝试使用集成到 QTCreator 的表单编辑器,但即使我将插件放入 QtCreator.app/Contents/MacOS/designer 也不会显示。不过,相同的 dylib 文件确实适用于独
在此代码示例中。 “this.method2();”之后会读到什么?在返回returnedValue之前会跳转到method2()吗? public int method1(int returnedV
我的项目有通过gradle配置的依赖项。我想添加以下依赖项: compile group: 'org.restlet.jse', name: 'org.restlet.ext.apispark', v
我将把我们基于 Windows 的客户管理软件移植到基于 Web 的软件。我发现 polymer 可能是一种选择。 但是,对于我们的使用,我们找不到 polymer 组件具有表格 View 、下拉菜单
我的项目文件夹 Project 中有一个文件夹,比如 ED 文件夹,当我在 Eclipse 中指定在哪里查找我写入的文件时 File file = new File("ED/text.txt"); e
这是奇怪的事情,这个有效: $('#box').css({"backgroundPosition": "0px 250px"}); 但这不起作用,它只是不改变位置: $('#box').animate
这个问题在这里已经有了答案: Why does OR 0 round numbers in Javascript? (3 个答案) 关闭 5 年前。 Mozilla JavaScript Guide
这个问题在这里已经有了答案: Is the function strcmpi in the C standard libary of ISO? (3 个答案) 关闭 8 年前。 我有一个问题,为什么
我目前使用的是共享主机方案,我不确定它使用的是哪个版本的 MySQL,但它似乎不支持 DATETIMEOFFSET 类型。 是否存在支持 DATETIMEOFFSET 的 MySQL 版本?或者有计划
研究 Seam 3,我发现 Seam Solder 允许将 @Named 注释应用于包 - 在这种情况下,该包中的所有 bean 都将自动命名,就好像它们符合条件一样@Named 他们自己。我没有看到
我知道 .append 偶尔会增加数组的容量并形成数组的新副本,但 .removeLast 会逆转这种情况并减少容量通过复制到一个新的更小的数组来改变数组? 最佳答案 否(或者至少如果是,则它是一个错
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
noexcept 函数说明符是否旨在 boost 性能,因为生成的对象中可能没有记录异常的代码,因此应尽可能将其添加到函数声明和定义中?我首先想到了可调用对象的包装器,其中 noexcept 可能会产
我正在使用 Angularjs 1.3.7,刚刚发现 Promise.all 在成功响应后不会更新 angularjs View ,而 $q.all 会。由于 Promises 包含在 native
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我正在编写一个玩具(物理)矢量库,并且遇到了 GHC 坚持认为函数应该具有 Integer 的问题。是他们的类型。我希望向量乘以向量以及标量(仅使用 * ),虽然这可以通过仅使用 Vector 来实现
PHP 的 mail() 函数发送邮件正常,但 Swiftmailer 的 Swift_MailTransport 不起作用! 这有效: mail('user@example.com', 'test
我尝试通过 php 脚本转储我的数据,但没有命令行。所以我用 this script 创建了我的 .sql 文件然后我尝试使用我的脚本: $link = mysql_connect($host, $u
使用 python 2.6.4 中的 sqlite3 标准库,以下查询在 sqlite3 命令行上运行良好: select segmentid, node_t, start, number,title
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我是一名优秀的程序员,十分优秀!