C 无符号整数、浮点数据类型和乘法的古怪
我不是很擅长C语言,只是遇到了一个我不懂的问题。代码是:C 无符号整数、浮点数据类型和乘法的古怪,c,unsigned,unsigned-integer,C,Unsigned,Unsigned Integer,我不是很擅长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
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是无符号整数类型,则(a-b)是平凡的。乘以浮点数c后,结果为8589934592.000000。我有两个问题:
首先,为什么将整数类型编号2相乘并分配给整数类型编号后的结果是非平凡的
第二,为什么即使(a-b)是负数并且结果是无符号整数类型,结果仍然是非平凡的
我正在使用Xcode测试这段代码,编译器是默认的APPLE LLVM 6.0
谢谢 您在printf中得到负数,因为您要求它打印一个带有%d的有符号整数。如果要查看最终得到的实际值,请使用%u。这还将向您展示如何得到浮点乘法的输出 你认为
a-b
为负值的假设是完全错误的
由于a
和b
具有unsigned int
类型,因此使用这两个变量的所有算术运算都在unsigned int
类型的域中执行。这同样适用于混合“unsigned int
”算法和int
”算法。此类操作实现模运算,模等于UINT\u MAX+1
这意味着表达式a-b
生成类型为unsigned int
的结果。它是一个大的正值,等于UINT_MAX+1-100
。在具有32位int
的典型平台上,它是4294967296-100=4294967196
表达式(a-b)*2也会生成类型为无符号int
的结果。它也是一个很大的正值(UINT_MAX+1-100
乘以2
,取模UINT_MAX+1
)。在典型的平台上,它是4294967096
后一个值对于类型int
太大。这意味着当您将其强制放入变量result\u i
时,会发生有符号整数溢出。赋值时有符号整数溢出的结果由实现定义。在您的情况下,result\u i
最终为-200
。它看起来“正确”,但语言不能保证这一点。(尽管您的实现可能会保证这一点。)
变量result\u
接收正确的无符号结果-正值UINT\u MAX+1-100
。但是您可以使用printf
中的%d
格式说明符打印该结果,而不是使用正确的%u
。使用%d
说明符打印不符合int
范围的无符号int
值是非法的。因此,代码的行为未定义。您在输出中看到的-100
值只是未定义行为的一种表现。这个输出在形式上是没有意义的,即使它乍一看是“正确的”
最后,变量result\u f
接收(a-b)*c
表达式的“正确”结果,因为乘法是在float
域中执行的,因此计算时不会溢出。您看到的是我上面提到的大正值乘以2
。但它很可能被四舍五入到float
类型的精度,这是实现定义的。准确的值应该是4294967196*2=8589934392
有人可能会争辩说,您打印的最后一个值是唯一正确反映无符号算术特性的值,即它“自然”来自a-b
的实际结果。您能描述一下您所说的“非平凡”是什么意思吗?printf(“%d\n”,result\u)代码>-->printf(“%u\n”,结果)谢谢大家。我认为“平凡”等于无意义,“非平凡”正好相反。是的,它应该是“%u”而不是%d。但我想知道为什么“%d”可以得到正确的结果?谢谢。琐碎并不意味着无意义,非琐碎也不是无意义的对立面“非平凡”通常意味着“不简单或不明显”,它将如何显示他如何得到浮点输出?他使用已经正确的%f
打印浮点。它将显示无符号int结果的正确值,这使%f printf的输出变得明显。非常感谢!在表达式(a-b)*2中,2是否也自动视为无符号整数?是因为a,b是未签名的int吗?@facebook-1536745818;是。@facebook-1536745818:正式地说,2
是一个int
。但是,当您混合使用大小相同的有符号类型和无符号类型时,无符号类型将“获胜”,并且计算将在无符号类型的域中执行。因此,是的,2
被解释为无符号。