gpt4 book ai didi

c - unsigned int、float 数据类型和乘法的奇怪之处

转载 作者:太空宇宙 更新时间:2023-11-04 01:02:59 34 4
gpt4 key购买 nike

我对C语言不是很在行,刚遇到一个不懂的问题。代码是:

int main()
{
unsigned int a = 100;
unsigned int b = 200;
float c = 2;

int result_i;
unsigned int result_u;
float result_f;

result_i = (a - b)*2;
result_u = (a - b);
result_f = (a-b)*c;

printf("%d\n", result_i);
printf("%d\n", result_u);
printf("%f\n", result_f);
return 0;
}

输出是:

-200
-100
8589934592.000000
Program ended with exit code: 0

因为(a-b) 是负数且a,b 是unsigned int 类型,(a-b) 是平凡的。乘以一个浮点型数c后,结果为8589934592.000000。我有两个问题:

首先,为什么在乘以 int 类型数字 2 并赋值给 int 类型数字后结果是不平凡的?

其次,为什么 result_u 是非平凡的,即使 (a-b) 为负且 result_u 是 unsigned int 类型?

我正在使用Xcode来测试这段代码,编译器是默认的APPLE LLVM 6.0。

谢谢!

最佳答案

您的假设 a - b是负数是完全不正确的。

abunsigned int type 与这两个变量的所有算术运算都在 unsigned int 的域中执行类型。这同样适用于混合“unsigned intint ”算术。这样的操作实现模运算,模等于UINT_MAX + 1 .

这意味着表达式 a - b产生 unsigned int 类型的结果.它是一个很大的正值,等于 UINT_MAX + 1 - 100 .在具有 32 位 int 的典型平台上它是 4294967296 - 100 = 4294967196 .

表达式 (a - b) * 2还会产生 unsigned int 类型的结果.它也是一个很大的正值( UINT_MAX + 1 - 100 乘以 2 并取模 UINT_MAX + 1 )。在一个典型的平台上它是 4294967096 .

后一个值对于类型 int 来说太大了.这意味着当你将它强制为一个变量时 result_i , 发生有符号整数溢出。赋值时有符号整数溢出的结果是定义的实现。在你的情况下 result_i最终成为 -200 .它看起来“正确”,但语言不能保证这一点。 (尽管您的实现可能会保证这一点。)

变量 result_u收到正确的无符号结果 - 正值 UINT_MAX + 1 - 100 .但是您使用 %d 打印该结果printf 中的格式说明符, 而不是正确的 %u .打印unsigned int是违法的不属于 int 范围的值使用 %d说明符。因此,您的代码的行为未定义-100您在输出中看到的值只是该未定义行为的一种表现形式。此输出在形式上毫无意义,即使乍一看它似乎“正确”。

最后,变量result_f收到 (a-b)*c 的“正确”结果表达式,计算没有溢出,因为乘法是在 float 中执行的领域。你看到的是我上面提到的大正值乘以 2 .它可能四舍五入到 float 的精度虽然类型,这是实现定义的。确切的值为 4294967196 * 2 = 8589934392 .

有人会争辩说,您打印的最后一个值是唯一正确反射(reflect)无符号算术属性的值,即它“自然地”从 a - b 的实际结果中导出。 .

关于c - unsigned int、float 数据类型和乘法的奇怪之处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31328330/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com