浏览代码

Adding new test cases.
Fixing bug with checking if an object is 'ONE'.

Samuel Jaffe 8 年之前
父节点
当前提交
3c3d0eeb5c
共有 2 个文件被更改,包括 44 次插入2 次删除
  1. 15 2
      src/bigdecimal.cpp
  2. 29 0
      test/bigdecimal.t.h

+ 15 - 2
src/bigdecimal.cpp

@@ -141,15 +141,28 @@ 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 = data.size() - from; i < data.size(); ++i) {
+    if (data[i] != 0) return false;
+  }
+  return true;
+}
+
+static bool is_one(bigdecimal::data_type const & data, int32_t scale) {
+  static bigdecimal::data_type ONE = {1};
+  auto ms = mul_scale(scale);
+  return scale >= 0 && detail::compare(data, ONE, ms) == 0 && all_zero(data, ms);
+}
+
 bigdecimal & math::operator*=(bigdecimal & rhs, bigdecimal const & lhs) {
   int32_t const new_scale = rhs.scale_ + lhs.scale_;
   size_t const offset = mul_scale(rhs.scale_) + mul_scale(lhs.scale_) - mul_scale(new_scale);
   bool is_neg = rhs.is_negative != lhs.is_negative;
   if (rhs == bigdecimal::ZERO || lhs == bigdecimal::ZERO) {
     rhs = bigdecimal::ZERO;
-  } else if (detail::compare(lhs.data, bigdecimal::ONE.data) == 0) {
+  } else if (is_one(lhs.data, lhs.scale())) {
     rhs.is_negative = is_neg;
-  } else if (detail::compare(rhs.data, bigdecimal::ONE.data) == 0) {
+  } else if (is_one(rhs.data, rhs.scale())) {
     rhs = lhs;
     rhs.is_negative = is_neg;
   } else {

+ 29 - 0
test/bigdecimal.t.h

@@ -103,6 +103,35 @@ public:
     TS_ASSERT_EQUALS((a*b).to_string(), "1");
   }
   
+  void testMultiplicationCreateNewOffsetCell() {
+    math::bigdecimal C(1, 5);
+    TS_ASSERT_EQUALS((C*C).to_string(), "1.0000000000");
+  }
+
+  void testMultiplicationNegativeToPositiveScale() {
+    math::bigdecimal C(1, 5);
+    math::bigdecimal D(100, -2);
+    TS_ASSERT_EQUALS((D*C).to_string(), "100.000");
+  }
+  
+  void testMultiplicationFromDroppedToNonDropScale() {
+    math::bigdecimal C(1, 5);
+    math::bigdecimal E(1000000000, -9);
+    TS_ASSERT_EQUALS((E*C).to_string(), "1000000000");
+  }
+
+  void testMultiplicationFromDroppedToLowerScale() {
+    math::bigdecimal D(100, -2);
+    math::bigdecimal E(1000000000, -9);
+    TS_ASSERT_EQUALS((E*D).to_string(), "100000000000");
+  }
+
+  void testMultiplicationFromNonDropToDroppedScale() {
+    math::bigdecimal F(10000, -4);
+    math::bigdecimal G(100000, -5);
+    TS_ASSERT_EQUALS((G*F).to_string(), "1000000000");
+  }
+
   void testDivideHigherScaleByLowerScale() {
     math::bigdecimal a("1", 2);
     math::bigdecimal b("1", 1);