读程序

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.

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.

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++语言程序如下:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /* UVALive2245 POJ1131 HDU1376 ZOJ1086 */  
  2.   
  3. #include <iostream>  
  4. #include <cstring>  
  5.   
  6. using namespace std;  
  7.   
  8. const int BASE10 = 10;  
  9. const int BASE8 = 8;  
  10. const int MAXN = 1024;  
  11.   
  12. char s[MAXN];     //存放输入的8进制小数
  13. int ans[MAXN];    ////存放输出的10进制小数
  14.   
  15. int main(void)  
  16. {  
  17.     int len, digit, t, j, k;  
  18.   
  19.     while(cin >> s) {  
  20.         memset(ans, 0, sizeof(ans));  
  21.   
  22.         t = 0;  
  23.         len = strlen(s);    //1.求出输入的8进制小数位数
  24.         for(int i=len-1; i>1; i--) {  //从8进制小数的最后开始向前一位一位的遍历
  25.             digit = s[i] - '0';    
  26.             j = 0;  
  27.             k = 0;  
  28.             while(j<t || digit) {  
  29.                 digit = digit * BASE10 + ans[j++];  
  30.                 ans[k++] = digit / BASE8;  
  31.                 digit %= BASE8;  
  32.             }  
  33.             t = k;  
  34.         }  
  35.   
  36.         cout<< s << " [" << BASE8 << "] = 0." ;  
  37.         for(int i=0; i<t; i++)  
  38.             cout << ans[i];  
  39.         cout << " [" << BASE10 << "]" << endl;  
  40.     }  
  41.   
  42.     return 0;  
  43. }  
问题分析:
就此问题而言,就是如何将8进制的小数转换为10进制的小数。
原理如下:

就代码中使用的方法而言原理为:
代码分析:

  1.     while(cin >> s) {    //1.将8进制小数以字符数组的形式输入
  2.         memset(ans, 0, sizeof(ans));   //将数组ans清零
  3.   
  4.         t = 0;  
  5.         len = strlen(s);    //求出输入的8进制小数位数
  6.         for(int i=len-1; i>1; i--) {  //从8进制小数的最后开始向前一位一位的遍历
  7.             digit = s[i] - '0';    //字符转换为数字
  8.             j = 0;  
  9.             k = 0;  
  10.             while(j<t || digit) {  //对于遍历到的每一位小数,求出digit/8的每一位存放在ans[]中
  11.                 digit = digit * BASE10 + ans[j++];  
  12.                 ans[k++] = digit / BASE8;  
  13.                 digit %= BASE8;  
  14.             }  
  15.             t = k;  
  16.         }  
程序运行过程:举例: s= 0.75
遍历到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的各位小数。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值