Julia 位运算符

Julia 位运算符,无论怎样的数值类型,在计算机中都是连续的二进制串。任何的运算实质都是在改变或转移这些二进制串。对数值进行位运算,包括与(And)、或(Or)、非(取反,Not)、异或(Xor)、左移及右移等时,实际是对数据的内存结构进行直接的操作。在一些情况下,直接控制这些二进制串,可以在节约计算资源或提升关键代码性能等方面带来好处。这样的操作常见于通信中的传输协议、编解码或密码学等领域。

需要说明的是,Julia中提供的位运算符仅适用于整型,不能是其他类型,包括浮点型有理数型等。下表给出了Julia位运算符的示例用法及简单的说明。
Julia 位运算符

其中除了取反是一元的,其他都是二元运算符

与或非运算

我们以实例首先了解取反操作,例如:
Julia 位运算符

变量m的内容是一个值为50的有符号整数。经过取反后,其内存中的每一个二进制位均被反转,甚至包括符号位。所以取反的结果是数值50变成了-50这个负值。

再看一个无符号数值的例子:
Julia 位运算符

其中值为3的8位无符号整型m的各二进制位同样被逐位反转。因为是无符号的,所以不存在正负值变换的说法,但我们可以通过将其转换到Int64类型看一下值的变化:

julia> Int64(m)
3

julia> Int64(n)
252

对于与、或及异或运算,在符号变化方面有些不同,例如:

julia> m = Int8(10);
julia> n = Int8(-7);

julia> bitstring(m)                 # m的二进制结构
"00001010"

julia> bitstring(n)                 # n的二进制结构
"11111001"

julia> p = m & n                    # 与操作
8

julia> q = m | n                    # 或操作
-5

julia> r = m ˇ n                    # 异或操作
-13

julia> bitstring(p)                 # 与结果的二进制结构
"00001000"

julia> bitstring(q)                 # 或结果的二进制结构
"11111011"

julia> bitstring(r)                 # 异或结果的二进制结构
"11110011"

这三个运算同样会涉及符号位,但结果的符号是可以根据运算的特点进行推断的。例如,正数与负数做与运算时,结果肯定是正数(因为符号位必然是0);而做或运算时,则会得到负数,因为符号位必然是1。

移位运算

同样,左移运算也会涉及符号位,例如:

julia> bitstring(m)
"00001010"

julia> bitstring(m << 1)           # 左移1位
"00010100"

julia> bitstring(m << 2)           # 左移2位
"00101000"

julia> bitstring(m << 3)           # 左移3位
"01010000"

julia> m << 3                        # 左移3位后的取值
80
julia> bitstring(m << 4)           # 左移4位
"10100000"

julia> m << 4                        # 左移4位后的取值
-96

随着值为10的m变量的二进制位不断左移,值会越来越大,但当移动了4个位置后,符号位由0变成了1, m的值也变成了负数。

但右移运算中,Julia区分了是否考虑符号位的情况,分为算术右移及逻辑右移。在算术右移后,数值的正负是不变的,例如:
Julia 位运算符

变量n是负数,符号位是1,算术右移1位后,右侧的二进制位消失,但因为考虑了符号位,所以左侧在补充二进制位时,补上的并不是0而是1,从而保持了符号的表达。

继续对n进行算术右移,会发现:

julia> bitstring(n)                 # n的二进制结构
"11111001"

julia> bitstring(n >> 1)           # 算术右移1位
"11111100"

julia> bitstring(n >> 2)           # 算术右移2位
"11111110"

julia> bitstring(n >> 3)           # 算术右移3位
"11111111"

julia> bitstring(n >> 4)           # 算术右移4位
"11111111"

julia> n >> 4                      # 算术右移4位后的取值
-1

当移动了一定的数位后,二进制串中不再有0,结果的值便保持了-1,再算术右移任意的位数,该值都不再变化。

而对于正数来说,不断右移的结果为:

julia> m
10

julia> bitstring(m)                 # m的二进制结构
"00001010"

julia> bitstring(m >> 1)           # 算术右移1位
"00000101"

julia> bitstring(m >> 2)           # 算术右移2位
"00000010"

julia> bitstring(m >> 3)           # 算术右移3位
"00000001"

julia> bitstring(m >> 4)           # 算术右移4位
"00000000"

julia> bitstring(m >> 5)           # 算术右移5位
"00000000"

julia> m >> 5                        # 算术右移5位后的取值
0

右移了一定位数后,结果值保持为0值,而且不再变化。

正数的这种情况在逻辑右移中也是一样的,例如:

julia> bitstring(m >>> 1)          # 逻辑右移1位
"00000101"

julia> bitstring(m >>> 2)          # 逻辑右移2位
"00000010"

julia> bitstring(m >>> 3)          # 逻辑右移3位
"00000001"

julia> bitstring(m >>> 4)          # 逻辑右移4位
"00000000"

julia> bitstring(m >>> 5)          # 逻辑右移5位
"00000000"

对负数来说,逻辑右移的效果类似,但是有所不同,例如:

julia> n
-7

julia> bitstring(n)
"11111001"

julia> p = n >>> 1                  # 逻辑右移1位
124

julia> bitstring(p)
"01111100"

对于值为-7的n而言,仅移动了一位,结果的值便变成了124这个正数。

一般而言,任何负数只要经过一次逻辑右移便会变成正数,这是因为计算机表达正数的符号位是左侧的0,而一旦逻辑右移,1便会被0补上。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!