C语言逻辑移位和算术移位学习笔记

C语言的移位操作是程序员日常使用非常频繁的操作之一,用好了移位操作可以为我们省去不少的时间并且程序也可以写得更加漂亮。我们说移位操作是可以分为 左移  右移 的,左移的位操作符是 <<,左移一位表示将原数值乘以 2如果左移使其溢出了将不能得到正确的结果);右移的位操作符是 >>,右移一位表示将原数值除以 2。例如左移操作,如下图所示:

左移3位本质上就是将左边 3 位去掉,在右边用 3 个 0 补全,这就是左移了。看似移位操作很简单,其实这里面是有坑存在的。

如果你认为右移也是这样的话,那么你就掉坑里了,坑就坑在右移上。因为右移是又可以分为逻辑右移(slr)  算术右移(sar) 两种方式的。因为右移操作存在一个左移不增面临的问题:从左边移入新位的时候,可以有两种方案。一种是逻辑移位,左边移入的位用 0 填充;另一种是算术移位,左边移入的位由该值得符号位决定,符号位为 1 则移入 1 ,符号位为 0 则移入 0 ,这样移位可以保证原数值的正负性质不变。如果值 10010110 右移两位,逻辑移位的结果是 00100101,算术移位的结果则是 11100101

左移没有算术左移和逻辑左移之分(因为算术左移和逻辑左移是相同的)



标准 说明无符号值执行的所有移位操作都是逻辑移位,但对于有符号值,到底是采用逻辑移位还是算术移位取决于编译器。你可以编写一个简单的测试程序,看看你的编译器使用哪种移位方式,但这并不能保证其他编译器也会用同样的方式。因此,一个程序如果使用了有符号数的右移操作,他就是不可移植的

我自己在PC上做了测试,代码如下

 

 代码如下 复制代码
#include <stdio.h>
int main(int argc, char const *argv[])
{
    int a = -4; //计算机存储是以补码的形式存储的,所以是 11111100
    printf("before a=%d\n", a);
    a = a >> 1; // 右移一位
    printf("after a=%d\n", a); // 如果是-2则是算术右移,如果是126则是逻辑右移
    return 0;
}

 
执行结果如下图所示:

说明在Windows上VS2015环境下编译器是采用算术右移的。

我们可能会遇到类似这样的情况:
a << -5

左移 -5 位表示什么呢?是表示右移 5 位么,还是根本不移位?又或者移位的位数比操作数的位数还要多,会发生什么呢?

标准 说明这类位移的行为是未定义的,所以他是由编译器决定的。所以我们应该尽量避免这种情况的发生,它会导致我们的程序出现一些你无法预料的错误,并且使用这类移位操作是不可移植的。

时间: 2024-09-15 09:12:15

C语言逻辑移位和算术移位学习笔记的相关文章

C语言一维数组初步学习笔记_C 语言

数组 可以存储一组或者多组数值的变量,里面包含多个元素,数组的每个成员都是一个数组元素. 一维数组 定义:类型 数组名[常量表达式] = {值1, 值2, 值3-}; int a[3] = {0, 1, 2}; float f[2] = {1.2, 2.3, 3.14}; char str[] = {'h', 'e', 'l', 'l', 'o'}; chat str1 = "iPhone";//这也是定义字符数组的方法,字符数组后面会详细讲解,这里先了解一下 当数组元素个数为变量时,

C语言返回数组的学习笔记

问题来源于今天三班一个学霸问我,他的程序没法运行,什么情况? 那来看看他写的程序,虽然看着有些不舒服.  代码如下 复制代码 #include <stdio.h> #include <string.h> int main() {  char tra(char str[]);  char b[80];  gets(b);  puts(tra(b)); return 0; } char tra(char str[]) {  char stri[80]; int i,j,k=0; i=s

【学习】 R语言与机器学习学习笔记(1)K-近邻算法

