V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Explr
V2EX  ›  程序员

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

  •  
  •   Explr · 2022-02-20 11:05:52 +08:00 · 2398 次点击
    这是一个创建于 992 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如下 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 条回复    2022-02-20 20:56:33 +08:00
    EggtartZ
        1
    EggtartZ  
       2022-02-20 11:42:01 +08:00
    应该是 unsigned short 和 short 比较前会先被提升到 int(unsigned int)类型吧。
    mons
        2
    mons  
       2022-02-20 11:51:19 +08:00   ❤️ 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  
       2022-02-20 11:57:30 +08:00 via Android   ❤️ 3
    前两个比较,因为左边有 unsigned int ,所以右边数的被转换到了 unsigned int ;后两个比较,因为所有的数都在 int (signed int) 范围内,因此两边的数都升级到了 int / signed int 。
    mascteen
        4
    mascteen  
       2022-02-20 14:35:52 +08:00 via Android
    implicit number conversion.
    LotusChuan
        5
    LotusChuan  
       2022-02-20 15:31:47 +08:00 via iPhone
    你可以反汇编一下看看怎么比较的,csapp 的 lab 有反汇编的课程要求。
    DeWjjj
        6
    DeWjjj  
       2022-02-20 19:06:04 +08:00
    首先一个原则 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
       2022-02-20 20:03:50 +08:00
    @LotusChuan 是这个样子的,后面就有个 BombLab ,我还没看到那里。emm...不过我还真没想到这个思路。
    LotusChuan
        8
    LotusChuan  
       2022-02-20 20:56:33 +08:00
    @Explr
    BombLab 和 AttackLab 都是看汇编,反正都要学你现在直接开始尝试就行了。gcc 然后再 objdump 。

    你的问题涉及 unsigned 和 signed 的转化,然而 p111 说 C standard does not specify the conversion 。所以最好的方式是看汇编。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5377 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 07:17 · PVG 15:17 · LAX 23:17 · JFK 02:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.