【问题标题】:Understanding signed vs unsigned comparison [duplicate]了解有符号与无符号比较[重复]
【发布时间】:2014-08-27 02:31:47
【问题描述】:

谁能告诉我为什么 if 条件为假?

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    int a;
    unsigned int ua;

    a = -1;
    ua = a;

    cout << "ua: " << ua << endl;
    if (ua != -1)
        cout << "Is unsigned" << endl;
    else
        cout << "Is signed" << endl;

    return 0;
}

我的意思是,这里 ua == int_max_value,它不是 -1,但是当我运行它时,输出是

已签名

【问题讨论】:

  • -1 被转换为 unsigned int 以进行比较。
  • 如果-1转换为unsigned int,它怎么能持有-1?我的意思是,-1 已签名:S
  • -1 使用二进制补码算法进行转换,得到UINT_MAX。只是 C++ 有一种非常强烈的“倾向”,可以将所有内容都转换为无符号整数(发生这种情况的确切规则相当复杂;有关详细信息,请参阅 C++ 标准)。
  • @harryPoker:没有。但它再次为转换签名!

标签: c++ underflow


【解决方案1】:

!=== 在算术类型上执行所谓的通常的算术转换。与此处相关,给定一个unsigned X 类型的操作数和一个signed X 类型的操作数,其中Xintlonglong long 之一,通常的算术转换将带符号的操作数转换为比较之前的无符号类型。

因此,当您比较 uaunsigned int 类型)和 -1signed int 类型)时,-1 将转换为 unsigned int 类型(从概念上讲,通过添加 232 到它,假设是 32 位 int),结果比较等于 ua 的值。

【讨论】:

  • 太棒了!现在我的心可以安息了:)
【解决方案2】:

这是预期行为,!= 将对其操作数执行通常的算术转换(如果它们是算术类型)。这在草案 C++ 标准部分 5.10 平等运算符 中有所介绍:

如果两个操作数都是算术或枚举类型,通常 对两个操作数执行算术转换;每一个 如果指定的关系为真,则运算符应为真,并且 如果为假,则为假。

在这种情况下,这将导致整数提升,这将看到-1 转换为无符号整数。这在510 中有所介绍,最后说:

否则,如果无符号整数类型的操作数有秩 大于或等于另一个操作数的类型的等级, 带符号整数类型的操作数应转换为 无符号整数类型的操作数。

【讨论】:

  • 谢谢!现在我完全明白了:)
  • 请注意,引用的特定段落在 C++14 中发生了变化,但行为保持不变。相关论文是N3624
  • 另外,-1 到 unsigned 的转换不是整体提升。
  • @T.C. C ++ 14 是一个更简单的引用......在积分促销部分5 p 10Otherwise, the integral promotions (4.5) shall be performed on both operands
  • @ShafikYaghmour 如果您查看引用的部分,积分提升不适用于类型已经为 int 的操作数。转换为unsigned 发生在应用积分促销(如果有)之后。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-21
  • 2016-08-07
  • 1970-01-01
  • 2015-10-31
  • 2023-03-08
  • 1970-01-01
相关资源
最近更新 更多