假设我有一个名为 T
的类型名称,其大小始终为 >=
T2
两者都是无符号的。如何检查 T
类型的变量 a
是否适合 T2
而不会溢出,如果不适合则执行其他操作?我尝试检查它是否变为负值,但我不确定这是否是正确的检查方法,如下所示:
T a = ...;
T2 b = a;
if(b < 0) // didn't fit
else // ok, fit
最佳答案
这不起作用:如果 T
和T2
未签名,b < 0
永远都是假的。
由于这两种类型都是无符号的,因此可以保证溢出会导致回绕(旁注:如果这些是有符号类型,溢出将导致 UB,尽管它通常也会回绕)。因此,您可以使用如下内容:
T a = ...;
T2 b = a;
if ((T) b != a) {
/* didn't fit */
}
else { ... }
Actor 阵容b
并不是绝对必要的: if sizeof(T)
> sizeof(T2)
,那么通常的算术转换会导致 b
转换为T
与 a
进行比较之前。然而,为了清楚起见,我选择明确地将其保留在那里。
根据 C99 的第 6.3.1.3 节(请参阅下面的注释),当无符号整数转换为更窄的无符号类型时会发生以下情况:
if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type
这意味着在溢出的情况下,b
将不等于 a
当转换回T
时。这就是这段代码背后的基本原理。此外,它将小于 a
,这样您就可以切换!=
至<
如果你愿意的话。
或者,您可以在分配给 b
之前进行检查确保它适合:
T a = ...;
T2 b;
if (a > (T2)-1) {
/* won't fit */
}
else {
/* fits */
}
(T2) -1
是无符号类型 T2
的最大值能把持住。如果a
大于这个,那么它显然不适合 b
。看看为什么 (T2) -1
是可移植的并且始终可以工作,请参阅这个问题:Is it safe to use -1 to set all bits to true?
关于c - 如何检查值是否适合类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22157923/