user-0 提问: 关于有符号long long型数据的标志位问题。

回复:
user: user-0
content: 引用 14 楼 zhao4zhong1 的回复:[quote=引用 13 楼 yuyouyang 的回复:] 恩，我还是自己开调试看看比较好。居然忘了这个，就知道自己在这里猜想了。 理解和讨论之前请先观察或学会观察。[/quote] 恩，谢谢指导！

user: user-1
content: 引用 13 楼 yuyouyang 的回复:恩，我还是自己开调试看看比较好。居然忘了这个，就知道自己在这里猜想了。 理解和讨论之前请先观察或学会观察。

user: user-0
content: 恩，我还是自己开调试看看比较好。居然忘了这个，就知道自己在这里猜想了。

user: user-2
content: 引用 7 楼 dbzhang800 的回复:对，主要是他没意识到 int 到 long long 的这个提升。  不过网友经常疑惑的类似的问题，是在 char 到 int 的提升中。char vs unsigned char int 到long long是转换，不是提升。

user: user-1
content: 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  常量也有类型： C++ Integer Constants Integer constants are constant data elements that have no fractional parts or exponents. They always begin with a digit. You can specify integer constants in decimal, octal, or hexadecimal form. They can specify signed or unsigned types and long or short types.  Syntax  integer-constant :  decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt 'c-char-sequence'  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffixopt long-suffix unsigned-suffixopt  unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  To specify integer constants using octal or hexadecimal notation, use a prefix that denotes the base. To specify an integer constant of a given integral type, use a suffix that denotes the type.  To specify a decimal constant, begin the specification with a nonzero digit. For example:  int i = 157;   // Decimal constant int j = 0198;  // Not a decimal number; erroneous octal constant int k = 0365;  // Leading zero specifies octal constant, not decimal  To specify an octal constant, begin the specification with 0, followed by a sequence of digits in the range 0 through 7. The digits 8 and 9 are errors in specifying an octal constant. For example:  int i = 0377;   // Octal constant int j = 0397;   // Error: 9 is not an octal digit  To specify a hexadecimal constant, begin the specification with 0x or 0X (the case of the “x” does not matter), followed by a sequence of digits in the range 0 through 9 and a (or A) through f (or F). Hexadecimal digits a (or A) through f (or F) represent values in the range 10 through 15. For example:  int i = 0x3fff;   // Hexadecimal constant int j = 0X3FFF;   // Equal to i  To specify an unsigned type, use either the u or U suffix. To specify a long type, use either the l or L suffix. For example:  unsigned uVal = 328u;             // Unsigned value long lVal = 0x7FFFFFL;            // Long value specified                                    //  as hex constant unsigned long ulVal = 0776745ul;  // Unsigned long value

user: user-3
content: 引用 9 楼 yuyouyang 的回复:[quote=引用 6 楼 turingo 的回复:] 我的理解是，类型从32位提升到64位的时候，高32位是按照符号位来扩展的。 也就是说most虽然声明的是long long 64位，但是两个32位还是区别来对待的，有一个从低32位到高32位提升的过程是吗？[/quote] 不是。看#4

user: user-0
content: 引用 6 楼 turingo 的回复:我的理解是，类型从32位提升到64位的时候，高32位是按照符号位来扩展的。 也就是说most虽然声明的是long long 64位，但是两个32位还是区别来对待的，有一个从低32位到高32位提升的过程是吗？

user: user-3
content: 对，主要是他没意识到 int 到 long long 的这个提升。  不过网友经常疑惑的类似的问题，是在 char 到 int 的提升中。char vs unsigned char

user: user-0
content: 引用 3 楼 mujiok2003 的回复:特别的：当移位到低32位的最高位时： most:  2147483648 most:  80000000 那如何解释0x8fffffff取反之后却为正数的结果？ 你要知道，你的most是64位， 当most=0x 80000000是， 高32位全是0，当然是正数。 你看到的内存就是原码， 而不是补码。 恩，这个我同意。但是这个只是移位的输出，并没有解释我取反的那个结果。 ~0x8fffffff之后  %llx输出的为什么只有低32位的70000000，而不是ffffffff70000000,高32位不取反吗？

user: user-4
content: 我的理解是，类型从32位提升到64位的时候，高32位是按照符号位来扩展的。  引用 2 楼 yuyouyang 的回复:[quote=引用 1 楼 turingo 的回复:] 楼主想复杂了，其实就是取反而已： 1、~0x7f的话，最高位为1，所以会被理解为负数，到底是负多少，才由补码规则来确定； 2、~0x8f的话，最高位为0，所以会被理解为正数，到底是正多少，才由补码规则来确定。  你说的最高位是低32位的最高位  而不是64位的最高位。 请问long long型数据的符号位是在哪里？它是64位的。[/quote]

