深入理解C语言中的移位运算

深入理解C语言中的移位运算说明 本文主要摘录自 深入理解计算机系统 第二章信息的表示与处理 nbsp C 语言还提供了一组移位运算 以便向左或者向右移动位模式 对于一个位表示为 xn 1 xn 2 x0 的操作数 x C 表达式 x 有一个相应的右移运算 xk 但是它的行为有点微妙 一般而言 机器支持两种形式的右移 逻辑右移和算术右移 逻辑右移在左端补 k 个 0 得到的结果是 0 0 xn 1 xn 2 xk 算术右

说明:本文主要摘录自《深入理解计算机系统》第二章信息的表示与处理。

移位运算:

        C语言还提供了一组移位运算,以便向左或者向右移动位模式。对于一个位表示为[xn-1,xn-2,…,x0]的操作数x,C表达式x<

        有一个相应的右移运算x>>k,但是它的行为有点微妙。一般而言,机器支持两种形式的右移:逻辑右移和算术右移。逻辑右移在左端补k个0,得到的结果是[0,…,0,xn-1,xn-2,…,xk]。算术右移是在左端补k个最高有效位的值,得到的结果是[xn-1,…,xn-1,xn-1,xn-2,…,xk]。这种做法看上去可能有点奇特,但是我们会发现它对有符号整数数据的运算非常有用。

        让我们来看一个例子,下面的表给出了对某些实例8位数据做不同的移位操作得到的结果。

操作

参数X

[0110 0011]    [1001 0101]

X<<4

[0011 0000]    [0101 0000]

X>>4(逻辑右移)

[0000 0110]    [0000 1001]

X>>4(算术右移)

[0000 0110]    [1111 1001]

        斜体的数字表示的是最右端(左移)或最左端(右移)填充的值。可以看到除了一个条目之外,其他的都涉及填充0。唯一的例外是算术右移[]的情况。因为操作数的最高位是1,填充的值就是1。

        C语言标准并没有明确定义应该使用哪种类型的右移。对于无符号数据(也就是以限定词unsigned声明的整型对象),右移必须是逻辑的。而对于有符号数据(默认的声明的整型对象),算术的或者逻辑的右移都可以。不幸的是,这就意味着任何假设一种或者另一种右移形式的代码都潜在着可移植性问题。然而,实际上,几乎所有的编译器/机器组合都对有符号数据使用算术右移,且许多程序员也都假设机器会使用这种右移。

另一方面,Java对于如何进行右移有明确的定义。表达式x>>k会将x算术右移k个位置,而x>>>k会对x做逻辑右移。

当移动k位,这里k很大时

        对于一个由w位组成的数据类型,如果要移动k≥w位会得到什么结果呢?例如,在一个32位机器上计算下面的表达式会得到什么结果:

Int       lval = 0xFEDCBA98  << 32;

int       lval = 0xFEDCBA98  >> 36

unsigned  lval = 0xFEDCBA98u  >> 40;

        C语言标准很小心地规避了说明在这种情况下该如何做。在许多机器上,当移动一个w位的值时,移位指令只考虑位移量的低log2w位,因此实际上位移量就是通过计算k mod w得到的。例如,在一台采用这个规则的32位机器上,上面三个移位运算分别是移动0、4和8位,得到结果:

Lval    0xFEDCBA98

Aval    0xFEDCBA9

Uval    0x00FEDCBA

        不过这种行为对于C程序来说是没有保证的,所以移位数量应该保持小于字长。另一方面,Java特别要求位移数量应该按照我们前面所讲的求模的方法来计算。

与移位运算有关的操作符优先级问题

        常常有人会写这样的表达式1<<2+3<<4,其本意是(1<<2)+(3<<4)。但是在C语言中,前面的表达式等价于1<<(2+3)<<4,这是由于加法(和减法)的优先级比移位运算要高。然后,按照从左至右结合性规则,括号应该是这样打的(1<<(2+3))<<4,因此得到的结果是512,而不是期望的52。在C表达式中搞错优先级是一种常见的程序错误,而且常常很难检查出来。所以当你拿不准的时候,请加上括号!

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

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

(0)
上一篇 2026年3月17日 下午3:58
下一篇 2026年3月17日 下午3:58


相关推荐

  • Laravel框架_php laravel框架

    Laravel框架_php laravel框架laravel框架一、laravel简介laravel是一套优雅简介的PHP开发框架,受欢迎程度非常之高,功能强大,工具齐全;https://www.jianshu.com/p/206592c78113二、简单介绍1、laravel是基于mvc模式的php框架,m——模型层,v——视图层,c——控制器层;以下为laravel框架的目录文件,框出来的文件目录将在后续中用到:2、什么是MV…

    2025年8月23日
    3
  • matlab——for循环「建议收藏」

    matlab——for循环「建议收藏」简单for循环for循环用来循环处理数据。例:输出1~100的和>>clear>>sum=0;>>fori=1:100sum=sum+i;end>>sumsum=5050解释:i从1到100,每次增加一个,该共循环100次注意:分号的位置;不能使用“+=”符号…

    2022年6月25日
    43
  • c程序设计,贪吃蛇程序是什么_C语言编写贪吃蛇

    c程序设计,贪吃蛇程序是什么_C语言编写贪吃蛇C语言,贪吃蛇程序设计一.代码分析(1)头文件(2)宏定义(3)全局变量(4)函数部分1)绘制地图函数DreawMap(),2)食物位置函数FoodRand()3)键盘控制移动函数ControlMove()函数4)移动函数Move()函数5)蛇身开始函数Isnake()函数6)判断食物是否被吃到函数Jfood()函数7)判断是否碰到墙Jwell()函数8)判断是否碰到蛇身Jsnake()函数9)计算分数和难度Showf()函数10)清空存储空间函数二.代码附录一.代码分析(1)头文件1.include

    2025年7月22日
    4
  • CSS——06扩展:高级

    CSS——06扩展:高级人生苦短,要学就只学有用的【前端教学-CSS-高阶技巧】CSS样式初始CSS高级技巧目标理解能说出元素显示隐藏最常见的写法能说出精灵图产生的目的能说出去除图片底侧空白缝隙的方法应用能写出最常见的鼠标样式能使用精灵图技术,这个技术比较重要能用滑动门做导航栏案例,这个技术比较重要1.元素的显示与隐藏目的让一个元素在页面中消失或者显示出来场景类似网站广告,当我们点击关闭就不见了,但是我们重新刷新页面,会重新出现!1.1display显示(重点)…

    2022年5月29日
    43
  • Wan2.1 VAE数据库集成教程:使用MySQL管理生成结果与用户数据

    Wan2.1 VAE数据库集成教程:使用MySQL管理生成结果与用户数据

    2026年3月14日
    1
  • TabLayout+ViewPager+Fragment实现切页展示「建议收藏」

    TabLayout+ViewPager+Fragment实现切页展示「建议收藏」写在前面目前大多数的APP都采用的是几个Tab标签以及多个界面滑动的形式来提供多层次的交互体验,最为常用的做法就是采用TabLayout+ViewPager+Fragment的方式,最近在公司项目中遇到类似的界面,也看了各个论坛很多份博客,但是发现都没有完全把这种方法的坑填完,因此写下这篇博客,一方面是对知识的总结,另一方面也能让其他开发者们少走一些弯路,博客内容主要分为四个方面:T…

    2022年7月22日
    28

发表回复

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

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