Browse Source

Fixing to_string output when scale is negative.

Samuel Jaffe 8 năm trước cách đây
mục cha
commit
a855123300
2 tập tin đã thay đổi với 22 bổ sung159 xóa
  1. 5 5
      src/bigdecimal.cpp
  2. 17 154
      test/bigdecimal.t.h

+ 5 - 5
src/bigdecimal.cpp

@@ -12,14 +12,14 @@
 
 using namespace math;
 
-static size_t mul_scale(int32_t scale) {
-  return scale < 0 ? 0 : size_t(scale / bigdecimal::SEG_DIGITS);
-}
-
 static int32_t add_scale(int32_t scale) {
   return scale / bigdecimal::SEG_DIGITS + (scale > 0 ? 1 : 0);
 }
 
+static size_t mul_scale(int32_t scale) {
+  return scale < 0 ? 0 : size_t(add_scale(scale));
+}
+
 static void read(int32_t & dst, char const * & str, size_t len) {
   char seg[bigdecimal::SEG_DIGITS+1] = "";
   strncpy(seg, str, len);
@@ -192,7 +192,7 @@ std::string bigdecimal::to_string() const {
     int32_t const val = scale_ % SEG_DIGITS;
     sprintf(output.data() + idx, "%0.*d", val, data[0]/detail::powers[SEG_DIGITS-val]);
   } else if (scale_ < 0) {
-    
+    output.insert(output.begin() + idx, size_t(-SEG_DIGITS*add_scale(scale_)), '0');
   }
   return output.data();
 }

+ 17 - 154
test/bigdecimal.t.h

@@ -50,6 +50,11 @@ public:
     TS_ASSERT_EQUALS(scl.to_string(), "100");
   }
   
+  void testScaleBelowNegSegDoesntLoseAnything() {
+    TS_ASSERT_EQUALS(math::bigdecimal("1000000000", -9).to_string(),
+                     "1000000000");
+  }
+  
   void testAddTwoDecimalsSameScale() {
     using bd = math::bigdecimal;
     bd a("1000.10");
@@ -80,158 +85,16 @@ public:
     TS_ASSERT_EQUALS((b-a).to_string(), "99.90");
   }
 
