C++实现:分数类

C++分数类(Fraction)实现:从设计到优化的完整指南 在C++编程中,处理精确的有理数运算常面临浮点数精度丢失的挑战。通过面向对象编程的封装思想,可以设计一个值语义的分数类,其核心原理是维护分子与分母两个整数,并通过欧几里得算法进行约分以保证最简形式。该技术的价值在于提供精确的数学运算支持,避免了诸如0.1+0.2不等于0.3的精度问题,在金融计算、物理模拟和游戏开发等需要高精度比例处理的场景中尤为重要。本文深入探讨了如何实现一个健壮的Fraction类,涵盖**运算符重载**以使其使用如同内置类型,并详细分析了处理**溢出问题**等工程实践中的关键细节。 阅读详情

花了几个小时敲代码——测试——修改……

总算搞定了

好累,睡觉去的

有问题欢迎提出,继续修改

首先是头文件CFraction.h:

 

#ifndef CFRACTION_H_
#define CFRACTION_H_
#include <iostream>
using  namespace std;
class CFraction
{
public:
	CFraction(int a=1,int b=1);
	virtual ~CFraction(){};
	float GetValue()const;//获取分数值
	void Simplification();//化简
	void Show();//显示分数
	friend ostream& operator<<(ostream& os,CFraction& f);
	//重载四则运算操作符
	CFraction operator +(const CFraction& f)const;
	CFraction operator -(const CFraction& f)const;
	CFraction operator *(const CFraction& f)const;
	CFraction operator /(CFraction& f)const;
	//重载比较操作符
	bool operator ==(const CFraction& f)const;
	bool operator >(const CFraction& f)const;
	bool operator <(const CFraction& f)const;
	CFraction GetReciprocal();//获取分数的倒数
	void ChangeValue(int a,int b);//改变当前分数分子和分母
private:
	int m_molecular;//分子
	int m_denomilator;//分母
	bool m_IsNegative;//是否为负数 
};
#endif;

然后是类方法实现文件CFraction.cpp

#include "stdafx.h"
#include "CFraction.h"
#include <cmath>
//辗转相除法求最大公约数
int Function(int& a,int& b)
{
	int r=a%b;
	while(r)
	{
		a=b;
		b=r;
		r=a%b;
	}
	return b;
}
ostream& operator<<(ostream& os,CFraction& f)
{
	f.Simplification();
	if(f.m_IsNegative)//负数
		os<<"  -"<<f.m_molecular<<"/"<<f.m_denomilator<<endl;
	else//正数
		os<<"   "<<f.m_molecular<<"/"<<f.m_denomilator<<endl;
	return os;
}
CFraction::CFraction(int a, int b):m_IsNegative(false)
{//默认分数为正1
	while(b==0)
	{
		cout<<"分母不能为0,请重新输入分母:"<<endl;
		cin>>b;
	}
	this->m_molecular=abs(a);
	this->m_denomilator=abs(b);
	if(a<0&&b<0)
		this->m_IsNegative=false;
	else if(a<0||b<0)
		this->m_IsNegative=true;
	else
		this->m_IsNegative=false;
	this->Simplification();
}
float CFraction::GetValue()const
{
	return this->m_molecular/(float)m_denomilator;
}
void CFraction::Simplification()
{
	int a=m_molecular,b=m_denomilator;
	int ret=Function(a,b);
	m_molecular/=ret;
	m_denomilator/=ret;
}
CFraction CFraction::operator +(const CFraction &f)const
{
	CFraction temp;
	if(m_IsNegative==f.m_IsNegative)//同号相加
	{
		temp.m_molecular=m_molecular*f.m_denomilator+m_denomilator*f.m_molecular;
		temp.m_denomilator=m_denomilator*f.m_denomilator;
		temp.m_IsNegative=m_IsNegative;
	}
	else// 不同号
	{
		temp.m_molecular=abs(m_molecular*f.m_denomilator-m_denomilator*f.m_molecular);
		temp.m_denomilator=abs(m_denomilator*f.m_denomilator);
		if(this->GetValue()>f.GetValue())
			temp.m_IsNegative=m_IsNegative;
		else
			temp.m_IsNegative=f.m_IsNegative;
	}
	return temp;
}
void CFraction::Show()
{
	cout<<*this;
}
CFraction CFraction::operator -(const CFraction &f) const
{
	CFraction temp;
	if(m_IsNegative==f.m_IsNegative)//同号相减
	{
		temp.m_molecular=abs(m_molecular*f.m_denomilator-m_denomilator*f.m_molecular);
		temp.m_denomilator=m_denomilator*f.m_denomilator;
		if(GetValue()>=f.GetValue())
			temp.m_IsNegative=false;
		else
			temp.m_IsNegative=true;
	}
	else//异号相减
	{
		temp.m_molecular=m_molecular*f.m_denomilator+m_denomilator*f.m_molecular;
		temp.m_denomilator=m_denomilator*f.m_denomilator;
		temp.m_IsNegative=m_IsNegative;
	}
	return temp;
}
CFraction CFraction::operator *(const CFraction &f) const
{
	CFraction temp;
	temp.m_molecular=m_molecular*f.m_molecular;
	temp.m_denomilator=m_denomilator*f.m_denomilator;
	//接下来确定符号
	if(m_IsNegative==f.m_IsNegative)//同号相乘符号为正
		temp.m_IsNegative=false;
	else
		temp.m_IsNegative=true;
	return temp;

}
CFraction CFraction::operator /(CFraction &f) const
{
	CFraction temp,r;
	r=f.GetReciprocal();
	temp=*this*r;
	return temp;
}
CFraction CFraction::GetReciprocal()
{
	CFraction temp;
	temp.m_denomilator=m_molecular;
	temp.m_molecular=m_denomilator;
	temp.m_IsNegative=m_IsNegative;
	return temp;
}
bool CFraction::operator ==(const CFraction &f) const
{
	if(m_IsNegative!=f.m_IsNegative)//不同号肯定不相等
		return false;
	if(GetValue()==f.GetValue())
		return true;
	else
		return false;
}
bool CFraction::operator <(const CFraction &f) const
{
	if(m_IsNegative==f.m_IsNegative)//同号比较大小
	{
		if(GetValue()<f.GetValue())
		{
			if(m_IsNegative)
				return false;
			else
				return true;
		}
		else if(GetValue()>f.GetValue())
		{
			if(m_IsNegative)
				return true;
			else
				return false;
		}
		else//相等的分数
			return false;
	}
	else if(m_IsNegative)//左负友正
		return true;
	else// 左正右负
		return false;
}
bool CFraction::operator >(const CFraction& f)const//大于号小于号刚好相反
{
	return (f<*this);
}
void CFraction::ChangeValue(int a,int b)
{
	*this=CFraction(a,b);
}


