Julia语言程序设计
上QQ阅读APP看书,第一时间看更新

3.1.3 有无符号转换

显而易见,位数相同的整型中,与有符号相比,无符号整型能够表达更大的正数。必要时,我们可以使用unsigned()函数将有符号数值转为无符号类型,例如:


julia> unsigned(20)                              # 20为Int64类型
0x0000000000000014

julia> typeof(ans)
UInt64                                   # 转为原值相同位数的有符号类型

julia> unsigned(Int16(20))
0x0014

julia> typeof(ans)
UInt16                                   # 转为原值相同位数的有符号类型

反之,可以使用signed()函数将无符号数值转为有符号类型,即:


julia> signed(UInt32(20))
20

julia> typeof(ans)
Int32                                                            # 转为原值相同位数的有符号类型

julia> signed(0x14)
20

julia> typeof(ans) 
Int8                                                        # 转为原值相同位数的有符号类型

可以看出,上述的unsigned signed()函数在转换时会将原值变成位数相同的无符号或有符号类型。但需要注意的是,在这种转换中,前者则会忽略负值的检查;而后者会忽略表达范围越界(Overflow,溢出)的情况。例如:


julia> a1 = Int8(-20)               # a1为8比特的整型,负数
-20

julia> a2 = unsigned(a1)                # a2为将负数的a1转为无符号整型
0xec

julia> Int64(a2)                              # a2的实际值变成了236
236

julia> bitstring(a1)
"11101100"

julia> bitstring(a2)
"11101100"

其中的a2在将a1转换为无符号后,值发生了变化,不再是-20而是236。两者在存储结构中,位序列上仍是一致的,但类型已经不再相同,一个是负数,而另一个变成了正数。不过,再次对a2进行转换时,仍可以获得其原始的负值,即:


julia> signed(a2)
-20

julia> typeof(ans)
Int8

再例如:


julia> b1 = typemax(UInt8)
0xff

julia> signed(b1)
-1                                                        # 转换后溢出,导致结果并非是2^32-1,而变成了-1

julia> typeof(ans)
Int8

该例中尝试将UInt8的最大值转为有符号类型,但显然相同位数的有符号型Int8无法表达这个值,出现了溢出现象,变成了-1值。

提示 为了明白其中的原委,读者需要回顾关于计算机表达正负数的方法,这里不赘述。需要注意的是,这个过程signed()函数并不会上报异常,所以在实践中需要多多留意。

在整数表达方面,Julia提供了各种整型的表达方式,在开发中可以根据系统特点、业务需求及内存条件,选择恰当的类型,以在性能与功能方面达到最优的效果。