c++实现分数操作

此代码包含了分数的操作,包含以下操作:

约分;

求最大公因数和最小公倍数;

分数各项运算;

假分数转换成带分数。

#include<iostream>
#include<string>
#include<sstream>
#include<cmath>
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b) {
	return !b?a:gcd(b,a%b);
}
int lcm(int a,int b) {
	return a*b/gcd(a,b);
}
pair<int, int> simplify(int numerator, int denominator) {
	if(denominator == 0) throw invalid_argument("分母不能为零");
	if(numerator == 0) return {0, 1};
	int g = gcd(abs(numerator), abs(denominator));
	return {numerator / g, denominator / g};
}
void printFractionLine(int num) {
	int digits = 0;
	if(num == 0) digits = 1;
	else while(num) {
			digits++;
			num /= 10;
		}
	cout << string(digits, '-') << endl;
}
void printFraction(int numerator, int denominator) {
	cout << numerator << endl;
	printFractionLine(max(abs(numerator), abs(denominator)));
	cout << denominator << endl;
}
pair<int, int> addFractions(int n1, int d1, int n2, int d2) {
	if(d1 == 0 || d2 == 0) throw invalid_argument("分母不能为零");
	int lcm_val = d1 * d2 / gcd(d1, d2);
	int result_n = n1 * (lcm_val / d1) + n2 * (lcm_val / d2);
	return simplify(result_n, lcm_val);
}
pair<int, int> subtractFractions(int n1, int d1, int n2, int d2) {
	return addFractions(n1, d1, -n2, d2);
}
pair<int, int> multiplyFractions(int n1, int d1, int n2, int d2) {
	if(d1 == 0 || d2 == 0) throw invalid_argument("分母不能为零");
	return simplify(n1 * n2, d1 * d2);
}
pair<int, int> divideFractions(int n1, int d1, int n2, int d2) {
	if(d1 == 0 || d2 == 0 || n2 == 0) throw invalid_argument("分母或除数不能为零");
	return simplify(n1 * d2, d1 * n2);
}
void improperToMixed(int numerator, int denominator) {
	if(denominator == 0) throw invalid_argument("分母不能为零");
	int whole = numerator / denominator;
	int remainder = numerator % denominator;
	if(remainder == 0) {
		cout << "结果: " << whole << endl;
		return;
	}
	auto simplified = simplify(remainder, denominator);
	cout << "结果: \n" << whole << " 又\n";
	printFraction(simplified.first, simplified.second);
}
void showMenu() {
	cout << "******************\n";
	cout << "****分数计算器****\n";
	cout << "******************\n";
	cout << "0. 退出\n";
	cout << "1. 约分\n";
	cout << "2. 求最大公因数和最小公倍数\n";
	cout << "3. 分数加法\n";
	cout << "4. 分数减法\n";
	cout << "5. 分数乘法\n";
	cout << "6. 分数除法\n";
	cout << "7. 假分数转带分数\n";
	cout << "请输入操作编号: ";
}
int getValidInt(const string& prompt) {
	int value;
	while(true) {
		cout << prompt;
		if(cin >> value) {
			cin.ignore(numeric_limits<streamsize>::max(), '\n');
			return value;
		} else {
			cin.clear();
			cin.ignore(numeric_limits<streamsize>::max(), '\n');
			cout << "输入无效,请输入整数。" << endl;
		}
	}
}
int main() {
	int choice;
	while(true) {
		system("cls");
		showMenu();
		choice = getValidInt("");
		if(choice == 0) break;
		try {
			switch(choice) {
				case 1: {
					int numerator = getValidInt("输入分子: ");
					int denominator = getValidInt("输入分母: ");
					auto result = simplify(numerator, denominator);
					cout << "约分结果:" << endl;
					printFraction(result.first, result.second);
					break;
				}
				case 2: {
					int sub_choice = getValidInt("1. 最大公因数\n2. 最小公倍数\n请选择: ");
					int a = getValidInt("输入第一个数: ");
					int b = getValidInt("输入第二个数: ");
					if(sub_choice == 1) cout << "gcd(" << a << ", " << b << ") = " << gcd(a, b) << endl;
					else if(sub_choice == 2) cout << "lcm(" << a << ", " << b << ") = " << lcm(a, b) << endl;
					else cout << "无效选择" << endl;
					break;
				}
				case 3: {
					int n1 = getValidInt("第一个分数 - 分子: ");
					int d1 = getValidInt("第一个分数 - 分母: ");
					int n2 = getValidInt("第二个分数 - 分子: ");
					int d2 = getValidInt("第二个分数 - 分母: ");
					cout << "第一个分数:" << endl;
					printFraction(n1, d1);
					cout << "第二个分数:" << endl;
					printFraction(n2, d2);
					auto result = addFractions(n1, d1, n2, d2);
					cout << "加法结果:" << endl;
					printFraction(result.first, result.second);
					break;
				}
				case 4: {
					int n1 = getValidInt("第一个分数 - 分子: ");
					int d1 = getValidInt("第一个分数 - 分母: ");
					int n2 = getValidInt("第二个分数 - 分子: ");
					int d2 = getValidInt("第二个分数 - 分母: ");
					cout << "第一个分数:" << endl;
					printFraction(n1, d1);
					cout << "第二个分数:" << endl;
					printFraction(n2, d2);
					auto result = subtractFractions(n1, d1, n2, d2);
					cout << "减法结果:" << endl;
					printFraction(result.first, result.second);
					break;
				}
				case 5: {
					int n1 = getValidInt("第一个分数 - 分子: ");
					int d1 = getValidInt("第一个分数 - 分母: ");
					int n2 = getValidInt("第二个分数 - 分子: ");
					int d2 = getValidInt("第二个分数 - 分母: ");
					cout << "第一个分数:" << endl;
					printFraction(n1, d1);
					cout << "第二个分数:" << endl;
					printFraction(n2, d2);
					auto result = multiplyFractions(n1, d1, n2, d2);
					cout << "乘法结果:" << endl;
					printFraction(result.first, result.second);
					break;
				}
				case 6: {
					int n1 = getValidInt("第一个分数 - 分子: ");
					int d1 = getValidInt("第一个分数 - 分母: ");
					int n2 = getValidInt("第二个分数 - 分子: ");
					int d2 = getValidInt("第二个分数 - 分母: ");
					cout << "第一个分数:" << endl;
					printFraction(n1, d1);
					cout << "第二个分数:" << endl;
					printFraction(n2, d2);
					auto result = divideFractions(n1, d1, n2, d2);
					cout << "除法结果:" << endl;
					printFraction(result.first, result.second);
					break;
				}
				case 7: {
					int numerator = getValidInt("输入分子: ");
					int denominator = getValidInt("输入分母: ");
					improperToMixed(numerator, denominator);
					break;
				}
				default:
					cout << "无效操作编号" << endl;
			}
		} catch(const exception& e) {
			cout << "错误: " << e.what() << endl;
		}
		cout << "\n按任意键继续...";
		cin.ignore();
		cin.get();
	}
	cout << "\n感谢使用分数计算器!\n\n";
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值