希望对C++初学者有所帮助

C++真的很强大

努力学习中

再见

C++分数类实现:运算符重载与类型转换实战指南 在C++编程中,运算符重载是实现自定义类型与内置类型行为一致性的核心技术,它允许开发者为类定义如+、-、*、/等操作符的具体行为。其原理是通过定义特定的成员函数或全局函数,使编译器在遇到相应操作符时调用这些自定义逻辑。这项技术的核心价值在于提升代码的直观性和可读性,让用户自定义类型能够无缝融入C++的表达式体系,实现更自然的语法。在需要高精度计算或特定数学抽象的场景,如金融量化、物理引擎或游戏开发中,一个设计良好的自定义数值类型至关重要。本文聚焦于构建一个健壮的分数类,深入探讨了如何通过运算符重载实现分数的 阅读详情

相关推荐

D类功放几种常见“爆破音”问题根源与改善措施

在数字D类功放刚上电或功放播放状态切换时,人耳偶尔会听到“嘣”的声音,我们把这个爆破的Pop Noise。数字功放Pop Noise 出现的原因有很多,本文主要分析Pop Noise 出现原因,并提供相应解决方法。

qq_26815321的博客 3590

[C++]分数类的定义(成员函数、运算符重载)

C++分数类的实现

cumtLeibnizDavid的博客 2966

PointPainting 复现

三维目标检测

weixin_58207716的博客 4532

C++ 重载运算符——分数类和多项式类

【代码】C++ 重载运算符——分数类和多项式类。

weixin_74287172的博客 1455

Rsoft仿真实战:长周期光纤光栅参数优化与模式耦合分析

本文详细介绍了使用Rsoft软件进行长周期光纤光栅(LPFG)参数优化与模式耦合分析的实战方法。通过Rsoft仿真,可以高效优化光栅周期、包层厚度等关键参数,深入分析纤芯模与包层模的耦合特性,为光纤通信和传感应用提供可靠的设计依据。

h0i1j2k3l的博客 1115

用本地 Chrome + DeepSeek 实现浏览器自动化:browser-use 实战与踩坑记录

本文记录了使用本地Chrome浏览器结合DeepSeek API实现浏览器自动化的实战经验。作者通过browser-use项目连接本地Chrome(启动时需添加--remote-debugging-port=9222参数),并解决了DeepSeek API不支持response_format的问题,通过设置dont_force_structured_output=True和add_schema_to_system_prompt=True成功绕过。同时分享了任务描述需精准的重要性,避免Agent输出多余信息导

