【问题标题】:how integer is promoted to unsigned integer整数如何提升为无符号整数
【发布时间】:2018-06-14 17:06:01
【问题描述】:
#include<stdio.h>
void main()
  {    
    int a = -1;
    unsigned int b =15;
      if(b==a)
           printf ("b is equal to a"); 
  }

输出为空。负整数存储为相同正数的 2 的补码。当将整数与 unsigned int 进行比较时,通过将 2 的补码视为 unsigned int(此处为 15)将整数提升为 unsigned int,但即使 2 的补码为 -1,但输出为空是 15

【问题讨论】:

  • 即使 -1 的 2 的补码是 15 ? 不,你错了。再检查一次。
  • 幸运的是 int 可以存储超过 4 位
  • 输出为空,表示b不等于a。这是意料之中的,因为将-1 转换为unsigned int 会得到UINT_MAX,这绝对不是15。
  • -1 的 2 的补码只有在使用不符合标准的 4 位整数时才为 15。无论如何,2 的补码适用于 signed 值。

标签: c int unsigned-integer integer-promotion


【解决方案1】:

变量ab

int a = -1; /* its a sign ed int, it takes 4 bytes */
unsigned int b =15;/* its a unsigned int */

它看起来像下面

a = -1 => 1111 1111 | 1111 1111 | 1111 1111 | 1111 1111   

b = 15 => 0000 0000 | 0000 0000 | 0000 0000 | 0000 1111
          MSB                                         LSB

现在当你比较 ab

if(b==a) {
    /* some code */
}

在这里,您正在对两种不同类型的== 进行比较(a 属于signed 类型,b 属于unsigned 类型)。因此隐式编译器会将sign int 转换/提升为unsigned int,然后它将执行比较==。有关算术对话规则,请参阅此http://port70.net/~nsz/c/c11/n1570.html#6.3.1.8

现在 unsigned 相当于 a-1 是什么?全部为one's 4 个字节,即4294967295。所以现在看起来像

if(15==4294967295) { /*its false */
        /* some code */
}

由于if 条件为假,您的代码不会打印任何内容。

【讨论】:

  • int 只保证至少是两个字节,并且一个字节中的位数可能不是 8。我想还值得注意的是,负数不保证是以二进制补码形式(尽管我无法命名不使用该形式的架构)
  • int a = -1; 这里 a 是默认的 sign int & 它在 32 位系统上占用 4 byte
  • 对,但重要的是要知道这不是通用的。 int 在所有系统上都不是 32 位。该问题未指定平台,因此在做出此类假设时指定答案是最安全的,这样答案对于所有平台都不正确。跳过一些只有最奇特的系统才使用的假设(例如非 8 位字节和非二进制补码负数)可能是合理的,但我们周围有一些平台不是 32 位的。 OP 已经犯了一个错误,即期望 4 位数字的二进制补码可以普遍适用。
【解决方案2】:

如果将变量 b 更改为

unsigned int b = 4294967295;

(这确实假设 int 被存储为 32 位)

打印语句将运行。看,https://stackoverflow.com/a/2084968/7529976

【讨论】:

  • 你可以改用unsigned int b = UINT_MAX + 1 - 1;
猜你喜欢
  • 2022-01-20
  • 2017-07-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-04
  • 1970-01-01
  • 2017-07-21
  • 1970-01-01
相关资源
最近更新 更多