-
UID:2
-
- 注册时间2004-11-08
- 最后登录2024-01-27
- 在线时间6994小时
-
- 发帖11224
- 搜Ta的帖子
- 精华61
- 金钱140531
- 威望9948
- 贡献值701
- 好评度8170
-
访问TA的空间加好友用道具
|
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;
- }
- }
|