LY的博客 750

C++实现分数类

在几乎所有的语言中(至少我知道的语言都是这样),浮点数都是有精度丢失的。 怎么解决呢? 分数类就是解决办法之一。         分数类采用分数的形式,保存了两个整数之比,确保了精度。         分数类,肯定是要有约分、通分等函数和加、减、乘、除运算符的。(当然,要先实现求最大公因数和最小公倍数函数)这些都是基本数学知识。         代码如下: #ifndef F...

zgq的博客 9361

Android Framework WMS面试题及参考答案

什么是 WindowManagerService(WMS)?它的作用是什么? WindowManagerService(WMS)是 Android 系统中非常重要的一个系统服务。它运行在系统进程(system_server 进程)中。 从本质上来说,WMS 是 Android 窗口管理系统的核心。它负责管理系统中的所有窗口,包括应用程序窗口、系统窗口(如状态栏、导航栏)等。 它的主要作用有很多。首先是窗口的创建和销毁。当一个应用请求创建一个窗口时,WMS 会协调各个模块完成窗口的创建工

大模型大数据攻城狮的专栏 2162

【C++】分数运算

C++实现部分分数运算,封装成类

qq_47750131的博客 950

芒果YOLOv8改进52:主干Backbone篇之GhostNetV2:提出原创GhostNetV2 架构升级版:引入长距离注意力机制增强廉价操作,构建更强端侧轻量型骨干,打造高效轻量级检测器

长距离注意力机制增强廉价操作,打造轻量级检测器

包括YOLOv5、YOLOv7、YOLOv8等模型改进 1610

【数据结构】期末考试复习(考点+例题)

