IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 编程参考 - C/C++中的左右移位操作 -> 正文阅读

[C++知识库]编程参考 - C/C++中的左右移位操作

左移右移位运算符

Left shift and right shift operators (<< and >>)

位移运算符是右移运算符(>>),它将整数或枚举类型表达式的位移到右边,左移运算符(<<),它将位移到左边。

The bitwise shift operators are the right-shift operator (>>), which moves the bits of an integer or enumeration type expression to the right, and the left-shift operator (<<), which moves the bits to the left.

Syntax

shift-expression:

shift-expression << additive-expression

shift-expression >> additive-expression

对无符号的整数的位移操作:

左移:右边空出的位补零(zero filled),左边移除的位丢弃。

右移:左边空出的位补零,右边移除的位丢弃。

例子:

0x08 >> 1 = 0x04

0x01 << 1 = 0x00

或使用下面代码:

#include <stdio.h>

#include <stdlib.h>

int main(int arc, char** args)

{

???int a, val;

???unsigned int b, valb;

???char* str;

???printf("sizeof(int) is %ld\n", sizeof(int));

???str = args[1];

???printf("The string is: %s\n", str);

???a = strtol(str,(char**)NULL, 16);

???b = strtol(str,(char**)NULL, 16);

???printf("The convert number is: 0x%X\n", a);

???val = a>>1;

???printf("Int value>>1 is 0x%X\n", val);

???val = a<<1;

???printf("Int value<<1 is 0x%X\n", val);

? ?valb = b>>1;

???printf("Unsigned Int value>>1 is 0x%X\n", valb);

???valb = b<<1;

???printf("Unsigned Int value<<1 is 0x%X\n", valb);

???return 0;

}

$ gcc -o main main.c

$ ./main 0xFFFFFFFF

sizeof(int) is 4

The string is: 0xFFFFFFFF

The convert number is: 0xFFFFFFFF

Int value>>1 is 0xFFFFFFFF

Int value<<1 is 0xFFFFFFFE

Unsigned Int value>>1 is 0x7FFFFFFF

Unsigned Int value<<1 is 0xFFFFFFFE

我的GCC版本:

gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)

可以看到,0xFFFFFFFF左移一位是0xFFFFFFFE,右移一位是0x7FFFFFFF。

对有符号的整数的位移操作:(根据我的编译器进行的测试)

- 左移:

如果是负数,则最高位是1,左移时会保持最高位是1,结果就是负数。

如果是非负数,则正常移位,移位后的结果的正负性,根据最高位来判定。

- 右移:

如果是负数,则最高位是1,右移时空出的位用1补齐。

如果是非负数,则最高位不是1,右移时空出的位用0补齐。

移位和类型提升 / Shifts and promotions

移位操作符和两边的操作数构成了此移位表达式,操作数要求是整数。根据标准转换的规则进行整型类型提升(Standard conversions | Microsoft Docs)。

整个移位表达式的结果的类型,和整型提升后的类型一样。

如下例子所示,char型的变量,类型提升后变成整型:

#include <iostream>

#include <typeinfo>

using namespace std;

int main() {

??char char1 = 'a';

? auto promoted1 = char1 << 1;

??cout << typeid(promoted1).name() << endl;

??auto promoted2 = char1 << 10;

??cout << typeid(promoted2). << endl;

??return 0;

}

这里输出的类型的名字,如果是MSVC编译器,是“int”。

用GCC编译器,输出是“i”。

细节

E1 << E2 中,如果E2是负的,则此移位操作的结果是未定义的。

如果E2大于或等于移位表达式的位数,同样也是未定义的。

如果E2为0,则不进行移位操作。

备注 Footnotes

以下是C++11 ISO规范(INCITS/ISO/IEC 14882-2011[2012])第5.8.2和5.8.3节中对移位操作符的描述。

E1 << E2的值是E1左移了E2数量的位;空出的位被填为零。如果E1是无符号类型,结果的值是E1×2^E2,如果值溢出,要对此结果的类型可表示的最大值加1后取模。如果E1是有符号类型和非负值,并且E1×2^E2可以在结果类型的相应无符号类型中表示,那么该值转换为结果类型后,就是该值;否则,行为未定义。

E1>>E2的值是E1右移了E2数量的位。如果E1是无符号类型,或者E1是有符号类型和非负值,结果值是E1/2^E2商的整数部分。如果E1是有符号类型且为负值,那么结果值是根据实现定义的。


The following is the description of the shift operators in the C++11 ISO specification (INCITS/ISO/IEC 14882-2011[2012]), sections 5.8.2 and 5.8.3.

The value of?E1 << E2?is?E1?left-shifted?E2?bit positions; vacated bits are zero-filled. If?E1?has an unsigned type, the value of the result is?E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. Otherwise, if?E1?has a signed type and non-negative value, and?E1 × 2E2?is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.

The value of?E1 >> E2?is?E1?right-shifted?E2?bit positions. If?E1?has an unsigned type or if?E1?has a signed type and a non-negative value, the value of the result is the integral part of the quotient of?E1/2E2. If?E1?has a signed type and a negative value, the resulting value is implementation-defined.


参考:

Left shift and right shift operators ('<>') | Microsoft Docs

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-06-26 16:45:42  更:2022-06-26 16:46:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:42:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码