c - C 中的符号扩展

标签 c bit

我在这里寻找理解符号扩展: http://www.shrubbery.net/solaris9ab/SUNWdev/SOL64TRANS/p8.html

    struct foo {
        unsigned int    base:19, rehash:13;  
    };

    main(int argc, char *argv[]) 
    {
        struct foo  a;
        unsigned long addr;

        a.base = 0x40000;
        addr = a.base << 13;        /* Sign extension here! */
        printf("addr 0x%lx\n", addr);

        addr = (unsigned int)(a.base << 13);  /* No sign extension here! */
        printf("addr 0x%lx\n", addr);
    }

他们声称:

------------------ 64 位:

% cc -o test64 -xarch=v9 test.c
% ./test64
addr 0xffffffff80000000
addr 0x80000000
%

------------------ 32 位:

% cc -o test32 test.c
% ./test32
addr 0x80000000
addr 0x80000000
%

我有 3 个问题:

  1. 什么是符号扩展?是的,我阅读了 wiki,但不明白何时会发生类型提升,符号扩展是怎么回事?
  2. 为什么 ffff.. 在 64 位(引用地址)?
  3. 当我进行类型转换时,为什么没有符号扩展?

编辑: 4.为什么32位系统没有问题?

最佳答案

<< 的左操作数运营商进行标准促销,因此在您的情况下它被提升为 int - 到目前为止,一切都很好。接下来,int值(value)0x4000乘以 213,这会导致溢出并从而导致未定义的行为。然而,我们可以看到发生了什么:表达式的值现在只是 INT_MIN ,最小的可表示的 int 。最后,当您将其转换为无符号 64 位整数时,通常的模算术规则要求结果值为 0xffffffff80000000 。同样,转换为无符号 32 位整数给出值 0x80000000 .

要对无符号值执行操作,您需要使用强制转换来控制转换:

(unsigned int)(a.base) << 13

关于c - C 中的符号扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19260052/

相关文章:

c# - 如何在 C# 中有效地设置/获取位模式

c++ - 如何在 C++ 中一点一点地循环 long long

c++ - 是否可以同时控制 [] operator 和 operator=?

c - 访问不带括号的函数指针

C - 将结构内部的指针重新分配给结构外部的指针

c - 为什么我应该使用归约而不是原子变量?

java - 如何在 Java 中反转无符号字节的位?

c - Windows-C 代码使程序在启动时运行

c - 如何按值而不是引用添加字符串

php - 在MySQL+PHP中按位状态搜索