1.线性表定义及其存储实现:顺序表和链接表,优缺点分析(顺序存储可随 机访问,链式存储可灵活利用空间),相关操作的时间复杂度。 2.链表的插入删除操作 3.两种特殊的线性表及其应用:栈、队列 4.栈、队列上的(插入/删除)操作及其特点 5.循环队列满和空的条件 6.能够定义线性表、栈、队列的数据存储结构,能够实现相关操作的算法并 分析时间复杂度(例如插入、删除及其它应用等) 7.理解线性结构的应用( 如根据要求能灵活定义线性表结构,能根据线性表 的插入、删除操作解决实际问题) 二叉树基本概念与性质(高

Molly 的博客 9366

比较两个分数的大小

/*比较两个分数的大小。 *问题分析与算法设计 人工方式下比较分数大小最常用的方法是:进行分数的通分后比较分子的大小。可以编程模拟手式方式。 #include"stdio.h" #include"stdlib.h" #include"time.h" long int gongbeishu(int a,int b)//求最小公倍数 {int temp; int k1=a,k2=b; while

huitoukest的专栏 5147

Spring 核心技术解析【纯干货版】- I:Spring 基础模块 Spring-Core 模块精讲

Spring-Core 模块,是 Spring 核心容器模块之一。虽然 “Core” 本身就有 “核心的,重要的部分” 的含义,但是它并非是实现(常被我们说为 Spring 核心机制)IOC / AOP 的模块。Spring 中的 IOC 机制,主要来自于 BeanFactory 容器和 ApplicationContext 容器,这二者分别由同为核心容器模块的 Spring-Bean 模块 和 Spring-Context 模块所提供。

栗筝i的博客 2522

C++高级编程(第4版)个人笔记 15.8 - 转换运算符 | 转换运算函数

参考书籍: 《C++高级编程》(第4版)》 下面是一个简单的"分数"类: //Fraction.h //分数类 #ifndef FRACTION_FRACTION_H #define FRACTION_FRACTION_H class Fraction { public: Fraction(int num, int den = 1) : m_numerato...

Fista的笔记本 424

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

C++ DLUT 上机作业(一)

C++ DLUT 上机作业(一) 声明:不同老师有不同要求,仅供参考,不喜勿喷 另外,所有代码在Dev C++可运行 1、/*定义一个分数类如下,要求实现分数的初始化与设置、四则运算及约分以及输出等功能,并在主函数中测试。 class Rational{ int m; // 分母 int n; // 分子 public: Rational(int nn=1,int mm=1); //构造 bool setM( int ); // 设置分母,注意不能为零 void setN( int ); /

weixin_51568657的博客 1643

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Problem G: 分数类的模板数组类

这个题是有两种版本的,一种是定义不定长数组vector,一种是定义一个指针,个人觉得定义指针比较简单,

Lee贤的博客 394

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

实验3:类和对象

实验目的 1.掌握类的设计、定义、实现和测试 2.掌握C++程序以项目文件组织的多文件结构编写形式 3.深度理解面向对象编程与结构化编程在编程解决实际问题时思维方式的不同实验准备 实验前,请围绕以下几点复习/学习指定内容: 1.C++程序以项目文件方式组织的多文件结构浏览学习教材「5.6节多文件结构和编译预处理指令」。 2.类和对象 ...

weixin_30540691的博客 488

C++ 设计一个分数类fration,其中包含以下功能:能防止分母为0的构造函数; 对非最简分数进行约分的成员函数;加、减、乘、除运算符重载函数(用友元函数实现); 关系运算符、赋值运算符、流

设计一个分数类fration: #include using namespace std; class fraction { //定义分数 int numerator;//分子 int denominator;//分母 public: fraction(int x = 0, int y = 1);//默认分子为0,分母为1,函数体中必须有控制分母不为0的条件 fraction(const frac...

IT__caiji的博客 2747

面向对象程序设计与C++语言(朱站立版)期末复习及习题答案 第七章(模板)

C++语言中解决参数多态性问题的方法是模板。模板分为函数模板和类模板。函数模板是指将函数中的数据类型作为参数设计的通用函数。类模板是指把类中的成员变量的数据类型作为参数设计的通用类。只有通过参数实例化才能将模板变成一个数据类型具体的函数或类。参数实例化是指给函数模板或类模板传入实际的数据类型参数。把经过参数实例化的函数模板或类模板称为模板函数或模板类。

weixin_72788067的博客 211

C++语言基础 例程 重载单目运算符

贺老师的教学链接  本课讲解示例1:分数类对象的相反数class CFraction { private: int nume; // 分子 int deno; // 分母 public: CFraction(int nu=0,int de=1):nume(nu),deno(de) {} CFraction operator-(const CFraction &c

迂者-贺利坚的专栏 1777

c++简单程序设计-4

一 编程实验部分1.graph类 ① graph.h #ifndef GRAPH_H #define GRAPH_H // 类Graph的声明 class Graph { public: Graph(char ch, int n); // 带有参数的构造函数 void draw(); // 绘制图形 ...

weixin_30367873的博客 134

C++分数类

1.简介 我用C++做了一个分数类,实现了加减乘除、比较大小、约分、通分等功能。下面与大家分享一下代码(VS2019编译通过)。 2.代码 代码不难理解,用到的都是一些数学原理。 //CFraction.h #pragma once #include<stdexcept> class CFraction { private: typedef long long type; type numerator;//分子 type denominator;//分母 static type GCD(

[PE]经典八炮的博客 1884

python 分数化简_C++、Java、Python中都是怎么精确表达分数的?

你要的东西,STL 库已经有了,叫 std::ratio ,是 C++11 标准的模板类。在 C++11 标准之后,C++委员会加入了大量高等数学相关的函数,beta函数、gamma函数、黎曼Zeta函数、球面贝塞尔函数等等,少不了优秀的先驱库 boost 的功劳。Standard library header ​en.cppreference.comstd::ratio_add、std::rat...

weixin_39910043的博客 425

【C++】运算符重载实现分数类的四则运算

C++运算符重载实现分数类的简单四则运算。内容梗概:运算符重载的两种方式、最大公约数、友元函数、前自增和后自增区别。

njnu19210217的博客 4520

c++作业,带默认参数的成员函数

题目来源于:http://blog.youkuaiyun.com/sxhelijian/article/details/8723847 【项目2】C++中提供了多种基本的数据类型。实际上,这些远不能满足我们的需求,如复数(第10章的例子大多是处理虚数的),再如分数。本任务将设计一个简单的分数类,完成对分数的几个运算。一则巩固基于对象编程的方法,二则也为第10章做运算符重载等积累些感性认识。   项目要求:

Simple_Jan快乐的学习 1090

C++:完成一个分数(fraction)类

目录一:题目要求1.单目运算:2.双目运算3.其他4.main函数二:实现过程1.fraction.h的实现2.fraction.cpp的实现2.1 GCD求最大公约数 一:题目要求 用C++语言完成一个分数类(fraction)的构建,分数类实现的功能(函数)要求如下: 1.单目运算: Inverse:取负运算(例:+2/3 -> -2/3,或者 -2/3 -> +2/3)、 Reciprocal:求倒数(例:2/3 -> 3/2)、 Reduction:约分(例:6/9 -> 2

weixin_51252109的博客 6310
上一篇: C++实现贪吃蛇类
下一篇: C++实现:BF算法和KMP算法
疯狂-的-蜗牛
博客等级 码龄16年 427粉丝 104原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值