”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > ## 为什么右移位运算符在大移位值时会表现出意外行为?

## 为什么右移位运算符在大移位值时会表现出意外行为?

发布于2024-11-04
浏览:456

## Why Does the Right Shift Operator Exhibit Unexpected Behavior with Large Shift Values?

右移运算符的有趣行为

右移运算符 (>>) 在处理较大的右移值时表现出特殊的行为。考虑以下程序:

#include 
#include 

int foo(int a, int b)
{
   return a >> b;
}

int bar(uint64_t a, int b)
{
   return a >> b;
}

int main()
{
    std::cout > 32: " > 32) > (int)32: " > (int)32) 

foo(1, 32) 的预期输出将为 0,但令人惊讶的是,它返回 1。这可以归因于以下内容:

逻辑移位与算术运算Shift

在 x86/x86-64 架构上,右移运算符实际上执行逻辑右移,这意味着它用 0 填充空出的位,而不管左操作数的符号。该行为类似于使用 >>> b.

编译器优化

在 foo(1, 32) 的情况下,值 32 被转换为int,实际上被截断为 32 位。由于 int 可以容纳的最大值为 231-1,因此右移本质上是 >>> (32 % 32),其计算结果为 0。

Undefined行为

相关的 C 标准规定,对于计数大于或等于提升的左操作数宽度的右移,“行为未定义”。在这种情况下,1 >> 32 和 (int)1 >> (int)32 的计数都大于 32,导致不可预测的结果。

与 bar(1, 32)[ 的差异&&&]

函数bar采用64位无符号整数,保证其宽度大于32。因此,bar中的右移不受未定义行为的影响。

结论

处理大移位值时,右移运算符的行为变得不明确。在 x86/x86-64 架构上,执行逻辑右移,而在 ARM 上,可能会使用不同的实现。由于未定义的行为,在可移植代码中应避免计数大于或等于操作数宽度的右移结果。

