C++实现分数类

在几乎所有的语言中(至少我知道的语言都是这样),浮点数都是有精度丢失的。

C++实现分数类_第1张图片

C++实现分数类_第2张图片

怎么解决呢?

分数类就是解决办法之一。


        分数类采用分数的形式,保存了两个整数之比,确保了精度。

        分数类,肯定是要有约分、通分等函数和加、减、乘、除运算符的。(当然,要先实现求最大公因数和最小公倍数函数)这些都是基本数学知识。

        代码如下:

#ifndef FRACTION_H
#define FRACTION_H
#include
#include
using std::istream;
using std::ostream;
using std::getchar;
namespace math{
	template
	T gcd(T x,T y){
		if(x
	T lcm(T x,T y){
		return x/gcd(x,y)*y;
	} 
}
template  //T==int,long long,your big_int class ......
class fraction{
	private:
	T _up,_down;
	bool input_with_reduction,output_with_reduction,multi_optimize;
			//optimize指上界优化,即:以牺牲时间为代价换取不溢出 
	public:
	// constructors
	fraction(){
		_up=1,_down=1,input_with_reduction=output_with_reduction=1,multi_optimize=0;
	}
	fraction(T up,T down){
		_up=up,_down=down,input_with_reduction=output_with_reduction=1,multi_optimize=0;
		if(input_with_reduction) reduction();
	}
	fraction(bool optimize){
		_up=1,_down=1,input_with_reduction=output_with_reduction=1,multi_optimize=optimize;
	}
	fraction(T up,T down,bool optimize){
		_up=up,_down=down,input_with_reduction=output_with_reduction=1,multi_optimize=optimize;
		if(input_with_reduction) reduction();
	}
	fraction(bool input_reduct,bool output_reduct){
		_up=1,_down=1,input_with_reduction=input_reduct,output_with_reduction=output_reduct,
			multi_optimize=0;
	}
	fraction(T up,T down,bool input_reduct,bool output_reduct){
		_up=up,_down=down,input_with_reduction=input_reduct,output_with_reduction=output_reduct,
			multi_optimize=0;
		if(input_with_reduction) reduction();
	}
	fraction(bool input_reduct,bool output_reduct,bool optimize){
		_up=1,_down=1,input_with_reduction=input_reduct,output_with_reduction=output_reduct,
			multi_optimize=optimize;
	}
	fraction(T up,T down,bool input_reduct,bool output_reduct,bool optimize){
		_up=up,_down=down,input_with_reduction=input_reduct,output_with_reduction=output_reduct,
			multi_optimize=optimize;
		if(input_with_reduction) reduction();
	}
	// inputs
	friend istream& operator >> (istream& input,fraction& the_frac){
		if(the_frac.input_with_reduction) the_frac.reduction();
		input>>the_frac._up;
		getchar();
		input>>the_frac._down;
		return input;
	}
	fraction input_cin(bool with_reduction=1){
		if(with_reduction) reduction();
		using std::cin;
		cin>>_up;
		getchar();
		cin>>_down;
		return *this;
	}
	// outputs
	friend ostream& operator << (ostream& output,fraction the_frac){
		if(the_frac.output_with_reduction) the_frac.reduction();
		output< output_cout(bool with_reduction=1){
		if(with_reduction) reduction();
		using std::cout;
		cout<<_up<<'/'<<_down;
		return *this;
	}
	// basic_functions
	T up(){
		return _up;
	}
	T down(){
		return _down;
	}
	// (bool change)
	bool input_reduction(bool change_to){
		input_with_reduction=change_to;
		return change_to;
	}
	bool output_reduction(bool change_to){
		output_with_reduction=change_to;
		return change_to;
	}
	bool multi_optimize_change(bool change_to){
		multi_optimize=change_to;
		return change_to;
	}
	bool all_reduction(bool input_change_to,bool output_change_to){
		input_with_reduction=input_change_to,output_with_reduction=output_change_to;
		return input_change_to&&output_change_to;
	}
	bool all_bool_change(bool input_change_to,bool output_change_to,bool optimize_change_to){
		input_with_reduction=input_change_to,output_with_reduction=output_change_to,
			multi_optimize=optimize_change_to;
		return (input_change_to&&output_change_to)^optimize_change_to;
	}
	// (end of bool change)
	template
	Tans value()const{
		return Tans(_up)/Tans(_down);
	}
	fraction reduction(){  //约分 
		T gcd_result=math::gcd(_up,_down);
		_up/=gcd_result,_down/=gcd_result;
		return *this;
	}
	fraction reciprocal(bool with_reduction=1)const{
		return fraction(_down,_up,with_reduction,1);
	}
	template
	static void common(fraction &frac_x,fraction &frac_y){  //通分 
		T gcd_num=math::gcd(frac_x._down,frac_y._down);
		T1 x_multi_num=frac_y._down/gcd_num,y_multi_num=frac_x._down/gcd_num;
		frac_x._down*=x_multi_num,frac_x._up*=x_multi_num;
		frac_y._down*=y_multi_num,frac_y._up*=y_multi_num;
	}
	operator Tvalue()const{
		return Tvalue(_up)/Tvalue(_down);
	}
	// operator + , - , * , /
	// operator +
	fraction operator + (T another_adder)const{
		fraction frac_adder(another_adder*_down,_down,0,0);
		return fraction(_up+frac_adder._up,_down,1,1);
	}
	fraction operator + (fraction another_adder)const{
		two_fracs commoned=common_value(*this,another_adder);
		return fraction(commoned.first._up+commoned.second._up,commoned.first._down,true,true);
	}
	friend fraction operator + (T adder,fraction frac_adder){
		fraction frac_adder_eq1(adder*frac_adder._down,frac_adder._down,false,false);
		return fraction(frac_adder._up+frac_adder_eq1._up,frac_adder._down,true,true);
	}
	//operator -
	fraction operator - (fraction another_adder)const{
		two_fracs commoned=common_value(*this,another_adder);
		return fraction(commoned.first._up-commoned.second._up,commoned.first._down,true,true);
	}
	friend fraction operator - (T adder,fraction frac_adder){
		fraction frac_adder_eq1(adder*frac_adder._down,frac_adder._down,false,false);
		return fraction(frac_adder_eq1._up-frac_adder._up,frac_adder._down,true,true);
	}
	//operator *
	fraction operator * (T another_adder){
		T gcd_num;
		if((gcd_num=math::gcd(_down,another_adder))!=1)
			_down/=gcd_num,another_adder/=gcd_num;
		return fraction(_up*another_adder,_down,false,false);
	}
	fraction operator * (fraction another_adder){
		if(multi_optimize){
			T gcd_num;
			if(math::gcd(_up,_down)!=1) reduction();
			if(math::gcd(another_adder._up,another_adder._down)!=1) another_adder.reduction();
			if((gcd_num=math::gcd(_up,another_adder._down))!=1) 
				_up/=gcd_num,another_adder._down/=gcd_num;
			if((gcd_num=math::gcd(_down,another_adder._up)!=1))
				_down/=gcd_num,another_adder._up/=gcd_num;
			return fraction(_up*another_adder._up,_down*another_adder._down,false,false); 
		}
		else{
			return fraction(_up*another_adder._up,_down*another_adder._down,true,true);
		}
	}
	friend fraction operator * (T adder,fraction frac_adder){
		T gcd_num;
		if((gcd_num=math::gcd(frac_adder._down,adder))!=1)
			frac_adder._down/=gcd_num,adder/=gcd_num;
		return fraction(frac_adder._up*adder,frac_adder._down,false,false);
	}
	//operator /
	fraction operator / (T divider){
		return operator * (fraction(divider,1,multi_optimize));
	} 
	fraction operator / (fraction divider){
		return operator * (divider.reciprocal(!multi_optimize));
	}
	friend fraction operator / (T dividend,fraction divider){
		return operator * (dividend,divider.reciprocal(false));
	}
	// operator < , == , != , > , <= , >= 
	// operator <
	bool operator < (fraction frac_arg)const{
		two_fracs commoned=common_value(*this,frac_arg);
		return commoned.first._up frac_arg_eqint(integer_arg*_down,_down,false,false);
		return _up frac_arg){
		fraction frac_arg_eqint(integer_arg*frac_arg._down,frac_arg._down,false,false);
		return frac_arg._up frac_arg)const{
		two_fracs commoned=common_value(*this,frac_arg);
		return commoned.first._up==commoned.second._up;
	}
	bool operator == (T integer_arg)const{
		fraction frac_arg_eqint(integer_arg*_down,_down,false,false);
		return _up==frac_arg_eqint._up;
	} 
	friend bool operator == (T integer_arg,fraction frac_arg){
		fraction frac_arg_eqint(integer_arg*frac_arg._down,frac_arg._down,false,false);
		return frac_arg._up==frac_arg_eqint._up;
	}
	// operator !=
	bool operator != (fraction frac_arg)const{
		two_fracs commoned=common_value(*this,frac_arg);
		return commoned.first._up!=commoned.second._up;
	}
	bool operator != (T integer_arg)const{
		fraction frac_arg_eqint(integer_arg*_down,_down,false,false);
		return _up!=frac_arg_eqint._up;
	} 
	friend bool operator != (T integer_arg,fraction frac_arg){
		fraction frac_arg_eqint(integer_arg*frac_arg._down,frac_arg._down,false,false);
		return frac_arg._up!=frac_arg_eqint._up;
	}
	// operator >
	bool operator > (fraction frac_arg)const{
		two_fracs commoned=common_value(*this,frac_arg);
		return commoned.first._up>commoned.second._up;
	}
	bool operator > (T integer_arg)const{
		fraction frac_arg_eqint(integer_arg*_down,_down,false,false);
		return _up>frac_arg_eqint._up;
	} 
	friend bool operator > (T integer_arg,fraction frac_arg){
		fraction frac_arg_eqint(integer_arg*frac_arg._down,frac_arg._down,false,false);
		return frac_arg._up>frac_arg_eqint._up;
	}
	// operator <=
	bool operator <= (fraction frac_arg)const{
		two_fracs commoned=common_value(*this,frac_arg);
		return commoned.first._up<=commoned.second._up;
	}
	bool operator <= (T integer_arg)const{
		fraction frac_arg_eqint(integer_arg*_down,_down,false,false);
		return _up<=frac_arg_eqint._up;
	} 
	friend bool operator <= (T integer_arg,fraction frac_arg){
		fraction frac_arg_eqint(integer_arg*frac_arg._down,frac_arg._down,false,false);
		return frac_arg._up<=frac_arg_eqint._up;
	}
	// operator >=
	bool operator >= (fraction frac_arg)const{
		two_fracs commoned=common_value(*this,frac_arg);
		return commoned.first._up>=commoned.second._up;
	}
	bool operator >= (T integer_arg)const{
		fraction frac_arg_eqint(integer_arg*_down,_down,false,false);
		return _up>=frac_arg_eqint._up;
	} 
	friend bool operator >= (T integer_arg,fraction frac_arg){
		fraction frac_arg_eqint(integer_arg*frac_arg._down,frac_arg._down,false,false);
		return frac_arg._up>=frac_arg_eqint._up;
	}
	// operator += , -= , *= , /=
	// operator +=
	fraction operator += (fraction add_num){
		return *this=*this+add_num;
	}
	fraction operator += (T add_num){
		return *this=*this+add_num;
	}
	friend fraction operator += (T add_num,fraction add_frac){
		return add_frac=add_frac+add_num;
	}
	// operator -=
	fraction operator -= (fraction add_num){
		return *this=*this-add_num;
	}
	fraction operator -= (T add_num){
		return *this=*this-add_num;
	}
	friend fraction operator -= (T add_num,fraction add_frac){
		return add_frac=add_frac-add_num;
	}
	// operator *=
	fraction operator *= (fraction add_num){
		return *this=*this*add_num;
	}
	fraction operator *= (T add_num){
		return *this=*this*add_num;
	}
	friend fraction operator *= (T add_num,fraction add_frac){
		return add_frac=add_frac*add_num;
	}
	// operator /=
	fraction operator /= (fraction add_num){
		return *this=*this/add_num;
	}
	fraction operator /= (T add_num){
		return *this=*this/add_num;
	}
	friend fraction operator /= (T add_num,fraction add_frac){
		return add_frac=add_frac/add_num;
	}
	private:
	template
	struct two_fracs{
		fraction first;
		fraction second;
		two_fracs(){}
		two_fracs(fraction new_1,fraction new_2){
			first=new_1,second=new_2;
		}
	};
	template
	static two_fracs common_value(fraction frac_x,fraction frac_y){
		T1 gcd_num=math::gcd(frac_x._down,frac_y._down);
		T1 x_multi_num=frac_y._down/gcd_num,y_multi_num=frac_x._down/gcd_num;
		frac_x._down*=x_multi_num,frac_x._up*=x_multi_num;
		frac_y._down*=y_multi_num,frac_y._up*=y_multi_num;
		return two_fracs(frac_x,frac_y);
	}
};

namespace math{
	template
	fraction reduction(fraction the_frac){
		return the_frac.reduction();
	}
}
#endif

分数与浮点数之间的运算要用这样的形式:

fraction frac(1,2);
double doub=0.3;
cout<

欢迎转载,但请在文章中附加上本文链接: https://blog.csdn.net/weixin_41461277/article/details/84890580 。

你可能感兴趣的:(数学系列)