• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Explr
V2EX  ›  程序员

最近又看 CSAPP,请教无符号数比较问题

  •  
  •   Explr · Feb 20, 2022 · 3214 views
    This topic created in 1584 days ago, the information mentioned may be changed or developed.

    如下 C 代码:

    unsigned int ui = 5;
    unsigned short us = 5;
    int i = -100;
    short s = -100;
    printf("%d\n", ui < s);
    printf("%d\n", ui < i);
    printf("%d\n", us < s);
    printf("%d\n", us < i);
    

    终端输出是:

    1
    1
    0
    0
    

    如果前两个 1 是因为 s 和 i 被解释成无符号数与 ui 比较,那为什么后两个又是 0 了……

    8 replies    2022-02-20 20:56:33 +08:00
    EggtartZ
        1
    EggtartZ  
       Feb 20, 2022
    应该是 unsigned short 和 short 比较前会先被提升到 int(unsigned int)类型吧。
    mons
        2
    mons  
       Feb 20, 2022   ❤️ 1
    > The integer promotions
    > Whenever a small integer type is used in an expression, it is implicitly converted to int which is always signed. This is known as the integer promotions or the integer promotion rule.
    > Formally, the rule says (C11 6.3.1.1):
    >> If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.
    > This means that all small integer types, no matter signedness, get implicitly converted to (signed) int when used in most expressions.

    From https://stackoverflow.com/a/46073296
    iBugOne
        3
    iBugOne  
       Feb 20, 2022 via Android   ❤️ 3
    前两个比较,因为左边有 unsigned int ,所以右边数的被转换到了 unsigned int ;后两个比较,因为所有的数都在 int (signed int) 范围内,因此两边的数都升级到了 int / signed int 。
    mascteen
        4
    mascteen  
       Feb 20, 2022 via Android
    implicit number conversion.
    LotusChuan
        5
    LotusChuan  
       Feb 20, 2022 via iPhone
    你可以反汇编一下看看怎么比较的,csapp 的 lab 有反汇编的课程要求。
    DeWjjj
        6
    DeWjjj  
    PRO
       Feb 20, 2022
    首先一个原则 short i = int i ,这俩玩意在系统中定位一致。无论你用 int 还是 short 在 windows 初始化数不极端时候是一样的。
    第二,有符号跟无符号比较,有符号根据开头数字 1 为负 0 为正。所以-100 开头是 1 ,根据补码规则开头为 1 无脑填充 1 。此时-100 是一个较大正数。
    第三,us 是一个 short 无符号,他会向 int 先行转换,五的开头是 0 显示全部补成 0 了。然后再比较 5 自然比-100 大。
    这里涉及到的是补号原则,也就是转换。
    Explr
        7
    Explr  
    OP
       Feb 20, 2022
    @LotusChuan 是这个样子的,后面就有个 BombLab ,我还没看到那里。emm...不过我还真没想到这个思路。
    LotusChuan
        8
    LotusChuan  
       Feb 20, 2022
    @Explr
    BombLab 和 AttackLab 都是看汇编,反正都要学你现在直接开始尝试就行了。gcc 然后再 objdump 。

    你的问题涉及 unsigned 和 signed 的转化,然而 p111 说 C standard does not specify the conversion 。所以最好的方式是看汇编。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5501 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 07:05 · PVG 15:05 · LAX 00:05 · JFK 03:05
    ♥ Do have faith in what you're doing.