问题是将一个小数表示成一个分数。当然,只有有限小数和无限循环小数才能转换为分数。
对于无限循环小数,给定的格式是将循环节用括号括起来,比如: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; }
[编程之美] 2.6 精确表达浮点数,布布扣,bubuko.com
原文:http://blog.csdn.net/luofengmacheng/article/details/21040443