2016-02-13 30 views
-7

我的问题是:从int32到int64的转换是如何工作的?我对这样做的功能不感兴趣,我对感兴趣,他们是如何做到这一点的。比特级发生了什么?从int32到int64的转换如何工作

我特别感兴趣负int32(即-23)如何转换为int64。

+7

通过符号扩展。阅读整数表示(对于宽度类型的2的补码)。 – Olaf

+0

“通常的方式”,就是将签名的'short'或'char'扩展为更大类型的相同方式。没有太多办法可以这么做 - 我实际上只能想到一个@Olaf提到的方法。 – usr2564301

+0

@Jongware:不一定。基本类型不一定是2的补码。 – Olaf

回答

2

有关在符号扩展中会发生什么的答案取决于有符号整数的表示方式。有几种方法可以用来以二进制形式表示负数。最常见的变体是:

  1. 两个补码。迄今为止最常见的。
  2. 补码。我相信,有时用在DSP系统中。
  3. 符号和大小。
  4. 过量K.用于浮点指数。
  5. 基数-2。

这很有可能是另外几个变种,但是因为该列表中的第一个可能涵盖至少99%的计算机系统,这里的读者将会遇到,而其他四个将是绝大多数其余的系统(实际上,我只有在“现实生活”中遇到过量的K,其他人在我的计算机上工作30多年,仍然是理论上的)。后两种形式在C99标准中是不允许的,所以这是不可能的[但是并不绝对禁止为不符合目标系统的C编译器编写代码 - 你不能声称它支持完整的C99标准]

我现在将解释一个符号扩展如何在这些数字系统中的每一个中工作。我不打算解释每个系统在其他方面的工作原理,或者为什么选择某个特定的系统,他们在哪里使用,或者其他类似的东西。这可能属于“计算机体系结构书”。有关不同号码系统的更多详细信息,请参见Wikipidea here中的文章。

我将给出两个4位数字如何转换为它们各自的8位版本的示例 - 为了节省输入大量的1和0,原理是相同的,只是更多的数字。

两补:

采取31位(符号位),并将其复制到位32..63。大多数64位处理器都有特定的指令来执行此步骤,以便从32位到64位的转换是自动的。

值5是0101为四个比特数,复制位3 - > 00000101. -6在4位是1010,复制位3 - > 11111010.

一的补码:

与二进制补码相同 - 唯一真正的区别是有一个负64,由64个“1”组成。

值5是0101,为4位数字,将位3复制到位4..7-> 00000101。4位中的-6是1001,将位3复制到位4..7 - > 11111001。

成位63的扩展数字的其余符号和幅值

移动钻头31保持为零。

值5是0101作为一个四位数字,将位3复制到位7并替换为零 - > 00000101. - 4位中的-6是1110,将位3复制到位7,并替换为零 - > 10000110.

过量ķ

由于过量K是“偏置”表示,标志延伸装置正火,然后重新偏压具有较大恒定的数量。换句话说,减去2 并且加上2 [或“add 2 -2 ”]。

值5是1101为四张比特数,减去8,再加入128 - > 10000101. -6在4位是0010,减去8,再加入128 - > 01111010.

(这是经常在浮点数的指数中使用 - 我相信,再加上最高位的符号,可以将所有“常规”浮点数作为32位或64位整数进行比较,并仍然表现为预计 - 但不要在你的程序中使用它!)。

基地-2

这是一个非常奇怪的一个,作为值为-2 价值,其中,如果你按照上面的链接,你将看到的是不是在所有琐碎遵循。奇数位是负数,偶数位数是正数。然而,符号扩展是微不足道的 - 只需将零添加到相关级别,因为每一位都有符号或不是偶数或奇数。

值5是0101为四张比特数,用零填充扩展:00000101. -6在4位是1110,用零填补使00001110.

+0

请注意,此问题仍然标记为C/C++。你可能想提一提[ISO C99要求二进制补码,补码或符号/幅度](http://stackoverflow.com/questions/13652556/what-happens-when-i-assign-long-int-to- INT-在C#comment18743414_13652796)。根据该评论:[见第6.2.6.2节](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf)。无论如何,+ 1尤其适用于其他两种表示。 –

+0

[ARM加载/存储指令](http://www.peter-cockerell.net/aalp/html/ch-3.html)显然使用符号/幅度表示对位移进行编码,因为符号位仍然是符号当它是一个寄存器偏移而不是立即。 RE:将浮点数作为整数进行比较:是的,IEEE浮点数按正确的顺序排序为有符号整数。我不确定denormals,你是对的,这是有点脆弱。如果你没有获得大的加速并且可以确保它是安全的,那么不要依赖于IEEE FP表示。再加上它对于阅读你的程序的人来说很奇怪。 –

+0

将float位模式作为整数进行比较的更新:由于其有偏指数,IEEE浮点数正确比较为符号+量值整数。 [如果使用二进制补码硬件比较,除非两个浮点数都是负数,否则所有函数都可以使用:在这种情况下,顺序是颠倒的](https://en.wikipedia.org/wiki/IEEE_754-1985#Representation_of_numbers)。另外,+ NaN值比较> + Inf。 -NaNs在0和-Inf之间排序(或低于-Inf,从0开始最远,如果两个整数均为负数时颠倒顺序)。尽管如此,这种设计显然允许在int和FP cmp之间共享一些硬件。 –