-//  void testAddPastBounds() {
-//    math::bigdecimal bi{999999999ULL};
-//    TS_ASSERT_EQUALS((bi+1).to_string(), "1000000000");
-//  }
-//  
-//  void testAddReciprocalIsZero() {
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS((bi+(-bi)).to_string(), "0");
-//  }
-//  
-//  void testAddNegativeLargerGivesNegative() {
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS((bi+(-1001)).to_string(), "-1");
-//  }
-//  
-//  void testAddNegativeSmallerGivesPositive() {
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS((bi+(-999)).to_string(), "1");
-//  }
-//  
-//  void testSubSelfIsZero() {
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS((bi-bi).to_string(), "0");
-//  }
-//  
-//  void testNegativeMinusNegativeIncreateAbs() {
-//    math::bigdecimal bi{-1000};
-//    TS_ASSERT_EQUALS((bi-100).to_string(), "-1100");
-//  }
-//  
-//  void testSubLargerGivesNegative() {
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS((bi-1001).to_string(), "-1");
-//  }
-//  
-//  void testSubSmallerGivesPositive() {
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS((bi-999).to_string(), "1");
-//  }
-//  
-//  void testSubUnderflowBorrows() {
-//    math::bigdecimal bi{1000000000ULL};
-//    TS_ASSERT_EQUALS((bi-1).to_string(), "999999999");
-//  }
-//  
-//  void testMultiplyZeroReturnsZero() {
-//    auto &ZERO =  math::bigdecimal::ZERO;
-//    math::bigdecimal bi{999999999ULL};
-//    TS_ASSERT_EQUALS(bi*ZERO, ZERO);
-//    TS_ASSERT_EQUALS(ZERO*bi, ZERO);
-//  }
-//  
-//  void testMultiplyOneReturnsValue() {
-//    auto &ONE =  math::bigdecimal::ONE;
-//    math::bigdecimal bi{999999999ULL};
-//    TS_ASSERT_EQUALS((bi*ONE).to_string(), "999999999");
-//    TS_ASSERT_EQUALS((ONE*bi).to_string(), "999999999");
-//  }
-//  
-//  void testMultiplyNegativeOneReturnsInverse() {
-//    auto &NEGATIVE_ONE =  math::bigdecimal::NEGATIVE_ONE;
-//    math::bigdecimal bi{999999999ULL};
-//    TS_ASSERT_EQUALS((bi*NEGATIVE_ONE).to_string(), "-999999999");
-//    TS_ASSERT_EQUALS((NEGATIVE_ONE*bi).to_string(), "-999999999");
-//  }
-//  
-//  void testMultiplyOverflowsIntoNextCell() {
-//    math::bigdecimal bi{999999999ULL};
-//    TS_ASSERT_EQUALS((bi*bi).to_string(), "999999998000000001");
-//  }
-//  
-//  void testMultiplyCarryIntoNextCell() {
-//    math::bigdecimal bi{999999999ULL};
-//    math::bigdecimal big{bi*bi};
-//    TS_ASSERT_EQUALS((big*big).to_string(),
-//                     "999999996000000005999999996000000001");
-//  }
-//  
-//  void testMultiplyNoOverflow() {
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS((bi*bi).to_string(), "1000000");
-//  }
-//
-//  void testDivideByZeroThrows() {
-//    auto &ZERO =  math::bigdecimal::ZERO;
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_THROWS(bi/ZERO, std::domain_error);
-//  }
-//  
-//  void testDivideByOneReturnsValue() {
-//    auto &ONE =  math::bigdecimal::ONE;
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS(bi/ONE, bi);
-//  }
-//  
-//  void testDivideByNegativeOneReturnsInverse() {
-//    auto &NEGATIVE_ONE =  math::bigdecimal::NEGATIVE_ONE;
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS((bi/NEGATIVE_ONE).to_string(), "-1000");
-//  }
-//  
-//  void testDivisionWithMultipleMultSubSteps() {
-//    math::bigdecimal bi{1112};
-//    TS_ASSERT_EQUALS((bi/2).to_string(), "556");
-//  }
-//  
-//  void testDivisionDroppingNumberOfCells() {
-//    math::bigdecimal bi{1000000000ULL};
-//    TS_ASSERT_EQUALS((bi/2).to_string(), "500000000");
-//  }
-//  
-//  void testDivisionByBiggerNumberIsZero() {
-//    math::bigdecimal bi{1000ULL};
-//    TS_ASSERT_EQUALS((bi/1001).to_string(), "0");
-//  }
-//  
-//  void testDivisionWithLargeNumbers() {
-//    math::bigdecimal big{"999999998000000001"};
-//    TS_ASSERT_EQUALS(big.to_string(), "999999998000000001");
-//    TS_ASSERT_EQUALS((big/999999999ULL).to_string(),
-//                     "999999999");
-//  }
-//  
-//  void testModuloZeroThrows() {
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_THROWS(bi%0, std::domain_error);
-//  }
-//  
-//  void testModuloBiggerIsSameValue() {
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS(bi%2000, bi);
-//  }
-//  
-//  void testModuloSameNumberIsZero() {
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS(bi%1000, 0);
-//  }
-//  
-//  void testModuloDivisorIsZero() {
-//    math::bigdecimal bi{1000};
-//    TS_ASSERT_EQUALS(bi%100, 0);
-//  }
-//  
-//  void testModuloDiffSignIsInverseElement() {
-//    math::bigdecimal bi{1000};
-//    math::bigdecimal mod{13};
-//    TS_ASSERT_EQUALS((bi%mod)+((-bi)%mod), mod);
-//  }
-//  
-//  void testModuloNegativesIsNegative() {
-//    math::bigdecimal bi{1000};
-//    math::bigdecimal mod{13};
-//    TS_ASSERT_EQUALS((bi%mod), -((-bi)%(-mod)));
-//  }
+  void testMultiplicationIncreasesScale() {
+    math::bigdecimal bd("1.1");
+    auto out = bd * bd;
+    TS_ASSERT_EQUALS(out.scale(), bd.scale() + bd.scale());
+    TS_ASSERT_EQUALS(out.to_string(), "1.21");
+  }
+  
+  void testMultiplicationNegativeScaleCountersPositiveScale() {
+    math::bigdecimal a("0.01");
+    math::bigdecimal b("100", -2);
+    TS_ASSERT_EQUALS((a*b).to_string(), "1");
+  }
 };