题目源自:http://www.cppblog.com/jake1036/archive/2011/07/10/150521.html
一问题描述:
使用分数形式来表示小数,有限小数和无限循环小数都可以转化为分数。
例如: 0.9 = 9 / 10 。
0.33333(3) = 1 / 3 。
二问题分析:
(1) 若是有限小数,则可以使用以下方法: 0.a1 a2 a3 a4 a5 ..an = a1 a2 a3 a4 a5 a6 an / 10 ^ n
(2) 下面主要考虑无限循环小数:
设 X = 0.a1 a2 a3 a4 a5 … an . b1 b2 b3 b4 … bm(b1 b2 b3 b4 … bm)
10 ^ n * X = a1 a2 a3 a4 a5 … an . b1 b2 b3 b4 … bm(b1 b2 b3 b4 … bm)
Y = 0. b1 b2 b3 b4 … bm(b1 b2 b3 b4 … bm)
10 ^ m * Y = b1 b2 b3 b4 … bm . (b1 b2 b3 b4 … bm)
10 ^ m * Y – Y = b1 b2 b3 b4 …bm
Y = b1 b2 b3 b4 … bm / (10 ^ m – 1)
则X =( (a1 a2 a3 a4 … an) * (10 ^ m -1 ) + b1 b2 b3 b4 …bm) / (10 ^ n)*(10 ^ m – 1)
(3)化简到最后,分子分母可能会出现 不是最简的形式。 A / B ,则需要调用(A / gcd(A ,B)) / (B / gcd(A , B)) ,即已经化简完毕。
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
uint64_t gcd(uint64_t x, uint64_t y)
{
if(x<y) return gcd(y,x);
if(y==0) return x;
else
return gcd(x-y, y);
}
void tran(const string s)
{
int i=0;
while(s[i] != '(') i++;
string a = s.substr(2,i);
int ca = i-2;
i++;
int begin = i;
while(s[i] != ')') i++;
string b = s.substr(begin, i);
int cb = i-begin;
uint64_t na = atoi(a.c_str());
uint64_t nb = atoi(b.c_str());
na = na*(uint64_t)(pow(10.0, cb)-1)+nb;
nb = (uint64_t)(pow(10.0,cb)-1)*(uint64_t)pow(10.0,ca);
cout<<na<<"/"<<nb<<endl;
cout<<(na/gcd(na,nb))<<"/"<<(nb/gcd(na, nb))<<endl;
}
int main()
{
string a="0.285714(285714)";
tran(a);
system("pause");
return 0;
}