小数转化分数

    这个算法的根本原理是:一个分数对应一条直线的斜率。用数学语言描述就是:一条直线的斜率是无穷大(垂直于X轴)或者是(Y2-Y1) / (X2-X1),我们要做的就是找到2个整数,在指定的精度范围内接近这个斜率。对于正数来说,我们设置分子为0,分母为1,然后比较这个分数同给定的十进制数。如果我们的分数太小了(比如,我们选择的点在直线的下面),我们就加大分子的值直到这个分数太大(比如,这个点在直线的上方),之后我们在增加分母的大小直到这个点在直线下方。如果我们的最终目标是无理数(无限不循环小数),这个算法将一直继续,增加分子和分母,直到最终结果在指定的精度上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdlib.h>
#include <iostream.h>
#include <math.h>
 
int main()
{
     int iDecimal;
     int iNumerator, iDenominator, iNegative;
     double dFraction, dDecimal, dAccuracy, dInteger;
     
     cout << "请输入你要转换的数:";
     cin >> dDecimal;
     
     iDecimal = (int)dDecimal; //取整数部分,以在下一步判断输入的是否为整数
     
     if(iDecimal == dDecimal)  //判断输入是否为整数,若是则直接输出
     {
          cout << dDecimal << endl;
          return 0;
     }
     
     if(abs(iDecimal) >= 1)  //如果输入大于等于1,则分解为整数部分和小数部分
     {
          dInteger = iDecimal;
          dDecimal = dDecimal - iDecimal;
     }
 
     dAccuracy = 0.0001; //设置精度
     iNumerator = 0;  //初始分子
     iDenominator = 1;  //初始分母
     iNegative = 1;  //负数标志
     if(iDecimal <0)
          iNegative = -1;
 
     dFraction = 0;
 
     while (fabs(dFraction - dDecimal) > dAccuracy)  //判断精度是否达到要求
     {
          if(fabs(dFraction) > fabs(dDecimal))
               iDenominator = iDenominator + 1;     //增加分母
          else
               iNumerator = iNumerator + iNegative;     //增加分子
          dFraction = (double)iNumerator / (double)iDenominator;     //计算新的分数
     }
     
 
     if (abs(iDecimal) >= 1)
      cout << dInteger << '+' << '(' << iNumerator << '/' << iDenominator << ')' << endl;
    else
      cout << iNumerator << '/' <<iDenominator << endl;
 
     return 0;
}

posted @ 2016-03-16 23:03  copperface  阅读(647)  评论(0编辑  收藏  举报