0
回答
C++ 數字類別 v3.0 (=-*/)
华为云数据库免费试用   
#pragma once

#include <iostream>
#include <vector>
#include <string>

using std::string;
using std::ostream;
using std::cout;
using std::vector;

class Number {
private:

	char* m_number;
	char  m_decimal;
	int   m_number_space;
	bool  m_is_positive;

	static const string ALLOW_NUMBER_CHAR;

public:

	Number(string str = "") {
		for (int i = 0; i < str.size(); ++i) {
			if (!m_is_number(str[i])) {
				m_reset();
				return;
			}
		}

		int total_plus = 0;

		for (int i = 0; i < str.size(); ++i) {
			if (str[i] == '.')
				total_plus++;
		}

		if (total_plus > 1) {
			m_reset();
			return;
		}

		if (total_plus > 0) {
			int decimal_point = str.find('.');
			m_decimal = str[decimal_point + 1] - '0';
			str.resize(decimal_point);
		}
		else {
			m_decimal = 0;
		}

		if (str.empty()) {
			m_reset();
			return;
		}

		if (str.at(0) == '-')
			m_is_positive = false;
		else
			m_is_positive = true;

		if (m_is_positive == false) {
			str.erase(0, 1);
		}

		while (str.empty() == false && str.at(0) == '0') {
			str.erase(0, 1);
		}

		m_number = new char[str.size() + 1];

		for (int i = 0; i < str.size(); ++i) {
			m_number[i] = str.at(i) - '0';
		}

		m_number[str.size()] = '\0';

		m_number_space = str.size();
	}

	int m_get_size() {
		return m_number_space;
	}

	void m_reset() {

		m_number = new char[1];
		m_number[0] = '\0';

		m_decimal = 0;

		m_number_space = 0;

		m_is_positive = true;

		return;

	}

	bool m_is_number(char ch) {
		return ALLOW_NUMBER_CHAR.find(ch) != ALLOW_NUMBER_CHAR.npos;
	}

	string m_number_to_string() const {
		string str;
		str.resize(m_number_space);

		for (int i = 0; i < m_number_space; ++i) {
			str.at(i) = m_number[i] + '0';
		}

		return str;
	}

	string m_to_string() const {
		string number;
		number.resize(m_number_space);
		for (int i = 0; i < m_number_space; ++i) {
			number.at(i) = m_number[i] + '0';
		}

		if (number.empty())
			number = "0";

		number = (m_is_positive ? "" : "-") + number;

		if (number.empty() == true)
			number.insert(0, 1, '0');

		if (m_decimal != 0) {
			number.push_back('.');
			number.push_back(m_decimal + '0');
		}



		return number;
	}

	int Compare(Number & number) {

		if (this->m_is_positive != number.m_is_positive) {
			return this->m_is_positive == true ? 1 : -1;
		}

		if (this->m_number_space != number.m_number_space) {

			if (this->m_is_positive == false)
				return this->m_number_space > number.m_number_space ? -1 : 1;
			else
				return this->m_number_space > number.m_number_space ? 1 : -1;

		}

		for (int i = 0; i < this->m_number_space; ++i) {
			if (this->m_number[i] != number.m_number[i]) {

				if (this->m_is_positive == false)
					return this->m_number[i] > number.m_number[i] ? -1 : 1;
				else
					return this->m_number[i] > number.m_number[i] ? 1 : -1;

			}
		}

		if (this->m_decimal != number.m_decimal) {

			if (this->m_is_positive == false)
				return this->m_decimal > number.m_decimal ? -1 : 1;
			else
				return this->m_decimal > number.m_decimal ? 1 : -1;
		}

		return 0;
	}

	static string approximate(string str) {
		if (str.empty())
			return str;

		for (int i = 0; i < str.size(); i++) {
			if (str.at(i) > 81)
				return str;
		}

		for (int i = str.size() - 1; i > 0; --i) {
			if (str.at(i) > 9) {
				str.at(i - 1) += str.at(i) / 10;
				str.at(i) %= 10;
			}
		}

		if (str.at(0) > 9) {
			str.insert(0, 1, str.at(0) / 10);
			str.at(1) %= 10;
			return approximate(str);
		}

		return str;
	}

