代码之家  ›  专栏  ›  技术社区  ›  Robert Deml

正在发生什么类型的转换?

  •  1
  • Robert Deml  · 技术社区  · 14 年前
    #include "stdio.h"
    
    int main()
    {
        int x = -13701;
        unsigned int y = 3;
        signed short z = x / y;
    
        printf("z = %d\n", z);
    
        return 0;
    }
    

    我希望答案是-4567。我得到“z=17278”。

    我在监狱里执行了这个 Code Pad .

    4 回复  |  直到 14 年前
        1
  •  11
  •   John Kugelman Michael Hodel    14 年前

    隐藏类型转换为:

    signed short z = (signed short) (((unsigned int) x) / y);
    

    混合使用有符号和无符号类型时,无符号类型获胜。 x unsigned int ,除以3,然后将结果向下转换为(有符号) short . 使用32位整数:

    (unsigned) -13701         == (unsigned) 0xFFFFCA7B // Bit pattern
    (unsigned) 0xFFFFCA7B     == (unsigned) 4294953595 // Re-interpret as unsigned
    (unsigned) 4294953595 / 3 == (unsigned) 1431651198 // Divide by 3
    (unsigned) 1431651198     == (unsigned) 0x5555437E // Bit pattern of that result
    (short) 0x5555437E        == (short) 0x437E        // Strip high 16 bits
    (short) 0x437E            == (short) 17278         // Re-interpret as short
    

    顺便说一下 signed 关键字是不必要的。 signed short 是一个较长的说法 . 唯一需要显式 签署 char 烧焦

        2
  •  4
  •   Community CDub    8 年前

    简言之:事业部首先提升 x unsigned . 只有到那时,结果才被抛回原处 signed short .

    this SO thread.

        3
  •  3
  •   ThR37    14 年前

    问题来自 unsigned int y . 的确, x/y 变为无符号。它适用于:

    #include "stdio.h"
    
    int main()
    {
        int x = -13701;
        signed int y = 3;
        signed short z = x / y;
    
        printf("z = %d\n", z);
    
        return 0;
    }
    
        4
  •  1
  •   AnT stands with Russia    14 年前

    int 更大)。如果您的原始有符号值是负数,它将首先根据有符号到无符号转换的规则转换为正无符号值。对你来说 -13701 UINT_MAX + 1 - 13701 结果将作为股息。

    请注意,有符号到无符号转换在典型的32位上的结果 内景 4294953595 . 除法之后 3 1431651198 . 此值太大,无法强制转换为 short 16位平台上的对象 类型。尝试这样做会导致实现定义的行为。因此,如果您的平台的属性与我的假设中的属性相同,那么您的代码将生成实现定义的行为。从形式上讲,“毫无意义” 17278 您得到的价值不过是实现定义的行为的具体表现。如果您在编译代码时启用了溢出检查(如果您的编译器支持它们),那么它可能会在赋值时陷入陷阱。