这个算法的根本原理是:一个分数对应一条直线的斜率。用数学语言描述就是:一条直线的斜率是无穷大(垂直于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;
} |