Skip to content

Instantly share code, notes, and snippets.

@microcai
Created May 30, 2019 07:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save microcai/a7e502d46cbe05a8265e2e8b0acc5877 to your computer and use it in GitHub Desktop.
Save microcai/a7e502d46cbe05a8265e2e8b0acc5877 to your computer and use it in GitHub Desktop.
class decimal
{
long long fixed_float;
public:
decimal() : fixed_float(0) {}
decimal(int i) : fixed_float(i * 10000) {}
decimal(unsigned i) : fixed_float(i * 10000) {}
decimal(long i) : fixed_float(i * 10000) {}
decimal(unsigned long i) : fixed_float(i * 10000) {}
decimal(float i) : fixed_float( i * 10000 + 0.5) {};
decimal(double i) : fixed_float( i * 10000 + 0.5) {};
decimal(long double i) : fixed_float( i * 10000 + 0.5) {};
decimal(const std::string& string_reprent);
decimal(const char string_reprent[]) : decimal(std::string(string_reprent)){}
public: // io
operator std::string() const; // as string
public: // operations
friend decimal operator + (const decimal& a, const decimal& b);
friend decimal operator - (const decimal& a, const decimal& b);
friend decimal operator * (const decimal& a, const decimal& b);
friend decimal operator / (const decimal& a, const decimal& b);
friend decimal operator % (const decimal& a, const decimal& b);
decimal& operator+= (const decimal& o){ fixed_float += o.fixed_float; return *this; }
decimal& operator-= (const decimal& o){ fixed_float -= o.fixed_float; return *this; }
decimal& operator*= (const decimal& o){ fixed_float = fixed_float * o.fixed_float / 10000; return *this; }
decimal& operator/= (const decimal& o){ fixed_float = fixed_float * 10000 / fixed_float; return *this; }
decimal& operator%= (const decimal& o){ fixed_float = fixed_float % fixed_float; return *this; }
};
decimal operator + (const decimal& a, const decimal& b)
{
decimal r;
r.fixed_float = a.fixed_float + b.fixed_float;
return r;
}
decimal operator - (const decimal& a, const decimal& b)
{
decimal r;
r.fixed_float = a.fixed_float - b.fixed_float;
return r;
}
decimal operator * (const decimal& a, const decimal& b)
{
decimal r;
r.fixed_float = a.fixed_float * b.fixed_float / 10000;
return r;
}
decimal operator / (const decimal& a, const decimal& b)
{
decimal r;
r.fixed_float = a.fixed_float * 10000 / b.fixed_float;
return r;
}
decimal operator % (const decimal& a, const decimal& b)
{
decimal r;
r.fixed_float = a.fixed_float % b.fixed_float;
return r;
}
decimal::decimal(const std::string& string_reprent)
{
auto dot_pos = string_reprent.find('.');
if (dot_pos == std::string::npos)
{
fixed_float = 10000 * std::strtoll(string_reprent.c_str(), nullptr, 10);
}
else
{
std::string int_part = string_reprent.substr(0, dot_pos);
std::string xiaoshu_part = string_reprent.substr( dot_pos + 1 );
fixed_float = 10000 * std::strtoll(int_part.c_str(), nullptr, 10);
// 补齐 tailing 0
if (xiaoshu_part.length() < 4)
xiaoshu_part.insert(xiaoshu_part.end(), 4 - xiaoshu_part.length(), '0');
fixed_float += std::strtoll(xiaoshu_part.c_str(), nullptr, 10);
}
}
decimal::operator std::string() const
{
auto fixed_float_ = fixed_float;
if (fixed_float_ >= 0)
{
auto int_part = std::to_string( (fixed_float_ / 10000) );
if (fixed_float_ % 10000 != 0)
{
std::string xiaoshu_part = std::to_string( (fixed_float_ % 10000) );
if (xiaoshu_part.length() < 4)
xiaoshu_part.insert(xiaoshu_part.begin(), 4 - xiaoshu_part.length(), '0');
// remove tailing 0
while(*xiaoshu_part.rbegin() == '0')
xiaoshu_part.pop_back();
return int_part + "." + xiaoshu_part;
}
return int_part;
}
else
{
fixed_float_ = - fixed_float;
auto int_part = std::to_string( (fixed_float_ / 10000) );
if (fixed_float_ % 10000 != 0)
{
std::string xiaoshu_part = std::to_string( (fixed_float_ % 10000) );
if (xiaoshu_part.length() < 4)
xiaoshu_part.insert(xiaoshu_part.begin(), 4 - xiaoshu_part.length(), '0');
// remove tailing 0
while(*xiaoshu_part.rbegin() == '0')
xiaoshu_part.pop_back();
return "-" + int_part + "." + xiaoshu_part;
}
return "-" + int_part;
}
}
#include <iostream>
int main(int argc, char **argv)
{
decimal a = "2.1";
decimal b = 4;
auto c = a * b;
auto d = a + b;
auto e = a - b;
auto f = b / a;
std::cerr << (std::string) c << std::endl;
std::cerr << (std::string) d << std::endl;
std::cerr << (std::string) e << std::endl;
std::cerr << (std::string) f << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment