问题描述
假设我有一个名为 T
的类型名称,它的大小总是 >=
T2
都是无符号的.如何检查 T
类型的变量 a
是否适合 T2
而不会溢出,如果不适合执行其他操作?我试过检查它是否变成阴性,但我不确定它是否是正确的检查方法,如下所示:
Let's assume I have a type name called T
and its size always is >=
T2
both are unsigned. How do I check if a variable a
of type T
will fit into T2
without overflow and if it didn't fit do some other operation? I've tried check if it's became negative but I'm not sure if it's right way to check, like this:
T a = ...;
T2 b = a;
if(b < 0) // didn't fit
else // ok, fit
推荐答案
这不起作用:如果 0T
和 T2
未签名,b
永远是假的.
This won't work: if T
and T2
are unsigned, b < 0
will always be false.
因为这两种类型都是无符号的,所以可以保证溢出会导致环绕(旁注:如果这些是有符号类型,溢出会导致 UB,尽管它通常也会环绕).因此,您可以使用以下内容:
Since both of these types are unsigned, it is guaranteed that overflow causes wrap around (side note: if these were signed types, overflowing would cause UB, although it usually wraps around too). Thus, you can use something like:
T a = ...;
T2 b = a;
if ((T) b != a) {
/* didn't fit */
}
else { ... }
b
的强制转换不是绝对必要的:如果 sizeof(T)
> sizeof(T2)
,那么通常的算术转换会导致b
在与 a
比较之前要转换为 T
.但是,为了清楚起见,我选择明确地将其留在那里.
The cast around b
is not strictly necessary: if sizeof(T)
> sizeof(T2)
, then the usual arithmetic conversions cause b
to be converted to T
before comparing to a
. However, to make it clear, I chose to explicitly leave it there.
根据关于 C99 的第 6.3.1.3 节(请参阅下面的评论),这是将无符号整数转换为更窄的无符号类型时发生的情况:
According to section 6.3.1.3 on C99 (see comments below), this is what happens when an unsigned integer is converted to a narrower unsigned type:
如果新类型是无符号的,则值被重复转换加或减一个比最大值以新类型表示,直到值在新类型的范围内输入
这意味着在溢出的情况下,当转换回T
时,b
将不等于a
.这就是此代码背后的基本原理.此外,它会小于a
,因此您可以根据需要将!=
切换为<
.
This means that in case of overflow, b
will not be equal to a
when converted back to T
. That's the rationale behind this code. Moreover, it will be less than a
, so you can switch !=
to <
if you prefer.
或者,您可以在分配给 b
之前检查以确保它适合:
Alternatively, you can check before assigning to b
to make sure it will fit:
T a = ...;
T2 b;
if (a > (T2)-1) {
/* won't fit */
}
else {
/* fits */
}
(T2) -1
是无符号类型T2
可以容纳的最大值.如果a
大于这个,那么它显然不适合b
.要了解为什么 (T2) -1
可移植且始终有效,请参阅此问题:使用-1将所有位设置为true是否安全?
(T2) -1
is the maximum value that the unsigned type T2
can hold. If a
is greater than this, then it won't obviously fit into b
. To see why (T2) -1
is portable and always work, see this question: Is it safe to use -1 to set all bits to true?
这篇关于如何检查值是否适合类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!