Go 移位运算是一个效率很高的计算方式,根据场景进行使用,有时可以达到“出奇制胜”的效果。
创新互联公司专注为客户提供全方位的互联网综合服务,包含不限于成都网站设计、网站建设、外贸网站建设、化隆网络推广、微信平台小程序开发、化隆网络营销、化隆企业策划、化隆品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联公司为所有大学生创业者提供化隆建站搭建服务,24小时服务热线:18982081108,官方网址:www.cdcxhl.com
在 《Go 程序设计语言》里是这样描述移位运算的:“左移以 0 填补右边空位,无符号整数右移同样以 0 填补左边空位,但有符号数的右移操作是按符号位的值填补空位。因此,请注意,如果将整数以位模式处理,须使用无符号整型”。
这里的意思很明确,如果不是无符号数,最好不要用移位运算,那么,到底是为什么呢?“有符号数的右移操作是按符号位的值填补空位”又是什么意思呢?
首先,我们看左移:
完全符合预期,接着我们看右移:
纳尼?发生了什么?这里,其实发生了如下过程:
那么,11111101 又是怎样得到 -3 值的,很简单,保留符号位,再次取 补码 就可以了,最后得到 1000011。
想要知道取反计算过程,首先搞懂 “原码“,“反码”,“补码”,“取反”。
0变1,1变0
原码是计算机机器数中最简单的一种形式,数值位就是真值的绝对值。原码表示法在最高位为符号:正数该位为0,负数该位为1,原码又称带符号的绝对值。看整数9及-9的原码如下:
9的原码:0000 1001
-9的原码: 1000 1001
重点:对于源码,绝对值相等的正数和负数只有符号位不同。
反码通常是用来由原码求补码或者由补码求原码的过渡码。正数的反码就是其原码,负数的反码就是将原码除符号位以外每位取反(0变1,1变0)。例如:
9的反码:0000 1001
-9的反码:1111 0110
在计算机系统中,数值一律用补码来表示和存储。正数的原码就是其补码。负数的补码是其反码+1.例如:
9的补码:0000 1001
-9的补码:1111 0111
正整数的原码、反码、补码都是一样的。负数的反码是除符号位其他每一位取反,负数的补码是其反码+1
首先明确一个概念,由于在计算机中二进制都是以其补码形式存放在内存中的。所以要知道 ^9 就是对 9 的补码取反,也就是说无论是整数还是负数对其取反都是对其补码取反。
正数9:
原码为: 0000 1001
反码为: 0000 1001
补码为: 0000 1001
1. 取反结果=负数补码 :0000 1001 --- (取反) 1111 0110
注:由于 ^ 位取反操作符,对于符号位也会取反 所以这里得到一个负数的补码,想要计算其真实的值。还需要将其转换成原码。
2. 得反码:1111 0110 - 1 = 1111 0101
补码 = 反码 + 1 (反推) 反码 = 补码 - 1
3. 得原码 1111 0101 -- 1111 1010 = -10
原码 = 反码取反
负数-9:
原码为: 1111 1001
反码为: 1111 0110
补码为: 1111 0111
1. 取反结果=正数补码 1111 0111 ---- 0000 1000
2. 正数原码 = 反码 = 补码 = 0000 1000 = 8
很多语言都是采用 ~ 作为按位取反运算符,Go 里面采用的是 ^ 。
如果作为二元运算符,^ 表示按位异或,即:对应位相同为 0,相异为 1。
操作符 ^,按位置零,例如:z = x ^ y,表示如果 y 中的 bit 位为 1,则 z 对应 bit 位为 0,否则 z 对应 bit 位等于 x 中相应的 bit 位的值。
对于有符号的整数来说,是按照补码进行取反操作的(快速计算方法:对数 a 取反,结果为 -(a+1) ),对于无符号整数来说就是按位取反
计算过程
以3为例 3在内存中补码为 0*** 0011
取反 1*** 1100
-1操作 1*** 1011
除符号位取反 1*** 0100 结果为-4
-------------------------------------------
以9为例 9在内存中补码为 0*** 1001
取反 1*** 0110
-1操作 1*** 0101
除符号位取反 1*** 1010 结果为-10
-------------------------------------------
以-5为例 -5在内存中为的补码为 1*** 1011
为什么呢
-5源码 1*** 0101
除符号取反 1*** 1010
+1操作 1*** 1011
-------------------------------------------
那么-5取反怎么算
补码 1***1011取反为 0***0100
因为符号位为0,所以是正数了,正数的补码反码源码都是一个,所以是4
===================================
再看-1
-1源码 1*** 0001
除符号取反 1*** 1110
+1操作 1*** 1111
补码 1*** 1111 取反为 0*** 0000
因为符号位为0,所以是正数了,正数的补码反码源码都是一个,所以是0
go语言取反输出的例子看这里
Go语言(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言。Go 语言语法与 C 相近,但功能上有:内存安全,GC(垃圾回收),结构形态及 CSP-style 并发计算。 扩展资料
Go语言主要用作服务器端开发,其定位是用来开发“大型软件”的,适合于很多程序员一起开发大型软件,并且开发周期长,支持云计算的网络服务。Go语言能够让程序员快速开发,并且在软件不断的'增长过程中,它能让程序员更容易地进行维护和修改。它融合了传统编译型语言的高效性和脚本语言的易用性和富于表达性。
Go语言作为服务器编程语言,很适合处理日志、数据打包、虚拟机处理、文件系统、分布式系统、数据库代理等;网络编程方面,Go语言广泛应用于Web应用、API应用、下载应用等;除此之外,Go语言还可用于内存数据库和云平台领域,目前国外很多云平台都是采用Go开发。
之前是写java的,没有无符号有符号之分,最近刷题碰到了位运算的题,就想把这个搞清楚一点。
另外常用的int类型是有符号数,位长取决于你的电脑的位长,电脑是64位的int就是64位的。
左移
右移
首先无符号数没啥好说的,不管左移还是右移都是补0
有符号数,以int为例(64位)
老样子,机器内存的是补码
以7fffffffffffffffff为例
从前三个输出看,没有办法直接给int赋最大值(16进制),全f的话会报错,也就是不能直接赋值符号位,
但是第四个输出来看,这里的运算是逻辑位移,输出-2(ffffffffffffffe,找了半天也没找到怎样输出正儿八经的16进制数),也就是位移包括符号位.
之后再右移多少位都是-1(ffffff...f),就是补码位移规则
综上:
。。。。好乱
golang原生数据类型:按长度:int8(-128-127)、int16、int32、int64。
布尔型:布尔型的值只可以是常量true或者false。一个简单的例子:varbbool=true。
数字类型:整型int和浮点型float32、float64,Go语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码。
字符串类型:字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本。
派生类型:包括:(a)指针类型(Pointer)(b)数组类型?结构化类型(struct)(d)Channel类型(e)函数类型(f)切片类型(g)接口类型(interface)(h)Map类型。