C 如何转换2';s对机器相应的签名副本的补充?

C 如何转换2';s对机器相应的签名副本的补充?,c,language-lawyer,unsigned,unsigned-integer,C,Language Lawyer,Unsigned,Unsigned Integer,设a为有符号整数类型的变量T,而U为相应的无符号类型。表达式(U)a产生一个值,该值对应于a的值作为U的两个补码表示。我想知道C标准是否保证可以撤销该强制转换。是u类型的u,并且具有(u)a的值。BeMAX类型T可容纳的最大值。(请注意隐式转换为无符号类型,以及有符号变量的每个正值在这些转换中保持不变的事实。) 首先,假设,T能够保存结果: T convert_2scomplement_to_T(U n) { return n<=MAX ? n : -(T)(U)-n; } 据我

a
为有符号整数类型的变量
T
,而
U
为相应的无符号类型。表达式
(U)a
产生一个值,该值对应于
a
的值作为
U
的两个补码表示。我想知道C标准是否保证可以撤销该强制转换。是
u
类型的
u
,并且具有
(u)a
的值。Be
MAX
类型
T
可容纳的最大值。(请注意隐式转换为无符号类型,以及有符号变量的每个正值在这些转换中保持不变的事实。)

首先,假设,
T
能够保存结果:

T convert_2scomplement_to_T(U n) {
    return n<=MAX ? n : -(T)(U)-n;
}
据我所知,标有
/(*)
的行并不严格符合要求,因为标准没有对符号位的位置做出任何保证

所描述的功能是否按预期工作?在严格符合规范的情况下,是否可以避免检查符号位

(除了语言律师这件事……如果有人写过代码,知道至少有一个人在不使用两个补码的平台上使用过它,那么他可以留下评论,这是什么机器。提到

符号震级:

补语:


但在今天编写的程序中,这似乎没有什么可担心的。有什么理由该标准仍然针对这样的机器吗?

我认为这并不复杂。一个人的补码运算实际上更简单,因为每个数字都是其反数值的补码。唯一的问题是处理所有位集,因为它转换为负零

因此,是的,强制转换S->U->S肯定是可逆的,但是对于设置了高位的值,U->S->U可能会失败。对于负零,您可能无法撤消它,因为信息可能会丢失

将有符号强制转换为无符号保留位模式,是一种不可操作的操作

Unsigned to signed必须处理设置了高位的数字。上的所有位都是合法的,表示负零,允许陷阱、被视为零或被强制为零(至少这是我的读数,但我手边没有Univac 1100可供试用)。具有高位集的其他值超出有符号范围,因此行为由实现定义。它很可能会保留位模式,这是最容易做到的事情


如果你在寻找担保,你可能找不到。C/C++的大部分都是这样的。

两个补码的整数转换定义如下。n3936 S4.7/2,3[n1570 s6.3.1.3类似]

如果目标类型是无符号的,则结果值是与源整数全等的最小无符号整数(模2n,其中n是用于表示无符号类型的位数)。[注:在2的补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断)。-结束注]

同余的定义是:(数学)两个数之间的关系,表示两个数除以某个给定数后得到相同的余数

最小的意思是最小或最低的价值。“某个给定值”是2^位数

因此,无符号转换的计算结果(k mod 2^n)等于(2^n-k)

  • 使用四位数字,(有符号)-1=>(无符号)15
  • 使用16位数字,(有符号)-1=>(无符号)65535
  • 使用32位数字,(有符号)-1=>(无符号)4294967295
在每种情况下,这都需要复制位模式并增加结果

如果目标类型是有符号的,如果可以在目标类型(和位字段宽度)中表示,则该值不变;否则,该值由实现定义

在每种情况下,(无符号)值都不能在(有符号)目标类型中表示,因此您必须检查实现定义。深思熟虑的实现可能会反转上面指定的操作,但标准不要求这样做


因此,答案是,该标准不保证用于两个补码实现的有符号到无符号整数转换的往返;如果你要求的东西只在2的补码机器上工作?“表达式(U)a产生一个对应于2的补码表示a的值的值”-一般不正确。一般来说,如果你要求运算<代码>(u)的< /代码>,那么就要说明,你不是试图把2的补码从两个补码转换成一个带符号的数字,而是希望看到这个问题的最高答案(HVD):答案是C++,但我认为它也适用于C.@ QBT937;谢谢,我没找到那个。投票将我的问题作为重复项关闭,这样您可以再次尝试关闭它。“将有符号转换为无符号保留位模式,是不可操作的。”-不,在使用2的补码的计算机上,这只是不可操作的。如果不是,这是到2的补码的转换(忽略填充位)。也就是说,如果
n
的类型是
int
,那么
(无符号)n
的值与
*(无符号*)&n
的值不同,如果
n
为负数,我们有一台机器不使用2的补码。也许我的问题有点不清楚:例如(让我们暂时忽略填充位),设想一个程序将无符号整数作为表示某个值的2的补码的输入,我们希望将该值存储在相应的有符号整数对象中(我不想键入pun/reinterpret,我想转换)。在做了一些进一步的研究之后,我写了一个全新的答案。希望你喜欢。非常感谢你的帮助
T convert_2scomplement_to_T_checked(U n) {
    if(n <= MAX) return n;
    if( !(n & (U)1 << sizeof(U)*CHAR_BIT-1) ) { // (*)
        // invalid argument, the value is positive and `T' cannot hold it
    }
    /* `n' represents something negative if we're here. */
    if(-n < MIN) {
        // invalid argument, the value is negative and `T' cannot hold it
    }
    return -(T)(U)-n;
}