user: user-3
content: 打错字了： 其实他的问题就是

user: user-3
content: 其他它的问题就是  int a1 = -1; int a2 = 1;  long long a3 = a1; long long a4 = a2;  然后问，为什么a3 为负值，而 a4 为正值。和int的最高位(即符号位)有没有关系。

user: user-2
content: 特别的：当移位到低32位的最高位时： most:  2147483648 most:  80000000 那如何解释0x8fffffff取反之后却为正数的结果？ 你要知道，你的most是64位， 当most=0x 80000000是， 高32位全是0，当然是正数。 你看到的内存就是原码， 而不是补码。

user: user-0
content: 引用 1 楼 turingo 的回复:楼主想复杂了，其实就是取反而已： 1、~0x7f的话，最高位为1，所以会被理解为负数，到底是负多少，才由补码规则来确定； 2、~0x8f的话，最高位为0，所以会被理解为正数，到底是正多少，才由补码规则来确定。  你说的最高位是低32位的最高位  而不是64位的最高位。 请问long long型数据的符号位是在哪里？它是64位的。

user: user-4
content: 楼主想复杂了，其实就是取反而已： 1、~0x7f的话，最高位为1，所以会被理解为负数，到底是负多少，才由补码规则来确定； 2、~0x8f的话，最高位为0，所以会被理解为正数，到底是正多少，才由补码规则来确定。  引用 楼主 yuyouyang 的回复:今天在做一道题结果遇到了一点问题。 首先定义：long long most；这里将most定义为long long型的数据，占64位，8字节。 先给most 赋值： most = ~0x7fffffff。 0x7fffffff 为 0….0（高32位省略，下同） 0111 1111 1111 1111 1111 1111 1111 1111 取反得:       1….1 1000 0000 0000 0000 0000 0000 0000 0000 由于计算机存储的是补码，所以most的实际值为： 最高位符号位不变 其他位取反： 	    10..0 0111 1111 1111 1111 1111 1111 1111 1111 再+1：               10..0 1000 0000 0000 0000 0000 0000 0000 0000 	printf("most:  %lld\n",most); 	printf("most:  %llx\n",most); 得到的结果是: most:  -2147483648; 因为64位最高位的符号位为1，所以是负数。 most:  ffffffff80000000 这里显示的是取反之后的直接结果。  再给most赋值 most = ~0x8fffffff 0x8fffffff 为 0...0 1000 1111 1111 1111 1111 1111 1111 1111 取反得：     1...1 0111 0000 0000 0000 0000 0000 0000 0000 同样 计算机存储的是补码，所以理论上most的实际值应该是： 最高位符号位不变 其他位取反：                 10..0 1000 1111 1111 1111 1111 1111 1111 1111 再+1：                 10..0 1001 0000 0000 0000 0000 0000 0000 0000 理论上讲，64位的最高位符号位还是1，所以应该是负数。 	printf("most:  %lld\n",most); 	printf("most:  %llx\n",most); 但是输出的结果却是： most：  1879048192  为正数 most:   70000000  %llx也只输出了低32位。 结果却是正数。 这里 0x7fffffff和0x8fffffff的区别在于 低32位的最高位分别为0和1，是否低32位的最高位在某些时候也会作为标志位？ 所以我有点迷惑，这里的标志位究竟在哪里？ 为了探寻这个问题，我将most一个一个移位，并输出 	most=1; 	for(i=1;i<64;i++) 	{ 	    most=most<<1; 	    printf("most:  %lld\n",most); 	    printf("most:  %llx\n",most); 	} 得到的结果是只有最后一个输出才是负数，也即只有64位的最高位被置1的时候才标志着负数。 特别的：当移位到低32位的最高位时： most:  2147483648 most:  80000000 那如何解释0x8fffffff取反之后却为正数的结果？ 如有正解，不胜感激！ 谢谢！

user: user-4
content: 是的，从int到long long的提升。  引用 9 楼 yuyouyang 的回复:[quote=引用 6 楼 turingo 的回复:] 我的理解是，类型从32位提升到64位的时候，高32位是按照符号位来扩展的。 也就是说most虽然声明的是long long 64位，但是两个32位还是区别来对待的，有一个从低32位到高32位提升的过程是吗？[/quote]