当前位置: 首页 > news >正文

C++20 中位移位运算符的统一行为:深入解析与实践指南

文章目录

    • 1. 位移位运算符的基础
      • 1.1 左移运算符(`<<`)
      • 1.2 右移运算符(`>>`)
    • 2. C++20 对位移位运算符的统一
      • 2.1 移位数量超出操作数位宽
      • 2.2 负数移位
    • 3. 实践中的注意事项
    • 4. 示例代码
    • 5. 总结

在 C++ 的发展历程中,位移位运算符( <<>>)一直是语言的核心特性之一,广泛应用于性能优化、底层硬件操作和数据压缩等领域。然而,在 C++20 之前,这些运算符的行为在某些情况下存在不确定性,尤其是涉及负数移位或移位数量超出操作数位宽时。C++20 对位移位运算符的行为进行了统一和规范,解决了这些问题,使得代码更加可移植和安全。

1. 位移位运算符的基础

位移位运算符包括左移(<<)和右移(>>)两种。它们的作用是将操作数的二进制表示向左或向右移动指定的位数。移位运算符的语法如下:

shift-expression << additive-expression  // 左移
shift-expression >> additive-expression  // 右移

两个操作数都必须是整数类型,结果的类型与提升后的左操作数类型相同。

1.1 左移运算符(<<

左移运算符将第一个操作数的二进制表示向左移动指定的位数,空出的位用 0 填充。例如:

int a = 1;  // 二进制为 0001
int result = a << 2;  // 结果为 0100,即十进制的 4

左移一位的效果等同于将操作数乘以 2 的移位次数次方。

1.2 右移运算符(>>

右移运算符将第一个操作数的二进制表示向右移动指定的位数。对于无符号整数,空出的位用 0 填充;对于有符号整数,空出的位用符号位填充(即算术右移)。例如:

int a = 8;  // 二进制为 00001000
int result = a >> 2;  // 结果为 00000010,即十进制的 2unsigned int b = 8;  // 二进制为 00001000
unsigned int result2 = b >> 2;  // 结果为 00000010,即十进制的 2

右移一位的效果等同于将操作数除以 2 的移位次数次方。

2. C++20 对位移位运算符的统一

在 C++20 之前,位移位运算符的行为存在一些模糊之处,尤其是在以下几种情况:

  1. 移位数量超出操作数位宽:例如,int a = 1; a << 32; 的行为在旧标准中是未定义的。
  2. 负数移位:对于负数的右移,不同的编译器可能有不同的实现。

C++20 对这些问题进行了明确和统一:

2.1 移位数量超出操作数位宽

C++20 规定,如果移位数量大于或等于操作数的位宽,则结果为 0。例如:

int a = 1;  // 32 位整数
int result = a << 32;  // 结果为 0

这一规定消除了旧标准中移位数量超出位宽时的未定义行为,使得代码更加安全和可预测。

2.2 负数移位

C++20 明确了负数右移的行为:对于有符号整数的右移,空出的位用符号位填充。这意味着负数右移的结果仍然是负数,且行为是确定的。例如:

int a = -8;  // 二进制为 11111111 11111000
int result = a >> 1;  // 结果为 11111111 11111100,即十进制的 -4

这一规定统一了不同编译器之间的差异,使得负数移位的行为更加一致。

3. 实践中的注意事项

尽管 C++20 对位移位运算符的行为进行了统一,但在实际开发中,仍需注意以下几点:

  1. 避免使用负数移位:虽然 C++20 明确了负数移位的行为,但这种操作仍然可能导致意外结果,尤其是在跨平台开发中。
  2. 移位数量的合法性:在移位操作中,移位数量应始终小于操作数的位宽,以避免结果为 0。
  3. 使用无符号整数:在处理移位操作时,优先使用无符号整数,以避免符号位带来的复杂性。

4. 示例代码

以下是一个示例代码,展示了 C++20 中位移位运算符的统一行为:

#include <iostream>
#include <bitset>int main() {// 左移示例int a = 1;int leftShiftResult = a << 3;  // 左移 3 位std::cout << "Left Shift: " << leftShiftResult << std::endl;// 右移示例int b = -8;int rightShiftResult = b >> 1;  // 右移 1 位std::cout << "Right Shift: " << rightShiftResult << std::endl;// 移位数量超出位宽int c = 1;int invalidShift = c << 32;  // 移位数量超出位宽std::cout << "Invalid Shift: " << invalidShift << std::endl;return 0;
}

输出结果如下:

Left Shift: 8
Right Shift: -4
Invalid Shift: 0

5. 总结

C++20 对位移位运算符的行为进行了统一和规范,解决了旧标准中移位数量超出位宽和负数移位的不确定性问题。这一改进不仅提高了代码的可移植性和安全性,也使得位移位运算符的使用更加直观和可靠。在实际开发中,开发者应遵循最佳实践,避免使用负数移位,并确保移位数量合法,以充分利用 C++20 带来的好处。

通过理解和应用这些改进,我们可以编写出更加高效、可靠和跨平台兼容的代码,进一步提升 C++ 在底层开发和性能优化领域的优势。

相关文章:

C++20 中位移位运算符的统一行为:深入解析与实践指南

文章目录 1. 位移位运算符的基础1.1 左移运算符&#xff08;<<&#xff09;1.2 右移运算符&#xff08;>>&#xff09; 2. C20 对位移位运算符的统一2.1 移位数量超出操作数位宽2.2 负数移位 3. 实践中的注意事项4. 示例代码5. 总结 在 C 的发展历程中&#xff0c;…...

Linux——基本指令

我们今天学习Linux最基础的指令 ls 指令 语法&#xff1a; ls [选项] [⽬录或⽂件] 功能&#xff1a;对于⽬录&#xff0c;该命令列出该⽬录下的所有⼦⽬录与⽂件。对于⽂件&#xff0c;将列出⽂件名以及其他信 息。 命令中的选项&#xff0c;一次可以传递多个 &#xff0c…...

MySql面试总结(二)

WHERE 子句优化 截至2024年7月,MySQL最新稳定版本是8.2,并不存在MySQL 8.4 。下面从常见的几个方面为你介绍 MySQL 8.x 中 WHERE 子句的优化方法: 1. 确保使用索引 原理:索引可以加快数据的查找速度,当 WHERE 子句中的条件列有索引时,MySQL 可以直接定位到符合条件的数…...

Pytorch中的主要函数

目录 一、torch.manual_seed(seed)二、torch.cuda.manual_seed(seed)三、torch.rand(*size, outNone, dtypeNone, layouttorch.strided, deviceNone, requires_gradFalse)四、给大家写一个常用的自动选择电脑cuda 或者cpu 的小技巧五、torch.version.cuda&#xff1b;torch.bac…...

Java实现大数据量导出报表

一、实现方式 在Java中&#xff0c;导出数据到Excel有多种方式&#xff0c;每种方式都有其优缺点&#xff0c;适用于不同的场景。以下是常见的几种方式及其特点&#xff1a; 1.1 Apache POI Apache POI 是 Java 中最流行的库&#xff0c;支持读写 Excel 文件&#xff08;包括…...

大语言模型 智能助手——既能生成自然语言回复,又能在必要时调用外部工具获取实时数据

示例代码&#xff1a; import json from langgraph.graph import Graph, END,StateGraph from langchain_core.utils.function_calling import convert_to_openai_function from langchain_community.tools.openweathermap import OpenWeatherMapQueryRun from langchain_core…...

PyTorch 系统教程:理解机器学习数据分割

数据分割是机器学习中的一个基本概念&#xff0c;它直接影响模型的性能和泛化。在本文中&#xff0c;我们将深入研究为什么数据分割在机器学习中很重要&#xff0c;并演示如何使用PyTorch有效地实现它。 理解数据分割 数据分割是将数据集划分为单独的组以进行训练、验证和测试…...

分水岭算法(Watershed Algorithm)教程:硬币分割实例

import cv2 import numpy as np# 1. 图像预处理 img cv2.imread("./water/water_coins.jpeg") gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU) kernel np.ones((3, 3), np.int8)…...

【STM32项目实战系列】基于STM32G474的FDCAN驱动配置

前言&#xff1a;本周工作中用到了CANFD的驱动&#xff0c;由于以前都是用到的CAN2.0&#xff0c;所以过程并不是特别的顺利&#xff0c;所以中间遇到几个比较小的问题导致自己卡住了一段时间&#xff0c;特此记录一下并完全奉上自己的配置的源码。 1&#xff0c;CANFD配置与简…...

shell文本处理

shell文本处理 一、grep ​ 过滤来自一个文件或标准输入匹配模式内容。除了 grep 外&#xff0c;还有 egrep、fgrep。egrep 是 grep 的扩展&#xff0c;相当于 grep -E。fgrep 相当于 grep -f&#xff0c;用的比较少。 用法 grep [OPTION]... PATTERN [FILE]...支持的正则描述…...

如何利用客户端双向TLS认证保护云上应用安全

双向TLS(mTLS)通过要求服务器和客户端双方使用数字证书来验证彼此身份&#xff0c;从而扩展了传统TLS的安全性。常规的TLS只会验证服务器的身份(如大家的浏览器在验证网站时的场景)&#xff0c;而mTLS确保在任何数据交换发生之前&#xff0c;双方都对彼此持有信任。在本文中&am…...

nlp第十节——LLM相关

一、模型蒸馏技术 本质上是从一个大模型蒸馏出小模型&#xff0c;从小模型训练出来的概率分布&#xff08;如自回归模型预测下一个字的概率分布&#xff09;分别与大模型预测的概率分布和ground label求loss。与大模型预测的概率分布用KL散度求loss&#xff0c;与ground label用…...

T-SQL 语言基础: SQL 数据库对象元数据及配置信息获取

目录 介绍目录视图 获取表和架构名称获取列信息 信息架构视图 获取表信息获取列信息 系统存储过程和函数 获取对象列表获取对象详细信息获取约束信息获取数据库属性信息 总结引用 介绍 在 SQL 数据库管理中&#xff0c;获取数据库对象的元数据信息是至关重要的。元数据提供了…...

ue5 创建多列StreeView的方法与理解

创建StreeView的多列样式怎么就像是创建单行单列差不多&#xff1f;貌似就是在单行单列中加入了多列widget? 示例代码 DetailTabWidget #pragma once #include "TreeViewItemBase.h"class SDetailTabWidget : public SCompoundWidget {SLATE_BEGIN_ARGS(SDetailT…...

C# OnnxRuntime部署DAMO-YOLO香烟检测

目录 说明 效果 模型信息 项目 代码 下载 参考 说明 效果 模型信息 Model Properties ------------------------- --------------------------------------------------------------- Inputs ------------------------- name&#xff1a;input tensor&#xff1a;Floa…...

陕西省地标-DB61/T 1121-2018 政务服务中心建设和运营规范

揭秘陕西省智慧政务服务中心新标准&#xff1a;打造高效便捷的服务新体验 随着信息化时代的深入发展&#xff0c;智慧政务已成为提升政府服务效率、优化营商环境的重要举措。陕西省作为全国政务改革的先行者&#xff0c;近期颁布了《陕西省地标-DB61_T 1121-2018 政务服务中心…...

UDP协议(20250303)

1. UDP UDP:用户数据报协议&#xff08;User Datagram Protocol&#xff09;&#xff0c;传输层协议之一&#xff08;UDP&#xff0c;TCP&#xff09; 2. 特性 发送数据时不需要建立链接&#xff0c;节省资源开销不安全不可靠的协议 //一般用在实时性比较高…...

【四.RAG技术与应用】【12.阿里云百炼应用(下):RAG的云端优化与扩展】

在上一篇文章中,我们聊了如何通过阿里云百炼平台快速搭建一个RAG(检索增强生成)应用,实现文档智能问答、知识库管理等基础能力。今天咱们继续深入,聚焦两个核心问题:如何通过云端技术优化RAG的效果,以及如何扩展RAG的应用边界。文章会穿插实战案例,手把手带你踩坑避雷。…...

Docker新手入门(持续更新中)

一、定义 快速构建、运行、管理应用的工具。 Docker可以帮助我们下载应用镜像&#xff0c;创建并运行镜像的容器&#xff0c;从而快速部署应用。 所谓镜像&#xff0c;就是将应用所需的函数库、依赖、配置等应用一起打包得到的。 所谓容器&#xff0c;为每个镜像的应用进程创建…...

【星云 Orbit • STM32F4】08. 用判断数据头来接收据的串口通用程序框架

【星云 Orbit • STM32F4】08. 用判断数据头来接收据的串口通用程序框架 1. 引言 本教程旨在帮助嵌入式开发小白从零开始&#xff0c;学习如何在STM32F407微控制器上实现一个基于串口的数据接收程序。该程序能够通过判断数据头来接收一串数据&#xff0c;并将其存储到缓冲区中…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

WEB3全栈开发——面试专业技能点P4数据库

一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库&#xff0c;基于 mysql 库改进而来&#xff0c;具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点&#xff1a; 支持 Promise / async-await&#xf…...

2025.6.9总结(利与弊)

凡事都有两面性。在大厂上班也不例外。今天找开发定位问题&#xff0c;从一个接口人不断溯源到另一个 接口人。有时候&#xff0c;不知道是谁的责任填。将工作内容分的很细&#xff0c;每个人负责其中的一小块。我清楚的意识到&#xff0c;自己就是个可以随时替换的螺丝钉&…...

StarRocks 全面向量化执行引擎深度解析

StarRocks 全面向量化执行引擎深度解析 StarRocks 的向量化执行引擎是其高性能的核心设计&#xff0c;相比传统行式处理引擎&#xff08;如MySQL&#xff09;&#xff0c;性能可提升 5-10倍。以下是分层拆解&#xff1a; 1. 向量化 vs 传统行式处理 维度行式处理向量化处理数…...

软件工程教学评价

王海林老师您好。 您的《软件工程》课程成功地将宏观的理论与具体的实践相结合。上半学期的理论教学中&#xff0c;您通过丰富的实例&#xff0c;将“高内聚低耦合”、SOLID原则等抽象概念解释得十分透彻&#xff0c;让这些理论不再是停留在纸面的名词&#xff0c;而是可以指导…...

Go 语言中的内置运算符

1. 算术运算符 注意&#xff1a; &#xff08;自增&#xff09;和--&#xff08;自减&#xff09;在 Go 语言中是单独的语句&#xff0c;并不是运算符。 package mainimport "fmt"func main() {fmt.Println("103", 103) // 13fmt.Println("10-3…...

Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的方法

在 MyBatis 中使用 useGeneratedKeys"true" 获取新插入记录的自增 ID 值&#xff0c;可通过以下步骤实现&#xff1a; 1. 配置 Mapper XML 在插入语句的 <insert> 标签中设置&#xff1a; xml 复制 下载 运行 <insert id"insertUser" para…...