XChinux |
2012-09-22 18:32 |
mpmath.cpp
/** * mpmath浮点数精确计算简单封装, 依赖于GMP库 * (C) 2012 by XChinux@163.com */ #include <sstream> #include <gmp.h> #include "mpmath.hpp"
namespace ChinuxTeam { enum mp_op_t {op_add, op_sub, op_mul, op_div}; std::string mp_op(mp_op_t op, const std::string &arg1, const std::string &arg2, int prec);
std::string mp_add(const char *arg1, const char *arg2, int prec) { return mp_op(op_add, std::string(arg1), std::string(arg2), prec); }
std::string mp_sub(const char *arg1, const char *arg2, int prec) { return mp_op(op_sub, std::string(arg1), std::string(arg2), prec); }
std::string mp_mul(const char *arg1, const char *arg2, int prec) { return mp_op(op_mul, std::string(arg1), std::string(arg2), prec); }
std::string mp_div(const char *arg1, const char *arg2, int prec) { return mp_op(op_div, std::string(arg1), std::string(arg2), prec); }
std::string mp_fmt(const char *arg1, int prec, bool show_thousand_digit_symbol) { return mp_fmt(std::string(arg1), prec, show_thousand_digit_symbol); }
int mp_comp(const char *arg1, const char *arg2) { return mp_comp(std::string(arg1), std::string(arg2)); }
//-------------------------------------------------------------------
QString mp_add(const QString &arg1, const QString &arg2, int prec) { return QString::fromStdString(mp_op(op_add, arg1.toStdString(), arg2.toStdString(), prec)); }
QString mp_sub(const QString &arg1, const QString &arg2, int prec) { return QString::fromStdString(mp_op(op_sub, arg1.toStdString(), arg2.toStdString(), prec)); }
QString mp_mul(const QString &arg1, const QString &arg2, int prec) { return QString::fromStdString(mp_op(op_mul, arg1.toStdString(), arg2.toStdString(), prec)); }
QString mp_div(const QString &arg1, const QString &arg2, int prec) { return QString::fromStdString(mp_op(op_div, arg1.toStdString(), arg2.toStdString(), prec)); }
QString mp_fmt(const QString &arg1, int prec, bool show_thousand_digit_symbol) { return QString::fromStdString(mp_fmt(arg1.toStdString(), prec, show_thousand_digit_symbol)); }
int mp_comp(const QString &arg1, const QString &arg2) { return mp_comp(arg1.toStdString(), arg2.toStdString()); }
//----------------------------------------------------------------------
std::string mp_add(const std::string &arg1, const std::string &arg2, int prec) { return mp_op(op_add, arg1, arg2, prec); }
std::string mp_sub(const std::string &arg1, const std::string &arg2, int prec) { return mp_op(op_sub, arg1, arg2, prec); }
std::string mp_mul(const std::string &arg1, const std::string &arg2, int prec) { return mp_op(op_mul, arg1, arg2, prec); }
std::string mp_div(const std::string &arg1, const std::string &arg2, int prec) { return mp_op(op_div, arg1, arg2, prec); }
int mp_comp(const std::string &arg1, const std::string &arg2) { std::string::size_type pos1 = arg1.find_last_of("."); std::string::size_type pos2 = arg2.find_last_of("."); int prec1 = pos1 == std::string::npos ? 0 : (arg1.size() - pos1 - 1); int prec2 = pos2 == std::string::npos ? 0 : (arg2.size() - pos2 - 1);
mpf_t f1, f2; mpf_init2(f1, prec1); mpf_init2(f2, prec2); mpf_set_str(f1, arg1.c_str(), 10); mpf_set_str(f2, arg2.c_str(), 10); int ret = mpf_cmp(f1, f2); mpf_clear(f1); mpf_clear(f2); return ret; }
std::string mp_fmt(const std::string &arg1, int prec, bool show_thousand_digit_symbol) { mpf_t f1; mpf_init2(f1, prec); mpf_set_str(f1, arg1.c_str(), 10);
std::ostringstream fmt; fmt << "%." << prec << "Ff";
char *ret; int len = gmp_asprintf(&ret, fmt.str().c_str(), f1);
mpf_clear(f1);
std::string str(ret); __gmp_free_func(ret, len); ret = NULL;
if (!show_thousand_digit_symbol) { return str; }
int pos = str.size() - (prec > 0 ? (4 + prec) : 3); while (pos > 0) { str.insert(pos, 1, ','); pos -= 3; } return str; }
std::string mp_op(mp_op_t op, const std::string &arg1, const std::string &arg2, int prec) { std::string::size_type pos2 = arg2.find_last_of("."); int prec2 = pos2 == std::string::npos ? 0 : (arg2.size() - pos2 - 1);
mpf_t f2; mpf_init2(f2, prec2); mpf_set_str(f2, arg2.c_str(), 10);
if (op == op_div) { if (mpf_cmp_si(f2, 0) == 0) { mpf_clear(f2); return std::string(); } } std::string::size_type pos1 = arg1.find_last_of("."); int prec1 = pos1 == std::string::npos ? 0 : (arg1.size() - pos1 - 1);
mpf_t f1, f3; mpf_init2(f1, prec1); mpf_init2(f3, prec); mpf_set_str(f1, arg1.c_str(), 10); switch (op) { case op_add: mpf_add(f3, f1, f2); break; case op_sub: mpf_sub(f3, f1, f2); break; case op_mul: mpf_mul(f3, f1, f2); break; case op_div: mpf_div(f3, f1, f2); break; default:; }
std::ostringstream fmt; fmt << "%." << prec << "Ff";
char *ret; int len = gmp_asprintf(&ret, fmt.str().c_str(), f3);
mpf_clear(f1); mpf_clear(f2); mpf_clear(f3);
std::string str(ret); __gmp_free_func(ret, len); ret = NULL; return str; } }
|
|