c - 如何检查值是否适合类型?

标签 c types overflow

假设我有一个名为 T 的类型名称,其大小始终为 >= T2 两者都是无符号的。如何检查 T 类型的变量 a 是否适合 T2 而不会溢出,如果不适合则执行其他操作?我尝试检查它是否变为负值,但我不确定这是否是正确的检查方法,如下所示:

T a = ...;
T2 b = a;
if(b < 0) // didn't fit
else // ok, fit

最佳答案

这不起作用:如果 TT2未签名,b < 0永远都是假的。

由于这两种类型都是无符号的,因此可以保证溢出会导致回绕(旁注:如果这些是有符号类型,溢出将导致 UB,尽管它通常也会回绕)。因此,您可以使用如下内容:

T a = ...;
T2 b = a;
if ((T) b != a) {
   /* didn't fit */
}
else { ... }

Actor 阵容b并不是绝对必要的: if sizeof(T) > sizeof(T2) ,那么通常的算术转换会导致 b转换为Ta 进行比较之前。然而,为了清楚起见,我选择明确地将其保留在那里。

根据 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/

相关文章:

c - 如何正确使用 sem_timedwait()

c - 从 create_proc_read_entry 迁移到 proc_create 并使用 seq_files

python - 大 TSV 文件中 moSTLy 整数字符串列的 pandas read_csv dtype 推断不一致

c - int最快的c算术方法

构建二叉搜索树时的编译错误

c - C 中的 Shellcode - 这是什么意思?

python - 类信息类型列表

Scala自定义 map

c - 为什么使用双变量时不会溢出?

jquery - 溢出:隐藏属性在 Firefox 中表现异常/在 Chrome/Safari 中表现良好