《编程思维与实践》1015.八进制小数

《编程思维与实践》1015.八进制小数

题目

在这里插入图片描述

思路

进制转换(迭代)加高精度(数组存储)问题.

1. N = k n ⋅ 8 − 1 + k n − 1 ⋅ 8 − 2 + . . . + k 0 ⋅ 8 − n = k n + ( k n − 1 ⋅ 8 − 1 + . . . + k 0 ⋅ 8 − n + 1 ) ⋅ 8 − 1 N=k_n·8^{-1}+k_{n-1}·8^{-2}+...+k_0·8^{-n}=k_n+(k_{n-1}·8^{-1}+...+k_0·8^{-n+1})·8^{-1} N=kn81+kn182+...+k08n=kn+(kn181+...+k08n+1)81

可以采用迭代,如八进制数 0.75 = ( 7 + ( 5 ⋅ 8 − 1 ) ) ⋅ 8 − 1 0.75=(7+(5·8^{-1}))·8^{-1} 0.75=(7+(581))81 (注意是逆向迭代).

2.高精度是因为保留的位数可能超过double的范围,需要人为操作计算每次/8的值,

模仿笔除: 1/8=0余1,不足补0即1·10/8=1余2,2·10/8=2余4,4·10/8=5余0,所以1/8=0.125.

在这里插入图片描述

注意的点:

1.在通过循环模拟笔除时退出循环的条件不仅仅是余数为0(有可能还有下一位,如0.321/8)!应为长度为小数位数*3+1.

2.如果循环条件为长度为小数位数*3+1时,则结果有可能含有后置0,输出时需要注意去除.

代码

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

int main()
{
	int T;
	scanf("%d",&T);
	for(int i=0;i<T;i++)
	{
        char s[100];
		int result[200]={0};  //实现高精度存储
		scanf("%s",s);
		int k;
		for(int j=strlen(s)-1;j>1;j--)  //j=1时s[j]为小数点,逆向
		{
			k=0;
			int mod=0;  //记录余数
			result[k]+=s[j]-'0';   //每一位均小于8,所以做完除法后第一位都会变为0
			do{
				int temp=mod*10+result[k];     //余数*10+下一位
				result[k]=temp/8;  //更新得到的商
				mod=temp%8;   //更新余数
				k++;  
			}while(k<=3*(strlen(s)-2));   //循环条件 长度为小数位数*3+1 strlen(s)-2表示减去小数点和前置0
		}
        
		int m=k-1;
		while(result[m]==0)   //去除后置0 
		{
			m--;
		}

		printf("case #%d:\n",i);
		
		for(int j=0;j<=m;j++)
		{
			printf("%d",result[j]);
			if(j==0)
			{
				printf(".");
			}
		}
		printf("\n");		
	} 
	return 0;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值