为什么无符号4不被认为大于签名-2?

时间:2017-11-17 13:22:33

标签: c unsigned signed comparison-operators

unsigned int x = 4;
int y = -2; 
int z = x > y; 

当实现此操作时,变量Z的值为0,但为什么它为0而不是1?。

3 个答案:

答案 0 :(得分:6)

信不信由你,如果C表达式是由两个参数构成的,一个是int类型而另一个是unsigned类型,那么int值是在进行比较之前,将提升为unsigned类型。

因此,在您的情况下,y会提升为unsigned类型。因为它是否定的,所以会通过添加UINT_MAX + 1进行转换,并且它将采用值UINT_MAX - 1

因此x > y将为0。

是的,这是很多错误的原因。即使是专业程序员也会不时地为此而堕落。有些编译器可以警告你:例如,使用gcc,如果使用-Wextra进行编译,则会收到警告。

答案 1 :(得分:2)

这是算术转换的结果。

在表达式x > y中,您有一个int操作数和一个unsigned int操作数。 y被提升为unsigned int,并通过将最多unsigned int值加一个值转换为y的值来转换价值。

C standard涵盖算术转换的第6.3.1.8节说明如下:

  

许多期望算术类操作数的运算符会导致   以类似的方式转换和生成结果类型。目的是为了   确定操作数和结果的通用实数类型。为了   指定的操作数,转换每个操作数,而不更改类型   域,对应的实际类型是普通实数的类型   类型。除非另有明确说明,否则常见的实际类型也是如此   结果的相应实际类型,其类型域为   操作数的类型域,如果它们是相同的,并且是复杂的   除此以外。这种模式称为通常的算术转换

     

...

     

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

所以现在y是一个非常大的值,与x进行比较,因为x小于此值,x > y的计算结果为false,值为0.

答案 2 :(得分:1)

它被称为整数提升。

signed int

在此示例中,比较(>)运算符unsigned inty进行操作。根据转换规则,-2将转换为unsigned int。由于-2无法表示为无符号整数值,因此-2 + UINT_MAX+1会转换为0

C11 6.3.1.3,第2段:

  

否则,如果新类型是无符号的,则转换为   重复加或减一个以上的最大值   可以用新类型表示,直到值在范围内   新类型。

因此,程序会打印UINT_MAX,因为4不小于int z = (int)x >y;

或者

如果要打印1,则执行显式类型的情况。像:

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "status", "sources" })
public class NewsSource {

    @JsonProperty("status")
    private String status;
    @JsonProperty("sources")
    private List<Source> sources = null;

    @JsonProperty("status")
    public String getStatus() {
        return status;
    }

    @JsonProperty("status")
    public void setStatus(String status) {
        this.status = status;
    }

    @JsonProperty("sources")
    public List<Source> getSources() {
        return sources;
    }

    @JsonProperty("sources")
    public void setSources(List<Source> sources) {
        this.sources = sources;
    }

}