UInt128与它所包含的2个UInt64有什么关系?

Zac*_*iro -1 long-integer swift

如果我有以下结构:

public struct UInt128 {
    internal var value: (upperBits: UInt64, lowerBits: UInt64)
}
Run Code Online (Sandbox Code Playgroud)

想象一个初始化程序,它创建一个适合的随机数,UInt128并且该数字足够大,使得它超过其中一个的值.UInt64

高位和低位总和UInt128是以另一种方式管理的内存或内存的总和吗?

为了处理小数,如果每个的容量UInt64为20,如果该值为UInt12824,则高位值是20,低位值是4吗?

vac*_*ama 5

想象一下,要求您创建一个struct代表4位数字的数字,但您只能存储2位数字.所以,你有一个upperHalf代表前两个数字,一个lowerHalf代表后两个数字.

let upperHalf = 12
let lowerHalf = 34
Run Code Online (Sandbox Code Playgroud)

现在,您希望将它们组合在一起以生成完整的4位数字1234.

你是怎样做的?你加了吗?

12 + 34 = 46
Run Code Online (Sandbox Code Playgroud)

不,因为12不仅仅代表12.真的1200.

1200 + 34 = 1234
Run Code Online (Sandbox Code Playgroud)

因此,为了把它们结合在一起,你乘以upperHalf通过100使空间的低位,然后添加lowerHalf.

let upperHalf = 12
let lowerHalf = 34
let value = upperHalf * 100 + lowerHalf
print(value)  // 1234
Run Code Online (Sandbox Code Playgroud)

那么,是什么100?它表示将基数为10的数字左移2个位置.对于每个班次,您乘以10.所以2转变是10 * 10100.

现在,您将获得使用两个UInt8数字来表示数字的任务UInt16.

let upperBits = 2
let lowerBits = 1
Run Code Online (Sandbox Code Playgroud)

现在,您想要将它们组合起来以产生UInt16价值.与前一种情况一样,您不能只添加它们.你需要将地方upperBits向左移动,8以便腾出空间lowerBits.但是现在你正在使用二进制(基数为2),所以每次转换都是通过乘以来完成的2.

所以结合upperBitslowerBits两个UInt8值变得

let value = (upperBits * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2) + lowerBits
Run Code Online (Sandbox Code Playgroud)

这与:

let value = (upperBits * 256) + lowerBits
Run Code Online (Sandbox Code Playgroud)

也可以写成:

let value = (upperBits << 8) + lowerBits
Run Code Online (Sandbox Code Playgroud)

<< 8意味着将位移位8时间.

所以,如果upperBits2lowerBits1

let value = (2 * 256) + 1  // value = 513
Run Code Online (Sandbox Code Playgroud)

将这个类比扩展为使用两个UInt64数字来表示a UInt128,你需要upperBits在添加之前将64个位置向左移动lowerBits.每一次转变是一样的相乘2,所以你必须乘以upperBits通过2 ^ 64(或18446744073709551616)加入之前,以腾出空间lowerBits:

概念:

let value: UInt128 = (upperBits << 64) + lowerBits 
Run Code Online (Sandbox Code Playgroud)

这与以下相同:

let value: UInt128 = (upperBits * 18446744073709551616) + lowerBits
Run Code Online (Sandbox Code Playgroud)