正在发生什么类型转换?

发布于 2024-09-24 23:50:16 字数 328 浏览 6 评论 0原文

#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”。 为什么这些数字的提升结果是 17278?

我在 Code Pad 中执行了此操作。

#include "stdio.h"

int main()
{
    int x = -13701;
    unsigned int y = 3;
    signed short z = x / y;

    printf("z = %d\n", z);

    return 0;
}

I would expect the answer to be -4567. I am getting "z = 17278".
Why does a promotion of these numbers result in 17278?

I executed this in Code Pad.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甜是你 2024-10-01 23:50:16

隐藏的类型转换是:

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 Shortshort 的更长表达方式。唯一需要显式signed 的类型是charchar 可以有符号或无符号,具体取决于平台;所有其他类型始终默认签名。

The hidden type conversions are:

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

When you mix signed and unsigned types the unsigned ones win. x is converted to unsigned int, divided by 3, and then that result is down-converted to (signed) short. With 32-bit integers:

(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

By the way, the signed keyword is unnecessary. signed short is a longer way of saying short. The only type that needs an explicit signed is char. char can be signed or unsigned depending on the platform; all other types are always signed by default.

无法回应 2024-10-01 23:50:16

简短的回答:除法首先将x提升为unsigned。只有这样,结果才会被转换回有符号短

长答案:阅读这个SO线程。

Short answer: the division first promotes x to unsigned. Only then the result is cast back to a signed short.

Long answer: read this SO thread.

子栖 2024-10-01 23:50:16

问题来自于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;
}

The problems comes from the unsigned int y. Indeed, x/y becomes unsigned. It works with :

#include "stdio.h"

int main()
{
    int x = -13701;
    signed int y = 3;
    signed short z = x / y;

    printf("z = %d\n", z);

    return 0;
}
同展鸳鸯锦 2024-10-01 23:50:16

每次在加法和乘法算术运算中混合“大”有符号和无符号值时,无符号类型“获胜”,并且在无符号类型的域中执行计算(“大”意味着 int 和更大) )。如果您的原始有符号值是负数,则它首先会根据有符号到无符号转换的规则转换为正无符号值。在您的情况下,-13701 将变为 UINT_MAX + 1 - 13701,结果将用作股息。

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

Every time you mix "large" signed and unsigned values in additive and multiplicative arithmetic operations, unsigned type "wins" and the evaluation is performed in the domain of the unsigned type ("large" means int and larger). If your original signed value was negative, it first will be converted to positive unsigned value in accordance with the rules of signed-to-unsigned conversions. In your case -13701 will turn into UINT_MAX + 1 - 13701 and the result will be used as the dividend.

Note that the result of signed-to-unsigned conversion on a typical 32-bit int platform will result in unsigned value 4294953595. After division by 3 you'll get 1431651198. This value is too large to be forced into a short object on a platform with 16-bit short type. An attempt to do that results in implementation-defined behavior. So, if the properties of your platform are the same as in my assumptions, then your code produces implementation-defined behavior. Formally speaking, the "meaningless" 17278 value you are getting is nothing more than a specific manifestation of that implementation-defined behavior. It is possible, that if you compiled your code with overflow checking enabled (if your compiler supports them), it would trap on the assignment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文