|
|
|
@ -8,51 +8,6 @@ |
|
|
|
|
#define DOUBLE_MAX_LENGTH 6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace std { |
|
|
|
|
string to_string(int val) { |
|
|
|
|
char buf[20]; |
|
|
|
|
sprintf(buf, "%d", val); |
|
|
|
|
return string(buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
string to_string(unsigned val) { |
|
|
|
|
char buf[20]; |
|
|
|
|
sprintf(buf, "%u", val); |
|
|
|
|
return string(buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
string to_string(long val) { |
|
|
|
|
char buf[20]; |
|
|
|
|
sprintf(buf, "%ld", val); |
|
|
|
|
return string(buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
string to_string(unsigned long val) { |
|
|
|
|
char buf[20]; |
|
|
|
|
sprintf(buf, "%lu", val); |
|
|
|
|
return string(buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
string to_string(float val) { |
|
|
|
|
char buf[200]; |
|
|
|
|
sprintf(buf, "%f", val); |
|
|
|
|
return string(buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
string to_string(double val) { |
|
|
|
|
char buf[2000]; |
|
|
|
|
sprintf(buf, "%f", val); |
|
|
|
|
return string(buf); |
|
|
|
|
} |
|
|
|
|
string to_string(long double val) { |
|
|
|
|
char buf[20000]; |
|
|
|
|
sprintf(buf, "%Lf", val); |
|
|
|
|
return string(buf); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using namespace std; |
|
|
|
|
|
|
|
|
|
#define __method_2 |
|
|
|
@ -125,34 +80,117 @@ bool same_vec(vector<int> a, vector<int> b){ |
|
|
|
|
class Fraction { |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
Fraction(int top = 0, int bottom = 1); |
|
|
|
|
/* 默认构造 */ |
|
|
|
|
Fraction(){ |
|
|
|
|
ini(); |
|
|
|
|
_bottom = 1; |
|
|
|
|
}; |
|
|
|
|
/* 分子,分母输入构造 */ |
|
|
|
|
Fraction(int top, int bottom){ |
|
|
|
|
set(top, bottom); |
|
|
|
|
}; |
|
|
|
|
/* 小数输入构造 */ |
|
|
|
|
Fraction(double d){ |
|
|
|
|
set(d); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/* 拷贝构造 */ |
|
|
|
|
Fraction(const Fraction& obj){ |
|
|
|
|
set(obj.top(), obj.bottom()); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/* 析构 */ |
|
|
|
|
~Fraction(){}; |
|
|
|
|
|
|
|
|
|
/* 加法重载 */ |
|
|
|
|
Fraction operator+(const Fraction& obj){ |
|
|
|
|
Fraction f(this->top() * obj.bottom() + this->bottom() * obj.top(), this->bottom() * obj.bottom()); |
|
|
|
|
return f; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline void set(int top = 0, int bottom = 1){ |
|
|
|
|
ini(); |
|
|
|
|
adjust_minus(top, bottom); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline void set(double d = 0){ |
|
|
|
|
ini(); |
|
|
|
|
is_double_negative(d); |
|
|
|
|
|
|
|
|
|
if(get_long_int_length(get_double_decimals_part(d)) > 3) repeated_decimal_to_fraction(d); |
|
|
|
|
|
|
|
|
|
if(_bottom == 0) dec_to_frac_direct(d); |
|
|
|
|
|
|
|
|
|
simplify(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 提取小数结果 */ |
|
|
|
|
inline double val() const{ |
|
|
|
|
return (double)_top/_bottom; |
|
|
|
|
return (double)_top / _bottom * ((_isNegative) ? -1 : 1); |
|
|
|
|
} |
|
|
|
|
/* 提取string形式分数结果 */ |
|
|
|
|
inline string toStr(){ |
|
|
|
|
simplify(); |
|
|
|
|
stringstream ss; |
|
|
|
|
ss << _top << "/" << _bottom; |
|
|
|
|
ss << ((_isNegative) ? "-" : "") << _top << "/" << _bottom; |
|
|
|
|
return ss.str(); |
|
|
|
|
}; |
|
|
|
|
/* 提取分子 */ |
|
|
|
|
inline int top() const{ |
|
|
|
|
return ((_isNegative) ? -1 : 1) * (int) _top; |
|
|
|
|
} |
|
|
|
|
/* 提取分母 */ |
|
|
|
|
inline int bottom() const{ |
|
|
|
|
return (int)_bottom; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
int _top; |
|
|
|
|
int _bottom; |
|
|
|
|
void _check(){ |
|
|
|
|
/* 主要变量 */ |
|
|
|
|
unsigned int _top; |
|
|
|
|
unsigned int _bottom; |
|
|
|
|
bool _isNegative; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 初始化 */ |
|
|
|
|
inline void ini(){ |
|
|
|
|
_top = 0; |
|
|
|
|
_bottom = 0; |
|
|
|
|
_isNegative = false; |
|
|
|
|
} |
|
|
|
|
inline void adjust_minus(){ |
|
|
|
|
if(_bottom < 0){ |
|
|
|
|
_top *= -1; |
|
|
|
|
_bottom *= -1; |
|
|
|
|
|
|
|
|
|
/* 处理负号 */ |
|
|
|
|
inline void adjust_minus(int top, int bottom){ |
|
|
|
|
if(top < 0 && bottom < 0){ |
|
|
|
|
_isNegative = false; |
|
|
|
|
_top = -1 * top; |
|
|
|
|
_bottom = -1 * bottom; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if(bottom < 0){ |
|
|
|
|
_isNegative = true; |
|
|
|
|
_top = top; |
|
|
|
|
_bottom = -1 * bottom; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if(top < 0){ |
|
|
|
|
_isNegative = true; |
|
|
|
|
_top = (-1 * top); |
|
|
|
|
_bottom = bottom; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
_top = top; |
|
|
|
|
_bottom = bottom; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 处理分母为0 */ |
|
|
|
|
inline void is_bottom_zero() const{ |
|
|
|
|
if(_bottom == 0){ |
|
|
|
|
throw "Division by zero condition!"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 通分,找最大公约数 */ |
|
|
|
|
int get_common_divisor() const; |
|
|
|
|
inline void simplify(){ |
|
|
|
|
int t_divisor = get_common_divisor(); |
|
|
|
@ -161,16 +199,69 @@ class Fraction { |
|
|
|
|
_bottom /= t_divisor; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 针对double处理负号 */ |
|
|
|
|
inline void is_double_negative(double& d){ |
|
|
|
|
if(d < 0){ |
|
|
|
|
d *= -1; |
|
|
|
|
_isNegative = true; |
|
|
|
|
}else{ |
|
|
|
|
_isNegative = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 小数强制转分数 */ |
|
|
|
|
void dec_to_frac_direct(double d); |
|
|
|
|
|
|
|
|
|
/* 无限循环小数转分数 - 补丁 */ |
|
|
|
|
unsigned long int transfer_double_decimals_to_unsigned_long_int_for_single(const double& d); |
|
|
|
|
|
|
|
|
|
/* 转换double小数部分到长整型 */ |
|
|
|
|
unsigned long int transfer_double_decimals_to_unsigned_long_int(const double& d); |
|
|
|
|
|
|
|
|
|
/* 获取double小数整数部分 */ |
|
|
|
|
inline unsigned long int get_double_integer_part(const double& d){ |
|
|
|
|
return (unsigned long int)floor(fabs(d)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 获取double小数部分 */ |
|
|
|
|
inline unsigned long int get_double_decimals_part(const double& d){ |
|
|
|
|
double t; |
|
|
|
|
return transfer_double_decimals_to_unsigned_long_int(fabs(d) - floor(fabs(d))); |
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 获取小数部分的某一位 */ |
|
|
|
|
inline unsigned short get_one_decimal(const unsigned long int& t, unsigned short point){ |
|
|
|
|
return (t / (unsigned int)pow(10, point - 1)) % 10; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 获取 int 长度 */ |
|
|
|
|
unsigned short get_long_int_length(long int t); |
|
|
|
|
|
|
|
|
|
/* 获取循环小数循环体 */ |
|
|
|
|
unsigned int get_repeat_part(const unsigned long int& t); |
|
|
|
|
|
|
|
|
|
/* 检查循环体顺序 */ |
|
|
|
|
void confirm_repeat_part(const unsigned long int& t, unsigned int& repeat, unsigned short& start); |
|
|
|
|
|
|
|
|
|
/* 循环小数转分数 */ |
|
|
|
|
void repeated_decimal_to_fraction(double d); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fraction::Fraction(const int top, const int bottom) |
|
|
|
|
|
|
|
|
|
void Fraction::dec_to_frac_direct(double d) |
|
|
|
|
{ |
|
|
|
|
_top = top; |
|
|
|
|
_bottom = bottom; |
|
|
|
|
unsigned short t = get_long_int_length(get_double_decimals_part(d)); |
|
|
|
|
|
|
|
|
|
_top = d * (int)pow(10, t); |
|
|
|
|
_bottom = (unsigned int)pow(10, t); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Fraction::get_common_divisor() const |
|
|
|
|
{ |
|
|
|
|
int t_top = _top; |
|
|
|
@ -196,7 +287,7 @@ int Fraction::get_common_divisor() const |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned long int transfer_double_decimals_to_unsigned_long_int_for_single(const double& d) |
|
|
|
|
unsigned long int Fraction::transfer_double_decimals_to_unsigned_long_int_for_single(const double& d) |
|
|
|
|
{ |
|
|
|
|
if(d > 0.09999999999 && d < 0.100000000001) return 1; |
|
|
|
|
if(d > 0.19999999999 && d < 0.200000000001) return 2; |
|
|
|
@ -211,7 +302,7 @@ unsigned long int transfer_double_decimals_to_unsigned_long_int_for_single(const |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned long int transfer_double_decimals_to_unsigned_long_int(const double& d) |
|
|
|
|
unsigned long int Fraction::transfer_double_decimals_to_unsigned_long_int(const double& d) |
|
|
|
|
{ |
|
|
|
|
if(transfer_double_decimals_to_unsigned_long_int_for_single(d)) return transfer_double_decimals_to_unsigned_long_int_for_single(d); |
|
|
|
|
|
|
|
|
@ -225,29 +316,7 @@ unsigned long int transfer_double_decimals_to_unsigned_long_int(const double& d) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline unsigned long int get_double_decimals_part(const double& d) |
|
|
|
|
{ |
|
|
|
|
double t; |
|
|
|
|
return transfer_double_decimals_to_unsigned_long_int(fabs(d) - floor(fabs(d))); |
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline unsigned long int get_double_integer_part(const double& d) |
|
|
|
|
{ |
|
|
|
|
return (unsigned long int)floor(fabs(d)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline bool get_double_is_negative(const double& d) |
|
|
|
|
{ |
|
|
|
|
return (d < 0)? true : false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline unsigned short get_one_decimal(const unsigned long int& t, unsigned short point) |
|
|
|
|
{ |
|
|
|
|
return (t / (unsigned int)pow(10, point - 1)) % 10; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unsigned short get_long_int_length(long int t) |
|
|
|
|
unsigned short Fraction::get_long_int_length(long int t) |
|
|
|
|
{ |
|
|
|
|
int count = 0; |
|
|
|
|
while(t){ |
|
|
|
@ -260,7 +329,7 @@ unsigned short get_long_int_length(long int t) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int get_repeat_part(const unsigned long int& t) |
|
|
|
|
unsigned int Fraction::get_repeat_part(const unsigned long int& t) |
|
|
|
|
{ |
|
|
|
|
unsigned short i = 1; |
|
|
|
|
unsigned short len = get_long_int_length(t); |
|
|
|
@ -281,7 +350,7 @@ unsigned int get_repeat_part(const unsigned long int& t) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void confirm_repeat_part(const unsigned long int& t, unsigned int& repeat, unsigned short& start) |
|
|
|
|
void Fraction::confirm_repeat_part(const unsigned long int& t, unsigned int& repeat, unsigned short& start) |
|
|
|
|
{ |
|
|
|
|
unsigned short len = get_long_int_length(repeat); |
|
|
|
|
|
|
|
|
@ -303,8 +372,9 @@ void confirm_repeat_part(const unsigned long int& t, unsigned int& repeat, unsig |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void repeated_decimal_to_fraction(double d) |
|
|
|
|
void Fraction::repeated_decimal_to_fraction(double d) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
unsigned long int t = get_double_decimals_part(d); |
|
|
|
|
|
|
|
|
|
unsigned short start = 0; |
|
|
|
@ -329,6 +399,8 @@ void repeated_decimal_to_fraction(double d) |
|
|
|
|
|
|
|
|
|
up = t % (unsigned int)pow(10, get_long_int_length(repeat)); |
|
|
|
|
|
|
|
|
|
up = up + get_double_integer_part(d) * down; |
|
|
|
|
|
|
|
|
|
//cout << up << endl;
|
|
|
|
|
_top = up; |
|
|
|
|
_bottom = down; |
|
|
|
@ -344,18 +416,24 @@ int main() |
|
|
|
|
vector<int> b; |
|
|
|
|
b.push_back(2);b.push_back(4);b.push_back(3);b.push_back(5); |
|
|
|
|
|
|
|
|
|
Fraction f(5,20); |
|
|
|
|
Fraction f(-4,1); |
|
|
|
|
Fraction g(-4,1); |
|
|
|
|
Fraction k=f+g; |
|
|
|
|
|
|
|
|
|
Fraction l = f; |
|
|
|
|
|
|
|
|
|
double c; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// for(int i =0; i < a.size(); i++) cout << a[i] <<endl;
|
|
|
|
|
|
|
|
|
|
//try{
|
|
|
|
|
try{ |
|
|
|
|
cout << k.toStr() << endl; |
|
|
|
|
|
|
|
|
|
//repeated_decimal_to_fraction(2.666);
|
|
|
|
|
}catch(const char* msg){ |
|
|
|
|
cerr << msg << endl; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
repeated_decimal_to_fraction(2.666); |
|
|
|
|
//}catch(const char* msg){
|
|
|
|
|
// cerr << msg << endl;
|
|
|
|
|
//}
|
|
|
|
|
return 0; |
|
|
|
|
} |