C++ 实数类

本文介绍了一个自定义的C++实数类,该类支持基本的四则运算和比较操作。虽然目前尚未实现整数或小数转换以及无限循环小数转分数的功能,但作者强调了模版在实现过程中的重要作用,并分享了学习模版的心得。代码中已修复了operator=的自我赋值问题和小数转分数可能导致的整数溢出问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是一堆我自己写完都怀疑人生的代码。
或许我见识太少了吧……

实现一个实数类。这个类也可以看作是分数类。实现了基本的四则运算和比较。另外,与整数或小数的转换还没有实现,无限循环小数转分数也暂时没有实现。但我早晚会写的。。。
咕咕咕。
这里的重头戏是模版。
啊……模版,我边学边卖,才知道模版还可以这么玩。
这次只有一个文件……
来体会一下来自C++的恐惧吧!

注意:以下代码没有经过严谨测试及性能优化。

BUGFIX:
1. 修复operator=不能对自身影响的BUG;(2018.10.10)
2.修复小数转分数时,造成整数溢出的BUG;(2018.10.10)

Rational.h

#pragma once
#include "stdinc.h"

namespace Lunacia
{
    
    
	class __Rational {
    
    };

	template<typename NumT = int>
	class Rational final : public __Rational
	{
    
    
	public:
		Rational();

		template<typename NumT2>
		Rational(const Rational<NumT2>& ra); 

		Rational(NumT numer, NumT denom);
		Rational(NumT numer, NumT denom, bool isDenomFixed);
		~Rational();

	public:
		static NumT Gcd(NumT a, NumT b);
		static NumT Lcm(NumT a, NumT b);

		static bool IsEven(NumT num);
		static NumT GetSymbol(NumT num);

		static bool IsEqualFloating(long double a, long double b);

		void SetDenomFixed(bool isFix);
		bool GetDenomFixed() const;

		void GetRationalString(std::string& __out resStr) const;
		void GetRationalString(std::wstring& __out resStr) const;

	public:
		///operator+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		template<typename ParamT,
			typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type * = nullptr>
			Rational<NumT> operator +(const ParamT rRational) const;

		template<typename ParamT,
			typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
			Rational<NumT> operator +(const ParamT& rRational) const;

		Rational<NumT> operator +(const Rational& rRational) const;

		///operator-----------------------------------------------------------------------
		template<typename ParamT,
			typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type * = nullptr>
		Rational<NumT> operator -(const ParamT& rRational) const;

		template<typename ParamT,
			typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
			Rational<NumT> operator -(const ParamT& rRational) const;

		Rational<NumT> operator -(const Rational& rRational) const;

		///operator******************************************************
		template<typename ParamT,
			typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type * = nullptr>
			Rational<NumT> operator *(const ParamT& rRational) const;

		template<typename ParamT,
			typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
			Rational<NumT> operator *(const ParamT& rRational) const;

		Rational<NumT> operator *(const Rational& rRational) const;
		
		///operator///////////////////////////////////////////////////////
		template<typename ParamT,
			typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type * = nullptr>
			Rational<NumT> operator /(const ParamT& rRational) const;

		template<typename ParamT,
			typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
			Rational<NumT> operator /(const ParamT& rRational) const;

		Rational<NumT> operator /(const Rational& rRational) const;

		///operator=======================================================
		template<typename ParamT,
			typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type * = nullptr>
			Rational<NumT> operator =(const ParamT& rRational);

		template<typename ParamT,
			typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
			Rational<NumT> operator =(const ParamT& rRational);

		Rational<NumT> operator =(const Rational& rRational);

		///operator== == == == == == == == == == == == == == == == == == == == == == ==
		template<typename ParamT,
			typename  std::enable_if < 
				std::is_integral <ParamT> ::value || 
					std::is_base_of<__Rational, ParamT>::value,
				ParamT 
			> ::type * = nullptr>
			bool operator ==(const ParamT& rRational) const;

		template<typename ParamT,
			typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
			bool operator ==(const ParamT& rRational) const;
		
		///operator!= != != != != != != != != != != != != != != != != != != != != != != != != != != != != 
		template<typename ParamT,
			typename  std::enable_if <
				std::is_integral <ParamT> ::value ||
					std::is_floating_point <ParamT> ::value||
					std::is_base_of<__Rational, ParamT>::value,
				ParamT
			> ::type * = nullptr>
			bool operator !=(const ParamT& rRational) const;

		///operator>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		template<typename ParamT,
			typename  std::enable_if <
					std::is_integral <ParamT> ::value ||
					std::is_floating_point <ParamT> ::value ||
					std::is_base_of<__Rational, ParamT>::value,
				ParamT
			> ::type * = nullptr>
			bool operator >(const ParamT& rRational) const;

		///operator <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
		template<typename ParamT,
			typename  std::enable_if <
				std::is_integral <ParamT> ::value ||
					std::is_floating_point <ParamT> ::value ||
					std::is_base_of<__Rational, ParamT>::value,
				ParamT
			> ::type * = nullptr>
		bool operator <(const ParamT& rRational) const ;

		///operator >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= 
		template<typename ParamT,
			typename  std::enable_if <
				std::is_integral <ParamT> ::value ||
					std::is_floating_point <ParamT> ::value ||
					std::is_base_of<__Rational, ParamT>::value,
				ParamT> ::type * = nullptr>
		bool operator >=(const ParamT& rRational);

		///operator <= <= <= <= <= <= <= <= <= <= <
【问题描述】 合法的实数书写格式分一般格式和科学格式两种。分别描述如下: 一般格式为常见的书写格式,分为整数部分和小数部分两部分,中间分用小数点.分隔。整数部分最开始可能含有正号或负号,之后为不含前导零的数字串;小数部分是由0-9十种字符组成的任意长的字符串。当小数部分为0时,小数部分和小数点可以省略。 科学格式由系数部分和指数部分两部分组成,中间用英文字母E分隔。系数部分为实数书写的一般格式;指数部分为可带有正负号数字串。 例如,+2、-1.56为一般格式的实数,而6.2E-2、-9E8为科学格式的实数。 只有小数点而没有小数部分的书写格式为不合法,例如,23.,23.E16均为不合法的实数书写格式。 编程分析哪些数的书写是正确的,是用哪种方式书写的。 【输入形式】 输入文件为当前目录下的real.in。该文件包含一个字符串(长度不超过20个字符),以回车符结束,表示一个数据(无多余空格)。 【输出形式】 输出文件为当前目录下的real.out。该文件有一行。如果输入数据的书写是非法的,输出Wrong;如果输入数据是用一般格式书写的,输出“Format1”;如果该数据是用科学格式书写的,输出“Format2”。输出的末尾均要以一个回车符作为结束。 【输入样例1】 +1.23 【输出样例1】 Format1 【输入样例2】 -5.1.1 【输出样例2】 Wrong 【输入样例3】 -5.1E-2 【输出样例3】 Format2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值