C++中(long long int)1<<j与1<<j的差异及代码报错分析
C++中
(long long int)1 << j与1 << j的区别及代码错误分析 一、两个表达式的核心差异
1 << j:这里的1是C++默认的int类型(通常为32位有符号)。当j的取值使得移位结果超出int的有效范围时(比如j >= 31),会触发未定义行为:对于有符号int,溢出的结果不符合标准定义;即使编译器按无符号处理,也只能生成32位范围内的数值,无法覆盖64位的需求。(long long int)1 << j:先把1强制转换为64位的long long int,移位操作在64位空间内执行。只要j < 64,就能得到合法的64位移位结果,不会出现溢出或未定义行为。
二、两段代码的错误原因
针对输入1000000000和2000000000的场景:
- 计算
ans = l ^ r后,其二进制最高有效位是第30位(从0开始计数),外层循环会定位到i=30,随后内层循环要将j从29到0的所有位逐一置1,最终让ans变成从0到30位全为1的数值。 - 第一段代码中,
1 << j的1是int类型:当j接近31时(比如其他场景下j=31),1 << 31会得到int类型的负数(-2147483648),将这个值转换为unsigned long long时会变成0xFFFFFFFF80000000,和ans进行或操作时会错误地置高位,导致最终结果偏离预期。 - 第二段代码中,
(long long int)1 << j将移位操作放在64位类型中执行,1 << 31会得到正确的64位正数2147483648,转换为unsigned long long后是0x80000000,能精准对应目标位,和ans或操作后可以正确置位,得到预期结果。
内容的提问来源于stack exchange,提问作者vishal aggarwal
相关产品推荐
相关产品推荐

