为什么 golang 左移 64 位不会溢出?

2024-03-27

我正在看围棋之旅 https://tour.golang.org/basics/11我对 basic-types.go 示例中的某些内容感到困惑:

MaxInt uint64     = 1<<64 - 1

在无符号 64 位整数中向左移动 1 64 个位置是否不应该导致溢出(也称为移动一位超过 MSB)?

但是,编译器不会抱怨,直到该行更改为:

MaxInt uint64     = 1<<65 - 1

./basic-types.go:5: constant 36893488147419103231 overflows uint64

如果我编写一些代码来迭代不同长度的左移,包括像上面的示例中那样移动 65,导致编译器崩溃,我会看到两件事:

  1. 它的表现正如我所预期的那样1<<63将 1 放在 uint64 可能的 MSB 中

  2. 它不再溢出了(啊?!?!)

code:

package main

import "fmt"

func main() {
    for i := 60; i < 66; i++ {
        var j uint64 = 1 << uint64(i) - 1
        fmt.Printf("%2d | %64b | %#18x\n", i, j, j)

    }

output:

60 |     111111111111111111111111111111111111111111111111111111111111 |  0xfffffffffffffff
61 |    1111111111111111111111111111111111111111111111111111111111111 | 0x1fffffffffffffff
62 |   11111111111111111111111111111111111111111111111111111111111111 | 0x3fffffffffffffff
63 |  111111111111111111111111111111111111111111111111111111111111111 | 0x7fffffffffffffff
64 | 1111111111111111111111111111111111111111111111111111111111111111 | 0xffffffffffffffff
65 | 1111111111111111111111111111111111111111111111111111111111111111 | 0xffffffffffffffff

当你写的时候

1<<64

The 1上面不是一个int64。它是一个常量文字。从语言规范来看:

常量表达式总是被精确计算;中间值 并且常数本身可能需要很大的精度 大于该语言中任何预先声明的类型所支持的。

因此,常量文字是在编译时计算的,并且可能非常大,因为它不是语言实现的特定类型。

下面实际上会给出溢出错误:

var i int64
i = 1<<65 - 1

因为现在常量文字表达式的计算结果大于int64可以包含。

阅读更多相关内容here https://golang.org/ref/spec#Constant_expressions.

了解您的示例代码为何有效i = 65,参考以下Golang规范specs https://golang.org/ref/spec#Operators:

移位表达式中的右操作数必须是无符号整数 类型或者是可以转换为无符号的无类型常量 整数类型。如果非常量移位表达式的左操作数 是一个无类型常量,它首先被转换为它想要的类型 假设移位表达式是否被其左操作数替换 独自的.

上面的粗体部分涉及您的代码。考虑下面的代码:

a := 66
var j uint64 = 1<<uint64(a) - 1

在移位运算符中,右操作数是非常量表达式。所以整个移位操作就变成了非常量移位表达式。因此,如上所述,左操作数,1被转换为uint64.

现在,转变正在进行中uint64(1),可以使用<<去尽可能多的地方。您可以将其移至 64 位以上,并且实现将轻松允许它。但在这种情况下,保存着的内存uint64(1)上面将包含全零。

请注意,根据语言规范,此行为与溢出不同。同样,只要正确的运算符不是常量表达式,语言实现就允许尽可能多的移位。例如,这将起作用:

a := 6666
var j uint64 = 1<<uint64(a) - 1 // non-constant shift expression

这样想吧。早些时候,1没有打字。它具有任意精度(取决于实现)并且返回整个数字(所有位)。现在,既然它是一个uint64,仅考虑前 64 位。

这仍然会导致溢出,因为左操作数1是无类型的,可以包含大量位,返回的值对于uint64:

var j uint64 = 1<<uint64(66) - 1 // overflow. Note that uint64(64)
fmt.Println(j)                   // is typed, but it's still a constant
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 golang 左移 64 位不会溢出? 的相关文章

  • 对二进制数的字符串表示进行按位运算 python 2.7

    我想对二进制数的两个字符串表示执行按位或 但我不知道如何将字符串转换为原始二进制 a 010110 b 100000 a b 应该产生 110110 然后我想计算 on 位的数量 这应该返回 4 您可以使用内置的将字符串转换为二进制int
  • gcloud 部署应用程序找不到导入包 - golang

    我已经将应用程序的一个版本部署到 GAE 但现在部署新版本时遇到问题 当我尝试时gcloud app deploy version VERSION 我收到一堆错误 显示远程构建找不到我的导入包 Beginning deployment of
  • go:找到模块但不包含包

    我正在尝试安装 go 的网络包 但收到 不包含包错误 终端截图 我咨询过 go 模块 latest 已找到但不包含包 https stackoverflow com questions 62974985 go module latest f
  • NASM 轮班操作员

    您将如何在寄存器上进行 NASM 中的位移位 我读了手册 它似乎只提到了这些操作员 gt gt lt lt 当我尝试使用它们时 NASM 抱怨移位运算符处理标量值 您能解释什么是标量值并举例说明如何使用 gt gt and lt lt 另外
  • Go 中的切片分块

    我有一个切片 其中包含约 210 万条日志字符串 我想创建一个切片切片 其中字符串尽可能均匀分布 这是我到目前为止所拥有的 logs is a slice with 2 1 million strings in it var divided
  • golang从sdin扫描一行数字

    我正在尝试从标准输入读取输入 3 2 1
  • Google Cloud Kubernetes 上任务队列的替代方案

    我发现任务队列主要用于App Engine标准环境 我正在将现有服务从 App Engine 迁移到 Kubernetes 任务队列的一个好的替代方案是什么 推送队列是当前正在使用的队列 我在线阅读文档并浏览了此链接 何时使用 PubSub
  • Python 相当于 Bit Twiddling Hacks 中的 C 代码?

    我有一个位计数方法 我正在尝试尽可能快地实现 我想尝试下面的算法位摆弄黑客 http graphics stanford edu seander bithacks html CountBitsSetParallel 但我不知道 C 什么是
  • 在 Go 中生成随机、固定长度的字节数组

    我有一个字节数组 固定长度为4 token make byte 4 我需要将每个字节设置为随机字节 我怎样才能以最有效的方式做到这一点 这math rand就我而言 方法不提供随机字节函数 也许有一种内置的方法 或者我应该生成一个随机字符串
  • 从 []byte 到 char*

    我想包装一个 C 函数 它需要一个char 指向非空字节缓冲区 的第一个元素 我正在尝试使用 CGo 将其包装在 Go 函数中 以便我可以将其传递给 byte 但我不知道如何进行转换 C 函数签名的简化版本是 void foo char c
  • Go中如何自定义http.Client或http.Transport超时重试?

    我想实现一个自定义http Transport对于标准http Client 如果客户端超时 它将自动重试 附 由于某种原因 习俗http Transport is a 一定有 我已经查过了hashcorp go retryablehttp
  • 为什么奇数的切片容量与偶数的切片行为不同

    我注意到 当容量为奇数时 切片的容量会以不同的方式表现 更具体地说 当向切片添加元素时 切片的容量为doubled当原始容量为偶数时 但当原容量为奇数时 容量为增加一 然后加倍 例子 s make int 28 28 s append s
  • Go io.Pipe 的缓冲版本

    有缓冲版本吗io Pipe https golang org pkg io Pipe 在标准库或第三方库中 在我推出自己的库之前 上下文 我正在尝试使用这个解决方案 https stackoverflow com a 36229262 15
  • 是否可以获取有关 Golang 中调用者函数的信息?

    是否可以获取有关 Golang 中调用者函数的信息 例如 如果我有 func foo Do something func main foo 我怎样才能得到那个foo已被呼叫来自main 我可以用其他语言实现这一点 例如在 C 中我只需要使用
  • GAE Go — 如何对不存在的实体键使用 GetMulti?

    我发现自己需要做一个GetMulti使用键数组进行操作 其中某些实体存在 但有些实体不存在 我当前的代码 如下 返回错误 datastore no such entity err datastore GetMulti c keys info
  • GoQt 致命错误:QAbstractAnimation:没有这样的文件或目录

    我尝试编译 Qt 来开发桌面应用程序 我按照 Qt 网站上的官方 wiki 指南的说明进行操作 当我尝试go run示例文件夹中的示例 我收到错误 去运行 home pinkya rabbit workspace go1programs s
  • 将位图旋转 90 度

    我有一个1 个 64 位整数 我需要在 8 x 8 区域中旋转 90 度 最好使用直接位操作 我想不出任何方便的算法 例如 这个 0xD000000000000000 110100000000000000000000000000000000
  • mysql中的按位移位

    如何在 MySQL 中进行按位移位 有没有具体的指令或者操作符 如果不是 如何最佳地模拟它 看一下按位运算符MySQL first http dev mysql com doc refman 5 0 en bit functions htm
  • 如何在特定文件夹中运行 shell 命令

    我可以用这个out err exec Command git log Output 获取将在与可执行位置相同的路径中运行的命令的输出 如何指定要在哪个文件夹中运行命令 exec Command https golang org pkg os
  • 如何将UTC时间转换为unix时间戳

    我正在寻找将 UTC 时间字符串转换为 unix 时间戳的选项 我的字符串变量是02 28 2016 10 03 46 PM并且需要将其转换为 unix 时间戳 例如1456693426 知道该怎么做吗 首先 unix时间戳14566934

随机推荐

  • 将文本表转换为 pandas 数据框

    很多时候 当我尝试回答 Stackoverflow 上的问题时 问题包含一个表 我必须将其转换为 pandas 数据框才能进行处理 例如 在这个问题中 http stackoverflow com questions 43172116 pa
  • 使用验证器 jQuery 验证 Click 事件上的表单

    我正在使用 jQuery validate 来验证输入 我的代码 button click function form validate rules phone required true number true rangelength 7
  • 测试 Google Analytics iOS SDK

    有人找到了在 iOS 上测试 Google Analytics 的好方法吗 SDK 非常简单 但文档没有讨论如何测试或验证 该库在模拟器上或运行调试构建配置时的行为是否有所不同 我使用此委托方法设置了委托 GANTrackerDelegat
  • 紧凑框架中的网络浏览器

    我想用一个WebBrowser NET Compact Framework 3 5 项目中的组件 我面临着关于此的相互矛盾的信息 如果我只是尝试使用它 我会得到以下异常 System Threading ThreadStateExcepti
  • 椭圆弧箭头边缘d3力布局

    我正在使用强制布局来创建有向图 它渲染在画布上 我的示例位于http jsbin com vuyapibaqa 1 edit html 输出 http jsbin com vuyapibaqa 1 edit html output 现在我的
  • 无法在 DayNight 主题中动态切换模式

    我在我的应用程序中实现了 DayNight 主题 并添加了一个在白天和夜间模式之间切换的设置 但如果不重新启动 我无法在模式之间动态切换 如果我使用setDefaultNightMode 设置更改后 设置活动不会更改模式 但后台堆栈中的活动
  • VS Code 中的 SQL 调试

    我已经在 Windows 上安装了 VS code 工具并探索其功能 到目前为止 我想说它是一个很棒的工具 与传统的 SSMS 相比 它具有一些很酷的功能 我面临的困难是 在 VS Code 中使用 debug 当我单击调试时 它会在活动栏
  • C:执行 {...} while(0)? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么 C C 宏中有时会出现无意义的 do while 和 if else 语句 https stackoverflow com questions 154136 why are there som
  • 为什么 SQL Server 2008 Management Studio Intellisense 不工作?

    我正在疯狂地试图找出为什么智能感知根本无法工作 我使用的服务器是本地的 并且是 2008 年的 数据库设置为 2008 兼容性 智能感知在我能找到的每个菜单中都打开 但即使使用 CTRL J 也不会弹出任何成员列表 有没有人经历过类似的事情
  • Chrome Timeline 开发工具中的图像解码时间

    我正在构建一个视差滚动网站 不是我们所有人吗 除其他外 它会在用户滚动时显示图像 我通过将图像放在背景中并在顶部放置一个实心填充的 div 来完成 显示 然后 我根据滚动位置将该 div 从 100 高度设置为 0 高度 从而显示背景图像
  • 是否可以在 ng 服务之前和 Angular 7 中的实时重新加载/自动重新加载之前运行自定义脚本?

    在从 Angular cli 启动 ngserve 命令之前以及在 Angular 实时重新加载 自动重新加载之前 我必须运行自定义脚本吗 除了修改 package json 之外 是否可以使用 Angular 7 找你的package j
  • 如何为实际使用数据库上下文的 ASP.NET Core 控制器编写单元测试?

    关于如何编写良好的单元测试的信息似乎很少actualASP NET Core 控制器操作 关于如何使这项工作真正发挥作用有什么指导吗 我有一个系统 现在似乎运行得很好 所以我想我应该分享它 看看它是否能帮助其他人 有一个实体框架文档中非常有
  • Neo4j 3.0 中的存储过程

    我在 Windows 上使用 neo4j 3 0 并尝试使用存储过程新功能 我已经构建了 apoc jargithub 来源 https github com neo4j contrib neo4j apoc procedures 该 ja
  • R ggplot2:如何绘制具有纯色和透明笔触并根据颜色着色的geom_points?

    我想制作一个散点图 其中每个点都有一个球体 点及其球体都根据某些列值着色 一个显示我想要的最小示例 library ggplot2 library vcd only needed for example dataset ggplot Art
  • c、unix 中的睡眠函数

    我需要导入什么才能在unix中使用睡眠功能 我知道windows 是windows h 但是unix 呢 它应该位于 unistd h 中 请注意 这只能提供整数秒的精度 亚秒精度最便携的方法应该是 ab 使用 select
  • node.js:在全局范围内使用“this”令人困惑

    我最近一直在玩弄node js 并且遇到了关于使用的奇怪行为this在模块的全局范围内 this在全局范围内绑定到 module exports console log this exports gt true But this在方法范围内
  • 模块“QtQuick.Dialogs”版本 1.3 未安装

    我正在尝试在运行 1 2 版时没有任何问题的代码中导入 QtQuick Dialogs 1 3 版 但是在运行时我收到以下错误 模块 QtQuick Dialogs 版本 1 3 未安装 我正在使用默认的 Desktop Qt 5 9 2
  • 如何安全地读取 ASP.NET 中的流?

    byte bytes new byte uploader UploadedFiles 0 InputStream Length uploader UploadedFiles 0 InputStream Read bytes 0 bytes
  • Eclipse makefile 构建速度很慢...是什么原因?

    我们是 Eclipse 的狂热粉丝 这太棒了 但我们有大约 40 个 C 项目 并且还在不断增长 当所有项目都是最新的时 构建所有这些项目大约需要半分钟 总共 如果我只是创建一个对所有 40 个项目执行 make all 的 bash 脚本
  • 为什么 golang 左移 64 位不会溢出?

    我正在看围棋之旅 https tour golang org basics 11我对 basic types go 示例中的某些内容感到困惑 MaxInt uint64 1 lt lt 64 1 在无符号 64 位整数中向左移动 1 64