inline decimal operator*(const decimal& a, const decimal& b) { const int64_t va = a.value() > 0 ? a.value() : -a.value(); const int64_t vb = b.value() > 0 ? b.value() : -b.value(); const int64_t ia = va/DECIMAL_PRECISION; const int64_t ib = vb/DECIMAL_PRECISION; const int64_t fa = va%DECIMAL_PRECISION; const int64_t fb = vb%DECIMAL_PRECISION; const decimal result = decimal(ia*ib*DECIMAL_PRECISION + fa*ib + fb*ia + (fa*fb)/DECIMAL_PRECISION); if(a.value() < 0 && b.value() > 0 || b.value() < 0 && a.value() > 0) { return -result; } else { return result; } }
decimal operator/(const decimal& a, const decimal& b) { int64_t va = a.value() > 0 ? a.value() : -a.value(); int64_t vb = b.value() > 0 ? b.value() : -b.value(); if(va == 0) { return a; } int64_t orders_of_magnitude_shift = 0; const int64_t target_value = DECIMAL(10000000000000); while(va < target_value) { va *= DECIMAL(10); ++orders_of_magnitude_shift; } const int64_t target_value_b = DECIMAL(1000000); while(vb > target_value_b) { vb /= DECIMAL(10); ++orders_of_magnitude_shift; } int64_t value = (va/vb); while(orders_of_magnitude_shift > 6) { value /= DECIMAL(10); --orders_of_magnitude_shift; } while(orders_of_magnitude_shift < 6) { value *= DECIMAL(10); ++orders_of_magnitude_shift; } const decimal result(decimal::from_raw_value(value)); if(a.value() < 0 && b.value() > 0 || b.value() < 0 && a.value() > 0) { return -result; } else { return result; } }
explicit variant(decimal d) : type_(VARIANT_TYPE_DECIMAL), decimal_value_(d.value()) {}
inline bool operator<=(const decimal& a, const decimal& b) { return a.value() <= b.value(); }
inline decimal operator-(const decimal& a, const decimal& b) { return decimal(a.value() - b.value()); }