Octal Fractions
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 7248 | Accepted: 3988 |
Description
Fractions in octal (base 8) notation can be expressed exactly in decimal notation. For example, 0.75 in octal is 0.953125 (7/8 + 5/64) in decimal. All octal numbers of n digits to the right of the octal point can be expressed in no more than 3n decimal digits to the right of the decimal point.
Write a program to convert octal numerals between 0 and 1, inclusive, into equivalent decimal numerals.
Write a program to convert octal numerals between 0 and 1, inclusive, into equivalent decimal numerals.
Input
The input to your program will consist of octal numbers, one per line, to be converted. Each input number has the form 0.d1d2d3 ... dk, where the di are octal digits (0..7). There is no limit on k.
Output
Your output will consist of a sequence of lines of the form
0.d1d2d3 ... dk [8] = 0.D1D2D3 ... Dm [10]
where the left side is the input (in octal), and the right hand side the decimal (base 10) equivalent. There must be no trailing zeros, i.e. Dm is not equal to 0.
where the left side is the input (in octal), and the right hand side the decimal (base 10) equivalent. There must be no trailing zeros, i.e. Dm is not equal to 0.
Sample Input
0.75 0.0001 0.01234567
Sample Output
0.75 [8] = 0.953125 [10] 0.0001 [8] = 0.000244140625 [10] 0.01234567 [8] = 0.020408093929290771484375 [10]
Source
原文链接:http://blog.csdn.net/tigerisland45/article/details/70233474
参考博文链接:http://blog.csdn.net/acdreamers/article/details/9037763
问题链接:UVALive2245 POJ1131 HDU1376 ZOJ1086 Octal Fractions。
问题简述:参见上述链接。
问题分析:这是一个小数部分进制转换问题,是一种套路,需要根据进制原理进行计算。
有关进制转换,分为两种情况,一是整数进制转换,二是小数进制转换。一个数如果既有整数又有小数,那么要进行进制转换,则需要分别转换然后在合起来。整数进制转换可以参照函数itoa()的原理实现。
程序说明:(略)。
AC的C++语言程序如下:
问题分析:
就此问题而言,就是如何将8进制的小数转换为10进制的小数。
原理如下:
就代码中使用的方法而言原理为:
代码分析:
- while(cin >> s) { //1.将8进制小数以字符数组的形式输入
- memset(ans, 0, sizeof(ans)); //将数组ans清零
- t = 0;
- len = strlen(s); //求出输入的8进制小数位数
- for(int i=len-1; i>1; i--) { //从8进制小数的最后开始向前一位一位的遍历
- digit = s[i] - '0'; //字符转换为数字
- j = 0;
- k = 0;
- while(j<t || digit) { //对于遍历到的每一位小数,求出digit/8的每一位存放在ans[]中
- digit = digit * BASE10 + ans[j++];
- ans[k++] = digit / BASE8;
- digit %= BASE8;
- }
- t = k;
- }
遍历到5:
50/8=6 ;
50%8=2; 20/8=2;
20%8=4; 40/8=5; 40%8=0; 因此求得5/8=0.625,依次存放在ans[]中
遍历到7:
同理求得 7/8=0.875;
但在除时
digit = digit * BASE10 + ans[j++]; ans[j++]即为之前数字求得的相应小数位的值。完成了如下午所示的加法。
即7的过程变为:
(70+6)/8=9; (70+6)%8=4; (40+2)/8=5; (40+2)%8=2; (20+5)/8=3; (20+5)%8=1; (10+0)/8=1; (10+0)%8=2;
(20+0)/8=2; (20+0)%8=4; (40+0)/8=5; (40+0)%8=0; 结束
for
(
int
i=len-1; i>1; i--) 结束,即最终的 结果为0.953125.
while(j<t || digit)中,t表示上一个数字求出的小数位个数,j等于当前小数求出的小数位个数。当j<t,说明当前小数求出的小数位个数<上一个数字求出的小数位个数,此时因为上一个数的小数任然有值,因此要计算其/8的结果。digit即为数除8后剩余的余数。
只有在当前余数为0,且上一次除下小数的结果位数没有超过当前小数位数,即上一次结果中小数都已经在前面除过了,此时后面位小数全为0,此时就结束当前小数的除,进入下一位数的求除8的各位小数。