#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int a = 1;
int b = 0;
short int c = 0;
while (b < 18)
{
c = a << b;
printf("左移%d位结果:%d\n",b,c);
b++;
}
return 0;
}
定义了一个短整型变量c。将a移位后的值赋值给c并输出。结果如下:
为什么在左移15位的时候会产生-32768?
AI解答如下:当 b
为 15 时,a
被左移了 15 位。在这个过程中,发生了整数溢出,导致结果不正确。具体来说,左移操作相当于乘以 2 的 b
次方,当 b
为 15 时,乘积超过了 int
类型的最大值,所以结果不正确。
short int是2字节变量。一个字节是8位共16位也就是2^15=32768。
a=0000 0000 0000 0001
c=1000 0000 0000 0000
c应该为32768为什么会是“-32768”可能是把最高位看做了符号位导致。有待考证
随后我有试验了将十进制数3转换。结果如下
其中-16384对应带符号的二进制数1100 0000 0000 0000。又一次说明VS把最高位看做了符号位导致结果出错。
这两天有学习到了一点新知识,对上面的内容做补充。
int a = 0;
int b = ~a;
输出结果是-1.为什么呢?
看分析
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int a = 0; //int 四字节 一给字节8位 存储补码
int b = ~a;
printf("%d\n", b); //结果是-1 原码
//~--对二进制按位取反
//0000 0000 0000 0000 0000 0000 0000 0000
//原码、反码、补码
//负数在内存中存储的时候,存储的是二进制的补码。 正数的原码、反码、补码相等。
//所以内存中存储的是数的补码
//打印的是原码
//负数的反码:符号位不变,其余各位取反,则得到这个数字的反码表示形式。
//负数的补码:则将数字的反码加上1(相当于将原码数值位取反然后在最低位加1)。
//内存中0的补码 :0000 0000 0000 0000 0000 0000 0000 0000
//a~取反得 :1111 1111 1111 1111 1111 1111 1111 1111
//b是“对a取反”内存中记录的是b的补码
// 也就是 :1111 1111 1111 1111 1111 1111 1111 1111
//b的反码 :1111 1111 1111 1111 1111 1111 1111 1110
//b的原码 :1000 0000 0000 0000 0000 0000 0000 0001
//对应十进制数的-1,所以b输出是-1.
return 0;
}
同理对于上次的
//a = 0000 0000 0000 0001 原始数a
//c = 1000 0000 0000 0000 左移15位的结果
//c是原码的形式。
//在内存中的反码是 : 1111 1111 1111 1111
// 补码是反码加一 : 0001 0000 0000 0000 0000
//但由于定义的是short int只有2字节。
//所以补码是 : 0000 0000 0000 0000
// 反码是 : 1111 1111 1111 1110
// 原码是 : 1000 0000 0000 0000
// 输出的是原码算上符号位应该输出的是十进制的-0.
// 还是没解决下次在更新吧