在一些C99代码中,我需要检查变量i是否在区间[0, max]内,其中max被认为是正数。问题是该变量的类型可以是有符号的和无符号的(通过更改
直接的方法是:
这将在
我的当前想法是将
如果有符号类型具有二进制补码表示,则将任何负值强制转换为无符号版本后应大于
typedef
)。如何最好地检查变量是否在区间内?直接的方法是:
bool is_in_interval(my_type i, my_type max) {
assert(max > 0);
return (i >= 0 && i <= max);
}
这将在
typedef int my_type;
的情况下正常工作。但是当my_type
为无符号数时(即typedef unsigned int my_type;
),i >= 0
始终为真,编译器会(正确地)警告此问题,我想避免这种情况。(我不想关闭该警告,因为当实际上出现这样的比较时,它是有用的,而仅仅忽略编译器警告并不是一个好主意。)我的当前想法是将
i
转换为无符号类型,只检查上界:bool is_in_interval(my_type i, my_type max) {
assert(max > 0);
return ((size_t) i <= (size_t) max);
}
如果有符号类型具有二进制补码表示,则将任何负值强制转换为无符号版本后应大于
max
,是吗?如果是这样,那么这应该可以工作。然而,我不确定这是否是明智的方法。例如,假设所有平台上的有符号类型都使用二进制补码是安全的吗?有更好的方法吗?
MAX/2
,则此方法将无效。这种情况可能发生吗?(嗯,也许我是指小于。) - JongwareMAX
不是类型的限制(例如INT_MAX
或UINT_MAX
)。使用大写字母会产生误导(现在已更正)。 - Fredrik Savjesize_t
更宽的整数类型(非正式地说,更大),如果是这样,那么强制转换可能会改变值并给出错误结果。来自<stdint.h>
的uintmax_t
可以在 C99 及更高版本中避免此问题(但您说过是 C99)。另一方面,2sC 不是问题;在 C 中将有符号整数转换为无符号整数被定义为有效地加上或减去 2,即使在(非常罕见的)1sC 或 S&M 机器上也是如此。 - dave_thompson_085