超出范围时转换为有符号类型行为

Conversion to signed type behavior when out of range

提问人:Masquue 提问时间:2/25/2022 最后编辑:Masquue 更新时间:2/25/2022 访问量:299

问:

当源值无法在目标类型中表示时,将整数转换为有符号类型是根据 cppreference

  • 实现定义(直到 C++20)
  • 目标类型的唯一值等于源值模 2^n,其中 n 是用于表示目标类型的位数(自 C++20 起)

GCC 实现定义的行为中还指定了

为了转换为宽度为 N 的类型,该值将模 2^N 约简到该类型的范围内;未发出信号。

我想也有人说同样的话。我的问题是,减少/模制的结果是否仍然可能超出目标有符号类型的范围?假设 ,255 模 2^8 仍然是 255,保持不变。这种模制结果如何适应目标类型?signed char c = 255

答案显示了一种方法,该方法首先反转值并添加 1,然后在前面添加一个有符号位。我不确定这是否是实际所做的。

解释强调部分的正确/标准方法是什么?

C++ C++20 隐式转换 实现定义行为

评论

1赞 François Andrieux 2/25/2022
255 不是“目标类型的唯一值”。
2赞 Raymond Chen 2/25/2022
“约化模 2^N”中的“约简”一词具有特定的数学含义:“找到与原始值相差 2^N 的整数倍的唯一允许值。这里的“减少”一词并不意味着“减去”。相反,它指的是这样一个事实,即可能的答案集是所有整数集的简化集。

答:

2赞 eerorika 2/25/2022 #1

假设有符号 char = 255U,255 模 2^8 仍然是 255

255 不在类型范围内(8 位有符号整数)。

重新表述规则的一种方法是,转换后的结果将与不可表示的结果模 2^n 一致。

-513、-257、-1、255、511 都是全等模 256。在全等数中,只有 -1 在有符号类型的可表示范围内。

评论

0赞 Masquue 2/25/2022
怎么会有另一个一致的操作?目标类型的“相等”关系是否表明了这一点?
0赞 eerorika 2/25/2022
@Masquue -1 模 256 等于 255 模 256。因此,它们是全等模 256。
0赞 Masquue 2/25/2022
我意识到我对“模乘 2^N”的误解是 % 运算。谢谢。投了赞成票,但另一个答案似乎更严谨,有一点数学。
0赞 Jarod42 2/25/2022
@eerorika:“-1 模 256 等于 255 模 256” 从数学的角度来看,不是C++整数 ;-)
0赞 eerorika 2/26/2022
@Jarod42 它可以是;)但是,是的,我说的是它们的残差类,而不是 C++ 的余数运算符。
5赞 user17732522 2/25/2022 #2

这两个引号都不是说取原始值,应用模运算,以及将结果用作转换结果。

相反,它们意味着在目标类型中可表示的所有值中,数学相等的(唯一)值v

s + m * 2^n = v

对于某个整数 ,选择源值。如果它们满足此条件,则说 和 是全等模 2^n,或者有时它们也是相等模 2^nmssv

对于宽度为 的有符号目标,是不可表示的,但 是 并满足 的方程。s = 2558255-1v = -1m = -1