欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

蓝桥杯 输出二进制表示

程序员文章站 2022-07-14 23:17:24
...

蓝桥杯 输出二进制表示

问题描述
  输入[-128,127]内的整数,输出其二进制表示。提示,可使用按位与&
输入格式
  例:7
输出格式
  例:00000111

操作
对于位于区间 [0,127] 的整数,直接求其二进制数,对于位于区间 [128,0) 的整数,负数需用他的二进制补码表示,先求其反码,然后在反码末尾加1 (在原码基础上,每位取反,末尾加一)。但这样的操作有点复杂,但是我们会发现,该负数加上128,就和正数的二进制一样,将其符号位变为1。

原码、反码、补码
计算机巧妙地把符号位参与运算, 并且将减法变成了加法, 背后蕴含了怎样的数学原理呢?
将钟表想象成是一个1位的12进制数. 如果当前时间是6点, 我希望将时间设置成4点, 需要怎么做呢?我们可以:

  1. 往回拨2个小时: 6 - 2 = 4
  2. 往前拨10个小时: (6 + 10) mod 12 = 4
  3. 往前拨10+12=22个小时: (6+22) mod 12 =4
    2,3方法中的mod是指取模操作, 16 mod 12 =4 即用16除以12后的余数是4.

同余的概念

两个整数a,b,若它们除以整数m所得的余数相等,则称a,b对于模m同余
记作 a ≡ b (mod m)
读作 a 与 b 关于模 m 同余。
举例说明:
4 mod 12 = 4
16 mod 12 = 4
28 mod 12 = 4
所以4, 16, 28关于模 12 同余.

负数取模

正数进行mod运算是很简单的. 但是负数呢?
下面是关于mod运算的数学定义:
蓝桥杯 输出二进制表示
上面是截图, "取下界"符号找不到如何输入(word中粘贴过来后乱码). 下面是使用"L"和"J"替换上图的"取下界"符号:
x mod y = x - y L x / y J
上面公式的意思是:
x mod y等于 x 减去 y 乘上 x与y的商的下界.
以 -3 mod 2 举例:
-3 mod 2
= -3 - 2xL -3/2 J
= -3 - 2xL-1.5J
= -3 - 2x(-2)
= -3 + 4 = 1
所以:
(-2) mod 12 = 12-2=10
再根据上述时钟的问题可以得到
10 mod 12 = 10
所以 -2 和 10 是同余的。

在二进制中
2-1=2+(-1) = [0000 0010]原 + [1000 0001]原 = [0000 0010]补 + [1111 1111]补
如果把[1111 1111]当成原码, 去除符号位, 则:
[0111 1111]原 = 127
其实, 在反码的基础上+1, 只是相当于增加了模的值:
(-1) mod 128 = 127
127 mod 128 = 127
2-1 ≡ 2+127 (mod 128)
此时, 表盘相当于每128个刻度转一轮. 所以用补码表示的运算结果最小值和最大值应该是[-128, 128].
但是由于0的特殊情况, 没有办法表示128, 所以补码的取值范围是[-128, 127]

#include<stdio.h>

void Binary(int n);

int main()
{
	int n;
	scanf("%d",&n);
	Binary(n);
	return 0;
}

void Binary(int n)
{
	int i,j,k;
	int a[8];
	if(n>=0)     // if(n>=0 && n<=127)
	{
		for(i=7;i>=0;i--)
		{
			a[i]=n%2;
			n=n/2;
		}
	}
	else        //else if(n>=-128 && n<0)
	{
		n=n+128;
		for(j=7;j>=0;j--)
		{
			a[j]=(n%2);
			n=n/2;
		}
		a[0]=1;    // 最高位为符号位1,符号位正数为0,负数为1
	}
	for(k=0;k<8;k++)
	{
		printf("%d",a[k]);
	}
}

若代码有错误的地方或是其他代码,请各位指教。