[編程之美] 2.6 精確表達浮點數

問題是將一個小數表示成一個分數。當然,只有有限小數和無限循環小數才能轉換爲分數。

對於無限循環小數,給定的格式是將循環節用括號括起來,比如:0.3333(3333)。

書中先只考慮了0到1的純小數,然後分有限小數和無限循環小數討論,書上講的已經很好理解了,這裏就不贅述了,直接上代碼吧。

#include <iostream>
#include <string>
#include <cmath>
using namespace std;

typedef pair<unsigned long, pair<unsigned long, unsigned long> > decimal_type;

unsigned long gcd(unsigned long x, unsigned long y)
{
	return (!y) ? x : gcd(y, x % y);
}

unsigned int num_cnt(unsigned long data)
{
	unsigned int cnt = 0;
	while(data) {
		data /= 10;
		++cnt;
	}
	return cnt;
}

pair<unsigned long, unsigned long> transform_dot(decimal_type data)
{
	unsigned long numerator = 0, denominator = 0;
	unsigned long deci = 0, noncir = 0, cir = 0;
	deci = data.first;
	noncir = data.second.first;
	cir = data.second.second;
	if(cir == 0) {
		numerator = noncir;
		denominator = pow(10, num_cnt(noncir));
	}
	else {
		numerator = noncir * (pow(10, num_cnt(cir)) - 1) + cir;
		denominator = pow(10, num_cnt(noncir) + num_cnt(cir)) - pow(10, num_cnt(noncir));
	}
	unsigned long gcd_tmp = gcd(numerator, denominator);
	numerator /= gcd_tmp;
	denominator /= gcd_tmp;
	return make_pair(numerator, denominator);
}

decimal_type get_frac()
{
	unsigned long i = 0, j = 0, k = 0;
	char ch = 0;
	while(cin >> ch && ch != '.') {
		i = i * 10 + ch - '0';
	}
	while(cin >> ch && ch != '(') {
		j = j * 10 + ch -'0';
	}
	if(ch == '(') {
		while(cin >> ch && ch != ')') {
			k = k * 10 + ch -'0';
		}
	}
	return make_pair(i, make_pair(j, k));
}

int main()
{
	decimal_type data = get_frac();
	cout << data.first << "." << data.second.first;
	if(data.second.second) {
		cout << "(" << data.second.second << ")" << endl;
	}
	pair<unsigned long, unsigned long> fraction = transform_dot(data);
	cout << " = " << fraction.first << " / " << fraction.second << endl;

	return 0;
}

執行結果:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章