在不保证C ++ 20有符号整数是2的补码之前。现在,我们有两篇论文建议将二进制补码标准化作为唯一的表示形式:p0907和p1236,如果我理解正确的话,其中有一篇被合并为C ++ 20工作草案。
那么,有符号到无符号的转换是什么意思,反之亦然?我查看了cppreference,发现以下内容:
如果目标类型为无符号,则结果值为等于源值模
2n
的最小无符号值 其中n
是用于表示目标类型的位数。如果目标类型是带符号的,则如果源整数可以用目标类型表示,则值不会更改。否则,结果是目标类型的唯一值等于源值模
2n
其中n
是用于表示目标类型的位数。 (请注意,这与未定义的有符号整数算术溢出不同)。
不幸的是,我在理解此措词时遇到困难,我想知道C ++ 20工作草案中写的是什么。
所以有两个问题:
语言律师部分:有人可以指出该标准的确切含义以及该标准在何处注明吗?
有人可以用更多的外行术语来解释该措辞,也许还可以解释模块化算术并提供示例?
答案 0 :(得分:4)
转换规则为[conv.integral]/3:
否则,结果是目标类型的唯一值与源整数
2N
取模,其中N
是目标类型的范围指数。
其中范围指数在[basic.fundamental]的表中进行了描述,但表示您期望的含义(int
至少为16,long long
至少为64,依此类推)
例如,将值short
的{{1}}转换为-3
就是要找到类型unsigned short
的唯一值,该值与unsigned short
模{ {1}} ...也就是说-3
或216
。但是将216-3
的相同65533
值转换为short
会将模数基数更改为-3
,因此最终得到的是unsigned long long
。
从带符号类型转换为具有不同范围指数的带符号类型(或类似地从无符号到无符号)更简单-您可以将位砍掉或零扩展。例如,将值258的264
转换为18446744073709551613
或short
或int
只是258,而转换为long
则是2。
答案 1 :(得分:1)
您的报价中使用了很多单词来表达一些简单的内容:对于每个整数i
,在k
和0
之间恰好有一个整数M
,因此{ {1}}(在数学意义上,不是“固定大小整数表示形式”的意义)。用更多的外行术语来说,i % M == k
的意思是“如果我从i % M == k
加上或减去M
正确的次数,我可以获得i
”。
对于整数转换,k
,其中M = 2^N
是目标类型中的位数。该标准说:
否则,结果是目标类型的唯一值与源整数
N
取模,其中2^N
是目标类型的范围指数。
在示例中:
说您的目标类型有4位,因此它可以表示N
至2^4 = 16
的{{1}}值。将0
转换为该范围会产生15
,1
会产生1
,14
会产生14
,15
会产生{{1} },15
产生16
,0
产生17
,依此类推。转换1
会产生18
,2
会产生0
,0
会产生-1
等。
如果您真的想更深入地介绍模块化算术,则超出了本网站的范围。您应该参考网络上的大量资源,例如this one。