00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "Fraction.h"
00033 #include <map>
00034 #include <iostream>
00035
00036 namespace Modelib {
00037
00038 using namespace std;
00039
00044 FractionConvert::FractionConvert(unsigned _n)
00045 {
00046 map<float,Fraction> tmp;
00047 map<float,Fraction>::iterator trouve;
00048 for(unsigned i = 0; i <_n; ++i)
00049 {
00050 for(unsigned j = 0; j <i; ++j)
00051 {
00052 trouve = tmp.find(float(j)/float(i));
00053 if( trouve == tmp.end() )
00054 tmp[float(j)/float(i)] = Fraction(j,i);
00055 else if( trouve->second.num > i )
00056 trouve->second = Fraction(j,i);
00057 }
00058 }
00059 nfrac = tmp.size();
00060 frac = new Fraction[nfrac];
00061 reel = new float[nfrac];
00062
00063 unsigned i =0;
00064 for(trouve = tmp.begin(); trouve != tmp.end(); ++trouve)
00065 {
00066 reel[i] = trouve->first;
00067 frac[i] = trouve->second;
00068 ++i;
00069 }
00070 }
00071
00075 FractionConvert::~FractionConvert()
00076 {
00077 delete [] frac;
00078 delete [] reel;
00079 }
00080
00081
00090 bool FractionConvert::Approx(float nb, int & num, unsigned & den) const
00091 {
00092 unsigned a = 0,b=nfrac-1;
00093 if(nb==0.0)
00094 {
00095 num = 0;
00096 den = 1;
00097 return false;
00098 }
00099
00100 while(a<b)
00101 {
00102 unsigned mil = (a+b)/2;
00103 if(reel[mil] < nb)
00104 a = mil + 1;
00105 else
00106 b = mil;
00107 }
00108 if(a < nfrac)
00109 {
00110 if( reel[a]-nb >= nb - reel[a-1] )
00111 a--;
00112 num = frac[a].num;
00113 den = frac[a].den;
00114 return true;
00115 }
00116 else
00117 return false;
00118 }
00119
00120 }