	friend ostream & operator<<(ostream & os, Number & number);

	Number operator+(Number & number);

	friend Number operator-(Number & a, Number & b);
	friend Number operator*(Number & a, Number & b);
	friend Number operator/(Number & numbera, Number &);

	bool operator>(Number & number);
	bool operator<(Number & number);
	bool operator>=(Number & number);
	bool operator<=(Number & number);
	bool operator==(Number & number);
};

const string Number::ALLOW_NUMBER_CHAR = "-.0123456789";

bool Number::operator>(Number & number) {
	return this->Compare(number) == 1;
}

bool Number::operator<(Number & number) {
	return this->Compare(number) == -1;
}

bool Number::operator==(Number & number) {
	return this->Compare(number) == 0;
}

bool Number::operator>=(Number & number) {
	return (*this == number) + (*this > number);
}

bool Number::operator<=(Number & number) {
	return (*this == number) + (*this < number);
}

ostream & operator<<(ostream & os, Number & number) {
	os << number.m_to_string();

	return os;
}

Number Number::operator+(Number & number) {
	if (!this->m_is_positive) {
		Number new_number = *this;
		new_number.m_is_positive = true;
		return number - new_number;
	}

	if (!number.m_is_positive) {
		Number new_number = number;
		new_number.m_is_positive = true;
		return number - new_number;
	}

	int biger_number_size;

	string result_string;

	if (this->m_number_space > number.m_number_space)
		biger_number_size = this->m_number_space;
	else
		biger_number_size = number.m_number_space;

	result_string.resize(biger_number_size + 1);

	result_string.at(result_string.size() - 1) = this->m_decimal + number.m_decimal;

	for (int i = biger_number_size - 1; i >= 0; --i) {	///for (int i = result_string.size() - 2; i >= 0; --i)
		if (biger_number_size - i - 1 < this->m_number_space)
			result_string.at(i) += this->m_number[this->m_number_space - biger_number_size + i];
		if (biger_number_size - i - 1 < number.m_number_space)
			result_string.at(i) += number.m_number[number.m_number_space - biger_number_size + i];
	}

	for (int i = result_string.size() - 1; i > 0; --i) {
		result_string[i - 1] += int(result_string[i]) / 10;
		result_string[i] %= 10;
	}

	if (result_string[0] > 9) {
		result_string.insert(0, 1, int(result_string[0]) / 10);
		result_string[1] %= 10;
	}

	for (int i = 0; i < result_string.size(); ++i) {
		result_string[i] += '0';
	}

	result_string.insert(result_string.size() - 1, 1, '.');

	return Number(result_string);
}

Number operator-(Number & a, Number & b)
{
	if (b.m_is_positive == false) {
		Number numberb = b;
		numberb.m_is_positive = true;
		return a + numberb;
	}

	if (a.m_is_positive == false) {
		Number numbera = a;
		numbera.m_is_positive = true;
		return Number("-" + (numbera + b).m_to_string());
	}

	bool result_is_positive;

	Number numbera, numberb;

	if (a < b) {
		numbera = b;
		numberb = a;
		result_is_positive = false;
	}
	else {
		numbera = a;
		numberb = b;
		result_is_positive = true;
	}

	string result_string;

	result_string.resize(numbera.m_number_space + 1);

	for (int i = 0; i < numbera.m_number_space; ++i) {
		result_string.at(i) = numbera.m_number[i];
	}

	result_string.at(result_string.size() - 1) = numbera.m_decimal - numberb.m_decimal;

	if (result_string.at(result_string.size() - 1) < 0) {
		result_string.at(result_string.size() - 1) += 10;
		--result_string.at(result_string.size() - 2);
	}

	int result_string_size = result_string.size();
	for (int i = result_string_size - 2; i >= 0; --i) {
		if (result_string_size - i - 2 < numberb.m_number_space)
			result_string.at(i) -= numberb.m_number[numberb.m_number_space - result_string_size + i + 1];
		else
			break;
		if (result_string.at(i) < 0 && i > 0) {
			result_string.at(i) += 10;
			--result_string.at(i - 1);
		}
	}

	for (int i = 0; i < result_string.size(); ++i) {
		result_string[i] += '0';
	}

	result_string.insert(result_string.size() - 1, 1, '.');

	if (result_is_positive == false)
		result_string.insert(0, 1, '-');

	return Number(result_string);
}

