1. 程式人生 > >POJ NOI0113-03 八進位制小數(Bailian2765)

POJ NOI0113-03 八進位制小數(Bailian2765)

總時間限制:
1000ms
記憶體限制:
65536kB
描述

八進位制有限小數均可以用十進位制有限小數精確地表示。比如,八進位制裡面的0.75等於十進位制裡面的0.963125 (7/8 + 5/64)。所有小數點後位數為n的八進位制小數都可以表示成小數點後位數不多於3n的十進位制小數。

你的任務是寫一個程式,把(0,1)之間的八進位制小數轉化成十進位制小數。

輸入
一行,包含一個八進位制小數。每個小數的形式是0.d1d2d3 ... dk,這裡di是八進位制數0...7,dk不等於0,而且已知0 < k < 15。
輸出
輸入如下形式的一行

0.d1d2d3...dk [8] = 0.D1D2D3...Dm [10]


這裡左邊是輸入的八進位制小數,右邊是相等的十進位制小數。輸出的小數末尾不能有0,也就是說Dm不等於0。注意空格位置。
樣例輸入
0.75
樣例輸出
0.75 [8] = 0.953125 [10]
來源
翻譯自 Southern African 2001 的試題

問題分析

這是一個小數部分進位制轉換問題,是一種套路,需要根據進位制原理進行計算。

  有關進位制轉換,分為兩種情況,一是整數進位制轉換,二是小數進位制轉換。一個數如果既有整數又有小數,那麼要進行進位制轉換,則需要分別轉換然後在合起來。整數進位制轉換可以參照函式itoa()的原理實現。

程式說明

  (略)。


AC的C++語言程式:

/* Uvalive2245 POJ1131 HDU1376 ZOJ1086 Octal Fractions */

#include <iostream>
#include <cstring>

using namespace std;

const int BASE10 = 10;
const int BASE8 = 8;
const int MAXN = 1024;

char s[MAXN];
int ans[MAXN];

int main(void)
{
    int len, digit, t, j, k;

    while(cin >> s) {
        memset(ans, 0, sizeof(ans));

        t = 0;
        len = strlen(s);
        for(int i=len-1; i>1; i--) {
            digit = s[i] - '0';
            j = 0;
            k = 0;
            while(j<t || digit) {
                digit = digit * BASE10 + ans[j++];
                ans[k++] = digit / BASE8;
                digit %= BASE8;
            }
            t = k;
        }

        cout<< s << " [" << BASE8 << "] = 0." ;
        for(int i=0; i<t; i++)
            cout << ans[i];
        cout << " [" << BASE10 << "]" << endl;
    }

    return 0;
}