C语言的移位

#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.
	// 还是没解决下次在更新吧

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值