鱼C论坛

 找回密码
 立即注册
查看: 932|回复: 2

[已解决]小白求助

[复制链接]
发表于 2023-10-24 23:19:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <stdio.h>
void yichu(int i)
{
        int x = 1 << (sizeof(int) * 8 - 1);
        int result = x & i;
       
        if (result == 1)
                printf("发生了高位溢出\n");
        else
                printf("左移和右移的值分别为:%d %d",i<<=1,i>>=1);
}
int main(void)
{
        int i;
       
        printf("请输入一个数:");        scanf("%d",&i);       
        yichu(i);
       
        return 0;
}
求大佬指点为什么输入1000000000000明显溢出的值,却不会打印发生了高位溢出?
最佳答案
2023-10-24 23:19:38
问题出在这一行代码上:
int result = x & i;

在这里,你使用了位运算符 & 来检查最高位是否为1,以判断是否发生了高位溢出。然而,这个判断是错误的。

1 << (sizeof(int) * 8 - 1) 会将1左移到整型变量的最高位,得到一个负数。在大多数机器上, int 类型是32位的,所以左移31位后的值为-2147483648。而你输入的1000000000000明显比这个值要大,所以最高位肯定是1,但是由于 int 类型的范围限制,它的值会被截断,导致判断结果为0,即没有发生高位溢出。

要正确判断高位溢出,你可以使用无符号整型来存储输入的值,并将判断条件修改为:
unsigned int x = 1 << (sizeof(unsigned int) * 8 - 1);
unsigned int result = x & i;

if (result != 0)
    printf("发生了高位溢出\n");
else 
    printf("左移和右移的值分别为:%u %u", i <<= 1, i >>= 1);

这样,就能正确判断高位溢出了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-10-24 23:19:38 | 显示全部楼层    本楼为最佳答案   
问题出在这一行代码上:
int result = x & i;

在这里,你使用了位运算符 & 来检查最高位是否为1,以判断是否发生了高位溢出。然而,这个判断是错误的。

1 << (sizeof(int) * 8 - 1) 会将1左移到整型变量的最高位,得到一个负数。在大多数机器上, int 类型是32位的,所以左移31位后的值为-2147483648。而你输入的1000000000000明显比这个值要大,所以最高位肯定是1,但是由于 int 类型的范围限制,它的值会被截断,导致判断结果为0,即没有发生高位溢出。

要正确判断高位溢出,你可以使用无符号整型来存储输入的值,并将判断条件修改为:
unsigned int x = 1 << (sizeof(unsigned int) * 8 - 1);
unsigned int result = x & i;

if (result != 0)
    printf("发生了高位溢出\n");
else 
    printf("左移和右移的值分别为:%u %u", i <<= 1, i >>= 1);

这样,就能正确判断高位溢出了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-24 23:19:52 | 显示全部楼层
在你的代码中,你检查高位溢出的逻辑是使用位运算符&和常数1进行比较。然而,这种方法不能正确地检测到高位溢出。

原因是,你将右移操作符(>>)用于存储有符号整数类型 int 的变量 i。在进行右移操作时,C语言标准规定对有符号整数进行右移,结果取决于具体的实现。可能会发生算术右移,也可能会发生逻辑右移。在算术右移中,最高有效位(即符号位)的值会保持不变,而在逻辑右移中,最高有效位会被填充为零。

因此,当输入一个大于等于1000000000000的数时,右移操作不会引起高位溢出,因为最高有效位仍然为1。

要正确检测有符号整数的高位溢出,可以使用无符号整数类型 unsigned int 来执行位操作,并将结果与0x80000000(32位系统上的INT_MIN)进行比较。以下是修改后的代码示例:
#include <stdio.h>

void yichu(unsigned int i) {
    unsigned int x = 1U << (sizeof(unsigned int) * 8 - 1);
    unsigned int result = x & i;

    if (result != 0)
        printf("发生了高位溢出\n");
    else
        printf("左移和右移的值分别为:%u %u\n", i <<= 1, i >>= 1);
}

int main(void) {
    unsigned int i;

    printf("请输入一个数:");
    scanf("%u", &i);
    yichu(i);

    return 0;
}

这样修改后的代码会正确检测到输入大于等于1000000000000的数时的高位溢出。
请注意,本回答来自GPT-4
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-5 19:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表