试图从标准中了解有符号整数转换规则

时间:2019-07-11 05:20:34

标签: c language-lawyer

试图了解标准中的语法:

  

6.3.1.3有符号和无符号整数

     
      
  1. 将整数类型的值转换为另一种整数类型时   除了_Bool以外,如果该值可以由新类型表示,则它   不变。
  2.   
  3. 否则,如果新类型是无符号的,则值为   通过反复加或减一个   可以用新类型表示的最大值,直到该值为止   在新类型的范围内。
  4.   
  5. 否则,将对新类型进行签名并   该值不能在其中表示;要么结果是   实施定义或实施定义的信号被引发。
  6.   

请注意2部分,这意味着将int投射到unsigned int中的值上,即可将UINT_MAX + 1强制转换为int

例如,在这两个讨论中讨论了哪个:

Can a C compiler change bit representation when casting signed to unsigned?

Signed to unsigned conversion in C - is it always safe?

好吧,由于UINT_MAX + 1始终被承诺为零(https://stackoverflow.com/a/14899158/2162550),因此2部分可以理解为:

  

否则,如果新类型是无符号的,则将值转换为   重复添加或减去,直到该值在   新类型。

这对我来说毫无意义,因为加零不会改变。我的英语口译不好吗?我在这里想念什么?

2 个答案:

答案 0 :(得分:4)

  
      
  1. 否则,如果新类型是无符号的,则将值转换为   重复加或减一个比最大值大   可以用新类型表示,直到该值在   新类型。
  2.   

在这种情况下,“加或减”是指对数学值进行运算,而不是使用C的+-运算符对C值进行运算。

例如,如果起始值为-42,而UINT_MAX65535,则结果为-42 + 6553665494。该数学值在unsigned int的范围内,得出C值为65494U

确实,对C表达式UINT_MAX + 1求值的结果为零。这就是为什么该标准指的是“比可以在新类型中表示的最大值多一个”而不是UINT_MAX + 1。 (诚​​然,它可以说得更清楚一点。)

答案 1 :(得分:2)

首先,C标准摘录中缺少两个重要的单词,需要阅读其中

  
      
  • 否则,如果新类型是无符号的,则通过重复添加或减去比新类型中可以表示的最大值多一个值来转换值[,就好像],直到该值是在新类型的范围内。
  •   

即整个要点讨论了抽象机将如何进行计算。实际上,没有系统会使用重复的加法/减法将值减小到范围内。

更多部分只能理解为,表示无符号类型中不能表示的值,否则不能再一个,即>。可以将措词与含糊不清的+ 1进行对比。

表示转化的另一种方式是,结果是结果的除以正余数比最大可表示值大。