编程之美--精确表达浮点数

题目源自: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;
}
 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值