《编程思维与实践》1010.i-1进制I

《编程思维与实践》1010.i-1进制I

题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路

将输入的十六进制数转化成二进制(利用字符串处理),

注意到 a + b i = k n ( − 1 + i ) n + k n − 1 ( − 1 + i ) n − 1 + . . . + k 0 a+bi=k_n(-1+i)^n+k_{n-1}(-1+i)^{n-1}+...+k_0 a+bi=kn(1+i)n+kn1(1+i)n1+...+k0 , 故也考虑用迭代处理.

p n + q n i = ( − 1 + i ) ⋅ ( p n − 1 + q n − 1 i ) + r n − 1 = r n − 1 − ( p n − 1 + q n − 1 ) + ( p n − 1 − q n − 1 ) i p_n+q_ni=(-1+i)·(p_{n-1}+q_{n-1}i)+r_{n-1}=r_{n-1}-(p_{n-1}+q_{n-1})+(p_{n-1}-q_{n-1})i pn+qni=(1+i)(pn1+qn1i)+rn1=rn1(pn1+qn1)+(pn1qn1)i
{ p n = r n − 1 − ( p n − 1 + q n − 1 ) p 0 = 0 , r 0 = k n q n = p n − 1 − q n − 1 q 0 = 0 \left\{ \begin{aligned} \quad p_n=r_{n-1}-(p_{n-1}+q_{n-1}) \quad p_0=0,r_0=k_n\\ q_n=p_{n-1}-q_{n-1} \quad q_0=0 \end{aligned} \right. {pn=rn1(pn1+qn1)p0=0,r0=knqn=pn1qn1q0=0

注意的点:

1.十六进制转二进制时不能先将十六进制转十进制后再转成二进制,因为十六进制数对应的十进制数可能很大(超过long long范围),

十六进制转二进制时,每一位拆成四个二进制位,可通过&位运算实现,

但考虑到与左移后的1做&位运算来计算对应的二进制数时存储时倒序的,故可采用与逻辑右移后的1000做&位运算的方式存储.

2.a和b的类型应为long long.

代码

#include<stdio.h>
#include<string.h>

int main()
{
	getchar();
	getchar();
	char s[100];  //将16进制变为2进制
	scanf("%s",s);

	char bit[1000];
	int j=0;
 	for(int i=0;i<strlen(s);i++)  
    {
        int d;
        if(s[i]>='A') d=s[i]-'A'+10;
        else d=s[i]-'0';
        unsigned int flag=0x8;   //0x8对应的二进制为1000  右移可以顺序存储每一位
        while(flag)
        {
            if(d&flag) bit[j++]='1';
            else bit[j++]='0';
            flag=flag>>1;
        }
    }  
    bit[j]='\0';
	
	//迭代计算a,b 利用循环
	
	long long a,b;
	long long p=0,q=0;
	for(int i=0;i<strlen(bit);i++)
	{
		b=p-q;
		a=(bit[i]-'0')-(p+q);
		p=a;
		q=b;
	} 
    
    //控制输出

	if(b==0)  //没虚部
	{
		printf("%lld",a);  //无论a是否为0由于没有虚部都必须输出
	}
    else
    {
        if(a!=0)//没实部不输出,有实部才输出
        {
        	printf("%lld",a); 
            if(b>0)
            {
                printf("+");
            }
        }
        if(b==1)
        {
    		printf("i");        
        }
        else if(b==-1)
        {
            printf("-i");
        }
        else{
            printf("%lldi",b);
        }
    }
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值