Skip to content

Instantly share code, notes, and snippets.

@Heimdell
Last active August 29, 2015 13:57
Show Gist options
  • Save Heimdell/9587995 to your computer and use it in GitHub Desktop.
Save Heimdell/9587995 to your computer and use it in GitHub Desktop.
#pragma once
#include <cmath>
#include <iostream>
using namespace std;
static constexpr int pow(int x, int n) {
return n == 0? 1 : x * pow(x, n - 1);
}
template <int pointPos = 3>
struct decimal
{
enum { divisor = pow(10, pointPos) };
typedef long long carrier;
carrier value;
decimal() : value(0) { }
decimal(int value) : value( value * divisor ) { }
decimal(float value) : value(::round(value * divisor)) { }
decimal(double value) : value(::round(value * divisor)) { }
decimal(const decimal &other) : value(other.value) { }
static decimal fromRaw(carrier c) {
decimal d { 0 }; d.value = c; return d;
}
static decimal one() {
return fromRaw(divisor);
}
decimal operator + () {
return *this;
}
decimal operator - () {
return fromRaw(- value);
}
decimal operator + (decimal other) {
return fromRaw(value + other.value);
}
decimal operator - (decimal other) {
return fromRaw(value - other.value);
}
decimal operator * (decimal other) {
return fromRaw(value * other.value / divisor);
}
decimal operator / (decimal other) {
return fromRaw(::round(value / ((double) other.value / divisor)));
}
decimal operator % (decimal other) {
return operator - (other * operator / (other));
}
explicit operator int() { return value / divisor; }
explicit operator float() { return (float) value / divisor; }
explicit operator double() { return (double) value / divisor; }
friend ostream &operator << (ostream &o, decimal number) {
auto width = o.width();
auto fill = o.fill();
auto flags = o.flags();
o << (number.value / divisor) << '.';
o.width(pointPos);
o.fill('0');
o << right << abs(number.value % divisor);
o.width(width);
o.fill(fill);
o.flags(flags);
return o;
}
friend istream &operator >> (istream &is, decimal &number) {
double val;
is >> val;
number = val;
return is;
}
decimal round() {
return fromRaw(value / divisor * divisor);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment