题目大意:
八进制小数部分可以精确地表示成十进制小数,例如0.75(8) = 0.963125(10),方法是累除法:(7/8 + 5/8^2) = (5/8 + 7)/8,由于0~7除以8都是可以除尽的,因此八进制小数可以精确地表示成十进制小数,还有就是如果八进制小数部分的长度为n的话,那么等价的十进制小数部分长度不超过3n。
现要求写一个程序来计算0~1之间八进制小数的等价十进制形式,现有多个测例(测例数无上限),每行给出一个八进制小数(长度没有限制,可以很长,因此要用数组存),对于每行的八进制小数都要输出一个相应的十进制小数,而且一定要完全地精确,最后一位之后不能有0。
注释代码:
/*
* Problem ID : POJ 1131 Octal Fractions
* Author : Lirx.t.Una
* Language : C
* Run Time : 0 ms
* Run Memory : 156 KB
*/
#include <string.h>
#include <stdio.h>
//小数的可能最大位数(包括0.)
#define MAXN 50
char oct[MAXN];//octal,八进制小数
char dec[MAXN];//decimal,十进制小数
int
main() {
int dl;//length of decimal number,十进制数的当前长度
int num;//获取八进制小数的每一位数
int tmp;//临时变量
int i, j;//计数变量
while ( ~scanf("%s", oct) ) {
dl = 0;//每个测例开始现将十进制当前长度初始化为0
for ( i = strlen(oct) - 1; i > 1; i-- ) {//从后往前截取八进制小数每一位
//不包括0.这里两个符号!!
num = oct[i] - '0';//得到数字
for ( j = 0; j < dl || num; j++ ) {//高精度除法
//j指针从dec的头部开始检测
//目标是将num.dec用8除尽
//编程.xxxxxx的形式
tmp = num * 10 + ( j < dl ? dec[j] - '0' : 0 );//将dec中的数不断累加进来
dec[j] = tmp / 8 + '0';//将结果覆盖
//如果num不为0表示未除尽,需要在下一轮中放大再除
//可能会增长十进制数的长度
num = tmp % 8;
}
dl = j;
}
dec[j] = '\0';
printf("%s [8] = 0.%s [10]\n", oct, dec);
}
return 0;
}
无注释代码:
#include <string.h>
#include <stdio.h>
#define MAXN 50
char oct[MAXN];
char dec[MAXN];
int
main() {
int dl;
int num;
int tmp;
int i, j;
while ( ~scanf("%s", oct) ) {
dl = 0;
for ( i = strlen(oct) - 1; i > 1; i-- ) {
num = oct[i] - '0';
for ( j = 0; j < dl || num; j++ ) {
tmp = num * 10 + ( j < dl ? dec[j] - '0' : 0 );
dec[j] = tmp / 8 + '0';
num = tmp % 8;
}
dl = j;
}
dec[j] = '\0';
printf("%s [8] = 0.%s [10]\n", oct, dec);
}
return 0;
}
单词解释:
fraction:n, 分数部分(小数部分)
octal:adj, 八进制的
notation:n, 符号,乐谱
numeral:n, 数字; adj, 数字的
trailing:adj, 后面的,拖在尾巴后面的