前言 最近在学习数据挖掘,对数据挖掘中的算法比较感兴趣,打算整理分享一下学习情况,顺便利用R来实现一下数据挖掘算法. 数据挖掘里我打算整理的内容有:分类,聚类分析,关联分析,异常检测四大部分.其中分类算法主要介绍:K-近邻算法,决策树算法,朴素贝叶斯算法,支持向量机,神经网络,logistic回归. 写这份学习笔记主要以学校data mining课程的课件为主,会参考一堆的baidu,一堆的google,一堆的blog,一堆的book以及一堆乱七八糟的资料,由于精力有限,恕不能一一列出,如果有认

ruby语言学习笔记2

ruby学习笔记2  (摘自<ruby程序设计语言教程(中文版)>.pdf,全书25页) 1.同一个问题ruby有多个解决方案,途径 ruby之父:松本行弘(Matz),1993年创立 ruby的偶数发行版为稳定版 圆括号在方法调用中是可选的.即无论函数定义还是调用函数,括号都随意的 vim为ruby配置一个插件才好用:vim_ruby:在vimrc中添加<map> <F7> :!ruby -Ku % <CR>      表示用F7键运行  -Ku表示utf

PHP学习笔记 (1) 环境配置与代码调试

一配置PHP环境 1.了解什么是PHP PHP("PHP: Hypertext Preprocessor",超文本预处理器的字母缩写) PHP,是英文超级文本预处理语言Hypertext Preprocessor的缩写.PHP 是一种 HTML 内嵌式的语言,是一种在服务器端执行的嵌入HTML文档的脚本语言,语言的风格有类似于C语言,被广泛的运用 2.PHP的背景和优势 PHP的发展背景 1).1994年由Rasmus Lerdorf创建,开始是一个简单的Perl语言编写的程序,用统计

node.js学习笔记(9) 和谐模式

众所周知,ECMAScript 是一种开放的.国际上广为接受的脚本语言规范. 它本身并不是一种脚本语言.正如在 Web 应用程序中执行有用操作的 bean 集合(例如,Netscape 的 AWT)是 Sun 的 JavaBean 规范的一种实现一样,JavaScript 是 ECMAScript 规范的一种实现. 2015年6月17日,ECMA国际发布了EcmaScript2015,即EcmaScript6(以下简称ES6)草案的正式版.ES6是继ES5之后的一次主要改进,语言规范由ES5.1

php5学习笔记(转)

php5|笔记 作者: whhwq在phpv.net看到的感觉不错/*+-------------------------------------------------------------------------------+| = 本文为Haohappy读<<Core PHP Programming>> | = 中Classes and Objects一章的笔记 | = 翻译为主+个人心得 | = 为避免可能发生的不必要的麻烦请勿转载,谢谢 | = 欢迎批评指正,希望和所有

数据库学习笔记(一)

笔记|数据|数据库 这是我学习数据库时候的笔记,都是非常简单,非常基础的有关数据库的知识,最近整理一下,希望大家不要蛋蛋我啊,呵呵 数据库学习笔记(一)                         --绪论及基本概念 一,             数据:描述事物的符号记录称为数据. 二,             数据库:指长期存储在计算机内的.有组织.可共享的数据集合. 三,             数据库管理系统:数据管理的软件,主要以下功能:                   1, 

MySQL数据库学习笔记(一)

mysql|笔记|数据|数据库         我一直从事Informix和Oracle数据库开发,有一天发现网络上有一种小巧别致的数据库,被广泛使用,从MySQL的网站http://www.mysql.com/我下载了它的数据库软件,使用过后觉得真的挺好,这是我的一点学习笔记希望对各位初学者有点帮助. 1.       MySQL数据库介绍 MySQL 是瑞典的MySQL AB公司开发的一个可用于各种流行操作系统平台的关系数据库系统,它具有客户机/服务器体系结构的分布式数据库管理系统.MySQ