当x,y是字符,并且ux=(无符号)x,uy=(无符号)y时,在C中ux-uy==-(y-x)总是正确的吗?
我有以下C代码:当x,y是字符,并且ux=(无符号)x,uy=(无符号)y时,在C中ux-uy==-(y-x)总是正确的吗?,c,char,integer,unsigned-integer,C,Char,Integer,Unsigned Integer,我有以下C代码: char x, y; // Some random values unsigned ux = (unsigned)x; unsigned uy = (unsigned)y; 我需要确定表达式ux-uy==-(y-x)是否总是正确的,并证明它或给出一个反例 我不知道这是不是真的,因为它们是不同类型的整数,大小不同,其中两个是有符号的,另外两个是无符号的。不,有很多情况下,ux-uy==-(y-x)是不正确的 char具有实现定义的符号性,因此没有可移植的方法来判断x和y首先是
char x, y; // Some random values
unsigned ux = (unsigned)x;
unsigned uy = (unsigned)y;
我需要确定表达式ux-uy==-(y-x)
是否总是正确的,并证明它或给出一个反例
我不知道这是不是真的,因为它们是不同类型的整数,大小不同,其中两个是有符号的,另外两个是无符号的。不,有很多情况下,
ux-uy==-(y-x)
是不正确的
具有实现定义的符号性,因此没有可移植的方法来判断x和y首先是包含正值还是负值char
- x和y将整数提升为
,而不考虑其符号性,可能是符号扩展int
的操作数将根据“通常的算术转换”得到平衡,这意味着您最终将右操作数隐式转换为无符号类型,而不管它最初的值是什么 在理论上,这是以实现定义的方式完成的,但在实践中,它将在所有现实世界2的补充系统上工作相同=
避免此类问题的解决方案是对所选类型更加小心。避免对小整数类型进行算术运算。注意可变范围。学习各种隐式类型提升规则,以及它们如何导致符号改变等问题。这个问题比看起来更微妙。如果这是一次访谈,欢迎您详细说明实现定义的
char
符号、这些类型的大小,也包括实现定义、整数从char
提升到int
或无符号int
,具体取决于类型char
的大小和符号,关于二进制运算符(如=
)隐含的类型转换、有符号和无符号减法之间的差异、与未定义变量和有符号算术溢出相关的随机值和未定义行为。如果你掌握了这些科目,你可能会发现面试官可能不会。建议极其小心地相应调整您的演示
char x, y; // Some random values
unsigned ux = (unsigned)x;
unsigned uy = (unsigned)y;
x
和y
没有随机值,它们是未初始化的。计算(无符号)x
,(无符号)y
和y-x
都会调用未定义的行为。因此,按照编码,等式没有意义,它是未定义的x
和y
初始化为随机值,在一般情况下,问题是表达式ux-uy==-(y-x)
是否始终为真?答案是否定的,下面是一个反例:
在char
类型与int
具有相同大小和符号的体系结构上,表达式y-x
可能会溢出,例如,如果y=int\u MIN
和x=1
,并且该溢出具有未定义的行为。因此,对于这个体系结构和这些值,表达式ux-uy==-(y-x)
不是真的,它是未定义的char
具有8位且int
至少具有16位的更常见体系结构上,让我们研究不同的可能性:
- 在
中,y-x
和x
被提升为y
,因为该类型可以表示int
类型的所有值,无论类型char
是否有符号char
的类型为y-x
且在[-255,255]和int
范围内,并且-(y-x)
也在相同范围内。在这些体系结构上,int
与-(y-x)
和-y+x
具有相同的值。问题变成了:ux-uy==x-yx-y
- 表达式
将类型为ux-uy==x-y
的表达式与类型为unsigned int
的表达式进行比较。int
表达式转换为int
,并对无符号值进行比较unsigned int
- 通过将值
添加到负值并保留正值,可以将有符号整数值转换为无符号整数值。此操作的作用是计算算术值模UINT_MAX+1
UINT\u MAX+1
- 因此,表达式的计算公式为: ((x-mod(UINT_MAX+1))-(y-mod(UINT_MAX+1)))mod(UINT_MAX+1)=(x-y)mod(UINT_MAX+1)
- 模运算符是分布的,其值使得
是x-y
和x
的算术差,而与y
的符号无关char
sizeof(int)>1
的体系结构,答案是YES,该等式适用于x
和y
的所有值@Cherubim我知道有些编译器与其他编译器不同,所以我需要知道在这种情况下应该发生什么,而不是某些编译器实际做什么。@Cherubim这里的代码不能真正证明任何事情,因为有太多定义不清的行为。保存该程序在特定时刻在特定计算机和特定编译器上的行为。@Daniel:您可以通过单击其分数下方的灰色复选标记接受其中一个答案。虽然您的参数为真,但它们并不一定意味着
ux-uy==-(y-x)
不为真,您也不会给出这样的反例