[编程之美] 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;
}

执行结果:



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