最新教程 更多>
  • 如何使用 Go 的 pq 包将数据从 STDIN 导入到 PostgreSQL?
    如何使用 Go 的 pq 包将数据从 STDIN 导入到 PostgreSQL?
    如何将行从 STDIN 导入到 Postgresql? [重复]在 Go 中,您可以使用 pq 包将行从 STDIN 导入到 PostgreSQL。以下是分步解决方案:第 1 步:准备数据库连接import ( "database/sql" "githu...
    编程 发布于2024-11-17
  • 如何解决Python中类型提示的循环导入?
    如何解决Python中类型提示的循环导入?
    没有循环导入的 Python 中的类型提示在尝试将一个大类分成两个较小的类时,您会遇到循环问题进口。 “main”类导入 mixin 类,并且 mixin 类在其类型提示中引用“main”类。这会导致导入循环,导致类型提示无法正常工作。要解决此问题,可以考虑以下方法:# main.py from _...
    编程 发布于2024-11-17
  • 什么是 jQuery.fn?为什么它是 jQuery.prototype 的别名?
    什么是 jQuery.fn?为什么它是 jQuery.prototype 的别名?
    深入研究 jQuery.fn:原型的别名在 jQuery 库中,您可能会遇到神秘的 jQuery.fn。这个神秘的 fn 代表什么以及它有什么作用?Prototype 的作用在 JavaScript 领域,prototype 属性是一个至关重要的组成部分构造函数。当您使用特定构造函数创建实例时,该实...
    编程 发布于2024-11-17
  • 如何用Python实现高效的双向哈希表?
    如何用Python实现高效的双向哈希表?
    实现高效的双向哈希表双向哈希表允许键到值和值到键的查找。虽然 Python 的内置 dict 数据结构在键到值查找方面表现出色,但它并不能提供有效的值到键检索。实现双向哈希表的有效方法是利用类扩展了标准字典。此类名为 bidict,维护一个逆目录,该目录会根据对常规 dict 的任何修改自动更新。代...
    编程 发布于2024-11-17
  • PDOStatement::bindParam() 中的前导冒号真的是可选的吗?
    PDOStatement::bindParam() 中的前导冒号真的是可选的吗?
    PDOStatement::bindParam() 中参数名称的前导冒号是否真的可选?PDOStatement::bindParam() 允许您使用占位符(例如:name)在查询中指定命名参数。文档指出命名占位符的参数标识符应使用格式:name。然而,据观察,:name 和 name 似乎都可以使用...
    编程 发布于2024-11-17
  • 如何在 JavaScript 中实现稳定排序以在排序过程中保持元素顺序?
    如何在 JavaScript 中实现稳定排序以在排序过程中保持元素顺序?
    JavaScript中的稳定排序目标:基于键对对象数组进行高效排序,保持一致性和稳定性。算法推荐: 虽然存在许多排序算法,但为了满足您对稳定性的特定需求,请考虑实现非稳定排序算法,如 QuickSort 或 MergeSort。稳定排序技术:为了确保稳定性,请在排序比较函数中添加一个附加条件。具体来...
    编程 发布于2024-11-17
  • 掌握复合组件:构建灵活且可重用的 React 组件
    掌握复合组件:构建灵活且可重用的 React 组件
    介绍 React 世界中非常有用且全面的东西是它的设计模式,因为它们有助于保持代码的可扩展性并为我们创建的组件添加意义。 有多种模式,在本文中我们将讨论复合组件,这是一种高级模式,对于创建灵活的复合接口特别有用。 什么是复合组件? 复合组件是 React 中的一种高...
    编程 发布于2024-11-17
  • 如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    MySQL配置不正确:相对路径的问题在Django中运行python manage.py runserver时,可能会遇到以下错误:ImproperlyConfigured: Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-...
    编程 发布于2024-11-17
  • ## 双波形符运算符 (~~) 在 JavaScript 中有何作用?
    ## 双波形符运算符 (~~) 在 JavaScript 中有何作用?
    JavaScript 中的双波浪号运算符 (~~)在 JavaScript 中,~~ 运算符是一个类型强制运算符,它会删除 后面的所有内容数字的小数点。这与 ~ 运算符不同,~ 运算符是按位 NOT 运算符,可反转值的位。操作 运算符的工作原理是首先将其值转换为操作数为有符号 32 位整数。这意味着...
    编程 发布于2024-11-17
  • 如何在 Python 中执行模糊字符串比较?
    如何在 Python 中执行模糊字符串比较?
    Python 中的模糊字符串比较:有效模块在处理字符串中的潜在变化和错误时,需要进行模糊字符串比较。为这项任务找到合适的 Python 模块至关重要。这个问题寻求一个可以提供相似性百分比的模块,允许各种比较选项。 difflib: A Versatile Tool for Fuzzy Compari...
    编程 发布于2024-11-17
  • 如何在 PHP 中组合两个关联数组,同时保留唯一 ID 并处理重复名称?
    如何在 PHP 中组合两个关联数组,同时保留唯一 ID 并处理重复名称?
    在 PHP 中组合关联数组在 PHP 中,将两个关联数组组合成一个数组是一项常见任务。考虑以下请求:问题描述:提供的代码定义了两个关联数组,$array1和$array2。目标是创建一个新数组 $array3,它合并两个数组中的所有键值对。 此外,提供的数组具有唯一的 ID,而名称可能重合。要求是构...
    编程 发布于2024-11-17
  • 如何设置 Go 测试的工作目录?
    如何设置 Go 测试的工作目录?
    Go 测试中的工作目录在 Go 中,通常将配置文件放置在工作目录中并在代码中引用它们。但是,如果测试环境与生产环境不匹配,单元测试可能无法找到这些文件。要为 Go 测试指定工作目录,请探索以下解决方案:考虑使用运行时包中的 Caller 函数。调用者获取当前的测试源文件并返回其路径。该路径可用于设置...
    编程 发布于2024-11-17
  • 如何转义 PHP 正则表达式中的反斜杠?
    如何转义 PHP 正则表达式中的反斜杠?
    在 PHP 正则表达式中转义反斜杠要在 PHP 正则表达式模式中转义反斜杠,可以使用三个反斜杠 (\\ ) 或四个反斜杠 (\\\\)。虽然这两个选项都会产生成功的匹配,但它们的解释和用法存在细微差别。测试用例:考虑以下测试用例:// TEST 01: (3 backslashes) $patter...
    编程 发布于2024-11-17
  • 如何在 Python 中用逗号连接字符串:哪种方法最好?
    如何在 Python 中用逗号连接字符串:哪种方法最好?
    用逗号连接字符串:简洁的解决方案要连接列表中的字符串,在每对之间添加逗号,可以使用多种方法。一种流行的技术涉及将 ''.join() 函数与 lambda 函数 map() 结合使用。以下方法演示了此技术:result = ','.join(map(lambda x: x ','...
    编程 发布于2024-11-17
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    编程 发布于2024-11-17

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3