Number operator*(Number & a, Number & b)
{
	bool result_is_positive;

	if (a.m_is_positive != b.m_is_positive)
		result_is_positive = false;
	else
		result_is_positive = true;

	Number numbera, numberb;

	if (a < b) {
		numbera = b;
		numberb = a;
	}
	else {
		numbera = a;
		numberb = b;
	}

	string numbera_number, numberb_number;

	numbera_number.resize(numbera.m_number_space);
	numberb_number.resize(numberb.m_number_space);
	for (int i = 0; i < numbera.m_number_space; ++i)
		numbera_number.at(i) = numbera.m_number[i];
	for (int i = 0; i < numberb.m_number_space; ++i)
		numberb_number.at(i) = numberb.m_number[i];
	numbera_number.push_back(numbera.m_decimal);
	numberb_number.push_back(numberb.m_decimal);

	string result_string;

	string register_string;

	Number register_number;

	vector<string> possable_result(9);

	for (int i = 0; i < 9; ++i) {
		possable_result.at(i) = numbera_number;
		for (int j = 0; j < possable_result.at(i).size(); ++j) {
			possable_result.at(i).at(j) *= (i + 1);
		}
		possable_result.at(i) = Number::approximate(possable_result.at(i));
		for (int j = 0; j < possable_result.at(i).size(); ++j) {
			possable_result.at(i).at(j) += '0';
		}
	}

	for (int i = numberb_number.size() - 1; i >= 0; --i) {
		if (numberb_number.at(i) != 0)
			register_string = possable_result.at(numberb_number.at(i) - 1);
		else
			register_string = { 0, 0 };

		register_string.insert(register_string.size(), numberb_number.size() - i - 1, '0');

		register_number = Number(result_string) + Number(register_string);

		result_string.resize(register_number.m_number_space);

		for (int j = 0; j < register_number.m_number_space; ++j) {
			result_string.at(j) = register_number.m_number[j] += '0';
		}
	}

	if (result_string.size() >= 2) {
		result_string.insert(result_string.size() - 2, 1, '.');

		if (result_string.at(0) == '.')
			result_string.insert(0, 1, '0');

		if (result_is_positive == false)
			result_string.insert(0, 1, '-');
		return Number(result_string);
	}

	return Number();
}

Number operator/(Number & numbera, Number & numberb)
{
	bool result_is_positive;

	if (numbera.m_is_positive != numberb.m_is_positive)
		result_is_positive = false;
	else
		result_is_positive = true;

	string numbera_number, numberb_number;

	numbera_number = numbera.m_number_to_string();
	numberb_number = numberb.m_number_to_string();
	numbera_number.push_back(numbera.m_decimal + '0');
	numbera_number.push_back('0');
	numberb_number.push_back(numberb.m_decimal + '0');

	vector<string> possable_result(9);

	for (int i = 0; i < 9; ++i)
		possable_result.at(i) = (Number(numberb_number) * Number(std::to_string(i + 1))).m_number_to_string();

	string result_string("");

	int indes = -1;

	int number_need_to_multiplier;

	string register_string("");

	while (++indes < numbera_number.size()) {

		register_string += numbera_number.at(indes);

		if (Number(register_string) < Number(possable_result.at(0))) {
			result_string += '0';
			continue;
		}


		for (number_need_to_multiplier = 0; number_need_to_multiplier < 9; ++number_need_to_multiplier) {
			if (Number(register_string) < Number(possable_result.at(number_need_to_multiplier)))
				break;
		}

		result_string += number_need_to_multiplier + '0';

		register_string = (Number(register_string) - Number(possable_result.at(number_need_to_multiplier - 1))).m_number_to_string();
	}

	if (result_string.empty() == false) {
		result_string.insert(result_string.size() - 1, 1, '.');

		if (result_string.at(0) == '.')
			result_string.insert(0, 1, '0');

		if (result_is_positive == false)
			result_string.insert(0, 1, '-');
		return Number(result_string);
	}

	return Number();
}

//未測試 Bug

 

举报
EMCJava
发帖于8个月前 0回/96阅
顶部