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