浏览代码

Adding other comparison operators.
Fixing typo in compare shortcut.

Samuel Jaffe 8 年之前
父节点
当前提交
3d7a2065a9
共有 2 个文件被更改,包括 52 次插入24 次删除
  1. 6 0
      include/bigdecimal.h
  2. 46 24
      src/bigdecimal.cpp

+ 6 - 0
include/bigdecimal.h

@@ -56,7 +56,13 @@ namespace math {
     friend bigdecimal & operator-=(bigdecimal &, bigdecimal const &);
     friend bigdecimal & operator*=(bigdecimal &, bigdecimal const &);
     friend bigdecimal & operator/=(bigdecimal &, bigdecimal const &);
+    
     friend bool operator==(bigdecimal const &, bigdecimal const &);
+    friend bool operator!=(bigdecimal const &, bigdecimal const &);
+    friend bool operator<=(bigdecimal const &, bigdecimal const &);
+    friend bool operator< (bigdecimal const &, bigdecimal const &);
+    friend bool operator>=(bigdecimal const &, bigdecimal const &);
+    friend bool operator> (bigdecimal const &, bigdecimal const &);
     
     std::string to_string() const;
   private:

+ 46 - 24
src/bigdecimal.cpp

@@ -20,6 +20,30 @@ static size_t mul_scale(int32_t scale) {
   return scale < 0 ? 0 : size_t(add_scale(scale));
 }
 
+static bool all_zero(bigdecimal::data_type const & data, size_t from) {
+  for (size_t i = from; i > 0; --i) {
+    if (data[i-1] != 0) return false;
+  }
+  return true;
+}
+
+static int compare(bigdecimal::data_type const & ldata, bigdecimal::data_type const & rdata, size_t offset) {
+  auto cmp = detail::compare(ldata, rdata, offset);
+  if (cmp == 0) { return !all_zero(ldata, offset); }
+  return cmp;
+}
+
+static int compare(bigdecimal::data_type const & ldata, int32_t lsteps, bigdecimal::data_type const & rdata, int32_t rsteps) {
+  return lsteps < rsteps ?
+  compare(rdata, ldata, size_t(rsteps - lsteps))
+  : -compare(ldata, rdata, size_t(lsteps - rsteps));
+}
+
+static bool is_one(bigdecimal::data_type const & data, int32_t scale) {
+  static bigdecimal::data_type ONE = {1};
+  return compare(data, add_scale(scale), ONE, 0) == 0;
+}
+
 static void read(int32_t & dst, char const * & str, size_t len) {
   char seg[bigdecimal::SEG_DIGITS+1] = "";
   strncpy(seg, str, len);
@@ -142,30 +166,6 @@ bigdecimal & math::operator-=(bigdecimal & rhs, bigdecimal const & lhs) {
   return rhs;
 }
 
-static bool all_zero(bigdecimal::data_type const & data, size_t from) {
-  for (size_t i = from; i > 0; --i) {
-    if (data[i-1] != 0) return false;
-  }
-  return true;
-}
-
-static int compare(bigdecimal::data_type const & ldata, bigdecimal::data_type const & rdata, size_t offset) {
-  auto cmp = detail::compare(ldata, rdata, offset);
-  if (cmp == 0) { return !all_zero(ldata, offset); }
-  return cmp;
-}
-
-static int compare(bigdecimal::data_type const & ldata, int32_t lsteps, bigdecimal::data_type const & rdata, int32_t rsteps) {
-  return lsteps < rsteps ?
-    compare(rdata, ldata, size_t(rsteps - lsteps))
-  : compare(ldata, rdata, size_t(lsteps - rsteps));
-}
-
-static bool is_one(bigdecimal::data_type const & data, int32_t scale) {
-  static bigdecimal::data_type ONE = {1};
-  return compare(data, add_scale(scale), ONE, 0) == 0;
-}
-
 bigdecimal & math::operator*=(bigdecimal & rhs, bigdecimal const & lhs) {
   int32_t const new_scale = rhs.scale() + lhs.scale();
   bool is_neg = rhs.is_negative != lhs.is_negative;
@@ -237,6 +237,28 @@ bool math::operator==(bigdecimal const & lhs, bigdecimal const & rhs) {
   return lhs.is_negative == rhs.is_negative && compare(lhs.data, lhs.steps_, rhs.data, rhs.steps_) == 0;
 }
 
+bool math::operator!=(bigdecimal const & rhs, bigdecimal const & lhs) {
+  return !(rhs == lhs);
+}
+
+bool math::operator<=(bigdecimal const & rhs, bigdecimal const & lhs) {
+  return !(rhs > lhs);
+}
+
+bool math::operator< (bigdecimal const & rhs, bigdecimal const & lhs) {
+  if (rhs.is_negative != lhs.is_negative) { return rhs.is_negative; }
+  else if (rhs.is_negative) { return compare(rhs.data, rhs.steps_, lhs.data, lhs.steps_) > 0; }
+  else { return compare(rhs.data, rhs.steps_, lhs.data, lhs.steps_) < 0; }
+}
+
+bool math::operator>=(bigdecimal const & rhs, bigdecimal const & lhs) {
+  return !(rhs < lhs);
+}
+
+bool math::operator> (bigdecimal const & rhs, bigdecimal const & lhs) {
+  return lhs < rhs;
+}
+
 bigdecimal const bigdecimal::ZERO{0}, bigdecimal::ONE{1}, bigdecimal::NEGATIVE_ONE{-1};
 
 std::string bigdecimal::to_string() const {