Created
May 30, 2019 07:04
-
-
Save microcai/a7e502d46cbe05a8265e2e8b0acc5877 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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