Browse Source

Add clang-format, move includes into proper directory, more settings changes

Sam Jaffe 4 years ago
parent
commit
99d12f1327

+ 108 - 0
.clang-format

@@ -0,0 +1,108 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands:   true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: true
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:   
+  AfterClass:      false
+  AfterControlStatement: false
+  AfterEnum:       false
+  AfterFunction:   false
+  AfterNamespace:  false
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  BeforeCatch:     false
+  BeforeElse:      false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Attach
+BreakBeforeInheritanceComma: false
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: true
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: false
+ForEachMacros:   
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IncludeCategories: 
+  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+    Priority:        2
+  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
+    Priority:        3
+  - Regex:           '.*'
+    Priority:        1
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+IndentWidth:     2
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: All
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Middle
+ReflowComments:  true
+SortIncludes:    true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Cpp11
+TabWidth:        8
+UseTab:          Never
+...
+

+ 4 - 22
bigdecimal.xcodeproj/project.pbxproj

@@ -7,9 +7,7 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		CD2EC1BC1F0AF2C300D49DF5 /* bigdecimal.h in Headers */ = {isa = PBXBuildFile; fileRef = CD2EC1BB1F0AF2C300D49DF5 /* bigdecimal.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		CD2EC1BF1F0AF3B800D49DF5 /* bigdecimal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD2EC1BE1F0AF3B800D49DF5 /* bigdecimal.cpp */; };
-		CD2EC1C21F0BCCA700D49DF5 /* bignum_helper.h in Headers */ = {isa = PBXBuildFile; fileRef = CD2EC1C11F0BCCA700D49DF5 /* bignum_helper.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		CD2EC1C51F0BCCBF00D49DF5 /* bignum_helper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD2EC1C41F0BCCBF00D49DF5 /* bignum_helper.cpp */; };
 		CD3979042528D8480021B537 /* bignumber_test_printers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDB7F52E20B19E0D0053645C /* bignumber_test_printers.cpp */; };
 		CD47694820AFA150009AA8BB /* libbigdecimal.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5FB2861F06EFEA005A0D61 /* libbigdecimal.dylib */; };
@@ -18,7 +16,6 @@
 		CD47698B20AFB4FD009AA8BB /* bigdecimal_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD14CA711F0DA9FC0091A168 /* bigdecimal_test.cpp */; };
 		CD47698C20B03C5E009AA8BB /* biginteger_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD47697520AFA6B2009AA8BB /* biginteger_test.cpp */; };
 		CD5FB2911F06EFEF005A0D61 /* biginteger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5FB2801F06EF7D005A0D61 /* biginteger.cpp */; };
-		CD5FB2921F06EFF2005A0D61 /* biginteger.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5FB27F1F06EF70005A0D61 /* biginteger.h */; settings = {ATTRIBUTES = (Public, ); }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -68,18 +65,16 @@
 
 /* Begin PBXFileReference section */
 		CD14CA711F0DA9FC0091A168 /* bigdecimal_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bigdecimal_test.cpp; sourceTree = "<group>"; };
-		CD2EC1BB1F0AF2C300D49DF5 /* bigdecimal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bigdecimal.h; sourceTree = "<group>"; };
 		CD2EC1BE1F0AF3B800D49DF5 /* bigdecimal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bigdecimal.cpp; sourceTree = "<group>"; };
-		CD2EC1C11F0BCCA700D49DF5 /* bignum_helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bignum_helper.h; sourceTree = "<group>"; };
 		CD2EC1C41F0BCCBF00D49DF5 /* bignum_helper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bignum_helper.cpp; sourceTree = "<group>"; };
 		CD3B82A31F114E1C0081E9FC /* bignumber_integral_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bignumber_integral_test.cpp; sourceTree = "<group>"; };
 		CD47694320AFA150009AA8BB /* bigdecimal-test.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "bigdecimal-test.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
 		CD47694720AFA150009AA8BB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		CD47697520AFA6B2009AA8BB /* biginteger_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = biginteger_test.cpp; sourceTree = "<group>"; };
 		CD47697820AFAC9C009AA8BB /* GoogleMock.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GoogleMock.xcodeproj; path = "../../../gmock-xcode-master/GoogleMock.xcodeproj"; sourceTree = "<group>"; };
-		CD5FB27F1F06EF70005A0D61 /* biginteger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = biginteger.h; sourceTree = "<group>"; };
 		CD5FB2801F06EF7D005A0D61 /* biginteger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = biginteger.cpp; sourceTree = "<group>"; };
 		CD5FB2861F06EFEA005A0D61 /* libbigdecimal.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libbigdecimal.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+		CD8176CC25C5A4100043E7E7 /* include */ = {isa = PBXFileReference; lastKnownFileType = folder; path = include; sourceTree = "<group>"; };
 		CDB7F52D20B19D3F0053645C /* bignumber_test_printers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bignumber_test_printers.h; sourceTree = "<group>"; };
 		CDB7F52E20B19E0D0053645C /* bignumber_test_printers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bignumber_test_printers.cpp; sourceTree = "<group>"; };
 /* End PBXFileReference section */
@@ -127,7 +122,7 @@
 			isa = PBXGroup;
 			children = (
 				CD47697820AFAC9C009AA8BB /* GoogleMock.xcodeproj */,
-				CD5FB27B1F06EED6005A0D61 /* include */,
+				CD8176CC25C5A4100043E7E7 /* include */,
 				CD5FB27C1F06EED6005A0D61 /* src */,
 				CD5FB27D1F06EED6005A0D61 /* test */,
 				CD47694420AFA150009AA8BB /* bigdecimal-test */,
@@ -144,16 +139,6 @@
 			name = Products;
 			sourceTree = "<group>";
 		};
-		CD5FB27B1F06EED6005A0D61 /* include */ = {
-			isa = PBXGroup;
-			children = (
-				CD5FB27F1F06EF70005A0D61 /* biginteger.h */,
-				CD2EC1BB1F0AF2C300D49DF5 /* bigdecimal.h */,
-				CD2EC1C11F0BCCA700D49DF5 /* bignum_helper.h */,
-			);
-			path = include;
-			sourceTree = "<group>";
-		};
 		CD5FB27C1F06EED6005A0D61 /* src */ = {
 			isa = PBXGroup;
 			children = (
@@ -183,9 +168,6 @@
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				CD5FB2921F06EFF2005A0D61 /* biginteger.h in Headers */,
-				CD2EC1BC1F0AF2C300D49DF5 /* bigdecimal.h in Headers */,
-				CD2EC1C21F0BCCA700D49DF5 /* bignum_helper.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -422,7 +404,7 @@
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = "";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.15;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				ONLY_ACTIVE_ARCH = YES;
 				SDKROOT = macosx;
@@ -475,7 +457,7 @@
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = "";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.15;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				SDKROOT = macosx;
 				USER_HEADER_SEARCH_PATHS = include;

+ 29 - 20
include/bigdecimal.h

@@ -14,41 +14,49 @@ namespace math {
   class bigdecimal {
   private:
     template <typename Int>
-    using is_signed_t = typename std::enable_if<std::numeric_limits<Int>::is_integer && std::numeric_limits<Int>::is_signed, void*>::type;
+    using is_signed_t =
+        typename std::enable_if<std::numeric_limits<Int>::is_integer &&
+                                    std::numeric_limits<Int>::is_signed,
+                                void *>::type;
     template <typename Int>
-    using is_unsigned_t = typename std::enable_if<std::numeric_limits<Int>::is_integer && !std::numeric_limits<Int>::is_signed, void*>::type;
+    using is_unsigned_t =
+        typename std::enable_if<std::numeric_limits<Int>::is_integer &&
+                                    !std::numeric_limits<Int>::is_signed,
+                                void *>::type;
+
   public:
     using data_type = std::vector<int32_t>;
     static bigdecimal const ZERO, ONE, NEGATIVE_ONE;
-    static constexpr int32_t const MAX_SEG   { 999999999};
-    static constexpr int32_t const OVER_SEG  {1000000000};
-    static constexpr int32_t const SEG_DIGITS{         9};
+    static constexpr int32_t const MAX_SEG{999999999};
+    static constexpr int32_t const OVER_SEG{1000000000};
+    static constexpr int32_t const SEG_DIGITS{9};
+
   public:
     bigdecimal();
 
     template <typename Value>
-    bigdecimal(Value && value, int32_t scale)
-    : bigdecimal(value) {
+    bigdecimal(Value && value, int32_t scale) : bigdecimal(value) {
       rescale(scale);
     }
-    
+
     template <typename Int>
     bigdecimal(Int value, is_signed_t<Int> = nullptr)
-    : bigdecimal(value < 0, static_cast<uint64_t>(value < 0 ? -value : value)) {}
-    
+        : bigdecimal(value < 0,
+                     static_cast<uint64_t>(value < 0 ? -value : value)) {}
+
     template <typename Int>
     bigdecimal(Int value, is_unsigned_t<Int> = nullptr)
-    : bigdecimal(false, static_cast<uint64_t>(value)) {}
+        : bigdecimal(false, static_cast<uint64_t>(value)) {}
 
     bigdecimal(long double);
     bigdecimal(char const *);
-    
+
     int32_t scale() const { return scale_; }
     void rescale(int32_t);
     void set_value(bigdecimal const &);
-    
+
     bigdecimal operator-() const;
-    
+
     friend bigdecimal operator+(bigdecimal, bigdecimal const &);
     friend bigdecimal operator-(bigdecimal, bigdecimal const &);
     friend bigdecimal operator*(bigdecimal, bigdecimal const &);
@@ -57,20 +65,21 @@ 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 &);
-    friend bool operator> (bigdecimal const &, bigdecimal const &);
-    
+    friend bool operator>(bigdecimal const &, bigdecimal const &);
+
     std::string to_string() const;
+
   private:
     bigdecimal(bool, uint64_t);
     void set_scale(int32_t);
     void subtract_impl(bigdecimal const &, bool);
-    
+
     friend void swap(bigdecimal & rhs, bigdecimal & lhs) {
       using std::swap;
       swap(rhs.is_negative, lhs.is_negative);
@@ -78,7 +87,7 @@ namespace math {
       swap(rhs.steps_, lhs.steps_);
       swap(rhs.data, lhs.data);
     }
-    
+
     bool is_negative;
     int32_t scale_{0}, steps_{0};
     data_type data{};

+ 22 - 12
include/biginteger.h

@@ -14,27 +14,36 @@ namespace math {
   class biginteger {
   private:
     template <typename Int>
-    using is_signed_t = typename std::enable_if<std::numeric_limits<Int>::is_integer && std::numeric_limits<Int>::is_signed, int>::type;
+    using is_signed_t =
+        typename std::enable_if<std::numeric_limits<Int>::is_integer &&
+                                    std::numeric_limits<Int>::is_signed,
+                                int>::type;
     template <typename Int>
-    using is_unsigned_t = typename std::enable_if<std::numeric_limits<Int>::is_integer && !std::numeric_limits<Int>::is_signed, int>::type;
+    using is_unsigned_t =
+        typename std::enable_if<std::numeric_limits<Int>::is_integer &&
+                                    !std::numeric_limits<Int>::is_signed,
+                                int>::type;
+
   public:
     using data_type = std::vector<int32_t>;
     static biginteger const ZERO, ONE, NEGATIVE_ONE;
-    static constexpr int32_t const MAX_SEG   { 999999999};
-    static constexpr int32_t const OVER_SEG  {1000000000};
-    static constexpr int32_t const SEG_DIGITS{         9};
+    static constexpr int32_t const MAX_SEG{999999999};
+    static constexpr int32_t const OVER_SEG{1000000000};
+    static constexpr int32_t const SEG_DIGITS{9};
+
   public:
     // Constructors
     biginteger();
-    
+
     template <typename Int>
     biginteger(Int value, is_signed_t<Int> = 0)
-    : biginteger(value < 0, static_cast<uint64_t>(value < 0 ? -value : value)) {}
-    
+        : biginteger(value < 0,
+                     static_cast<uint64_t>(value < 0 ? -value : value)) {}
+
     template <typename Int>
     biginteger(Int value, is_unsigned_t<Int> = 0)
-    : biginteger(false, static_cast<uint64_t>(value)) {}
-    
+        : biginteger(false, static_cast<uint64_t>(value)) {}
+
     biginteger(char const *);
     // Unary operators
     biginteger operator-() const;
@@ -54,9 +63,10 @@ namespace math {
     friend bool operator==(biginteger const &, biginteger const &);
     friend bool operator!=(biginteger const &, biginteger const &);
     friend bool operator<=(biginteger const &, biginteger const &);
-    friend bool operator< (biginteger const &, biginteger const &);
+    friend bool operator<(biginteger const &, biginteger const &);
     friend bool operator>=(biginteger const &, biginteger const &);
-    friend bool operator> (biginteger const &, biginteger const &);
+    friend bool operator>(biginteger const &, biginteger const &);
+
   private:
     biginteger(bool, uint64_t);
     void subtract_impl(biginteger const & lhs, bool is_sub);

+ 5 - 3
include/bignum_helper.h

@@ -11,11 +11,13 @@
 
 namespace math { namespace detail {
   using data_type = std::vector<int32_t>;
-  constexpr const int32_t powers[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1 };
+  constexpr const int32_t powers[] = {
+      1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1};
   // 1 => GREATER, 0 => EQUAL, -1 => LESS
   int compare(data_type const & rhs, data_type const & lhs, size_t offset = 0);
   void add(data_type & rhs, data_type const & lhs, size_t offset = 0);
-  void subtract_nounderflow(data_type & rhs, data_type const & lhs, size_t offset = 0);
+  void subtract_nounderflow(data_type & rhs, data_type const & lhs,
+                            size_t offset = 0);
   void multiply(data_type & rhs, data_type const & lhs);
   data_type divide(data_type & remainder, data_type const & divisor);
-} }
+}}

+ 15 - 0
include/math/decimal_format.h

@@ -0,0 +1,15 @@
+//
+//  bigdecimal_format.h
+//  bigdecimal
+//
+//  Created by Sam Jaffe on 1/30/21.
+//  Copyright © 2021 Sam Jaffe. All rights reserved.
+//
+
+#pragma once
+
+namespace math {
+
+  struct decimal_format {};
+
+}

+ 60 - 54
src/bigdecimal.cpp

@@ -5,8 +5,8 @@
 //  Created by Sam Jaffe on 7/3/17.
 //
 
-#include "bigdecimal.h"
-#include "bignum_helper.h"
+#include "math/bigdecimal.h"
+#include "math/bignum_helper.h"
 
 #include <cstdlib>
 
@@ -22,21 +22,22 @@ static size_t mul_scale(int32_t 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;
+    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) {
+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 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) {
@@ -44,28 +45,28 @@ static bool is_one(bigdecimal::data_type const & data, int32_t scale) {
   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] = "";
+static void read(int32_t & dst, char const *& str, size_t len) {
+  char seg[bigdecimal::SEG_DIGITS + 1] = "";
   strncpy(seg, str, len);
   dst = atoi(seg);
   str += len;
 }
 
-static void read_segment(bigdecimal::data_type & data, char const * number, size_t len) {
-  auto elems = len/bigdecimal::SEG_DIGITS;
+static void read_segment(bigdecimal::data_type & data, char const * number,
+                         size_t len) {
+  auto elems = len / bigdecimal::SEG_DIGITS;
   data.resize(elems);
-  if (auto small = len-(elems*bigdecimal::SEG_DIGITS)) {
+  if (auto small = len - (elems * bigdecimal::SEG_DIGITS)) {
     read(*data.emplace(data.end()), number, small);
   }
   for (size_t idx = elems; idx > 0; --idx) {
-    read(data[idx-1], number, bigdecimal::SEG_DIGITS);
+    read(data[idx - 1], number, bigdecimal::SEG_DIGITS);
   }
 }
 
 bigdecimal::bigdecimal() : is_negative(false), data({0}) {}
 
-bigdecimal::bigdecimal(bool neg, uint64_t value) :
-is_negative(neg) {
+bigdecimal::bigdecimal(bool neg, uint64_t value) : is_negative(neg) {
   uint64_t next{0};
   do {
     next = value / OVER_SEG;
@@ -73,20 +74,19 @@ is_negative(neg) {
   } while ((value = next) > 0);
 }
 
-bigdecimal::bigdecimal(char const * number) :
-is_negative(number[0] == '-') {
+bigdecimal::bigdecimal(char const * number) : is_negative(number[0] == '-') {
   if (is_negative) { ++number; }
   if (auto p = strchr(number, '.')) {
     read_segment(data, number, size_t(p - number));
     number = p + 1;
     set_scale(int32_t(strlen(number)));
-    size_t elems = size_t(scale()/SEG_DIGITS);
+    size_t elems = size_t(scale() / SEG_DIGITS);
     data.insert(data.begin(), elems, 0);
     for (size_t idx = elems; idx > 0; --idx) {
-      read(data[idx-1], number, SEG_DIGITS);
+      read(data[idx - 1], number, SEG_DIGITS);
     }
     if (auto l = strlen(number)) {
-      data.insert(data.begin(), atoi(number) * detail::powers[SEG_DIGITS-l]);
+      data.insert(data.begin(), atoi(number) * detail::powers[SEG_DIGITS - l]);
     }
   } else {
     read_segment(data, number, strlen(number));
@@ -136,17 +136,17 @@ void bigdecimal::subtract_impl(bigdecimal const & lhs, bool is_sub) {
   }
 }
 
-bigdecimal bigdecimal::operator-() const {
-  return *this * NEGATIVE_ONE;
-}
+bigdecimal bigdecimal::operator-() const { return *this * NEGATIVE_ONE; }
 
 bigdecimal & math::operator+=(bigdecimal & rhs, bigdecimal const & lhs) {
   int32_t const new_scale = std::max(rhs.scale(), lhs.scale());
   rhs.rescale(new_scale);
   size_t const offset = size_t(rhs.steps_ - lhs.steps_);
-  if (lhs == bigdecimal::ZERO) { return rhs; }
-  else if (rhs == bigdecimal::ZERO) { rhs.set_value(lhs); }
-  else if (rhs.is_negative == lhs.is_negative) {
+  if (lhs == bigdecimal::ZERO) {
+    return rhs;
+  } else if (rhs == bigdecimal::ZERO) {
+    rhs.set_value(lhs);
+  } else if (rhs.is_negative == lhs.is_negative) {
     detail::add(rhs.data, lhs.data, offset);
   } else {
     rhs.subtract_impl(lhs, false);
@@ -158,9 +158,11 @@ bigdecimal & math::operator-=(bigdecimal & rhs, bigdecimal const & lhs) {
   int32_t const new_scale = std::max(rhs.scale(), lhs.scale());
   rhs.rescale(new_scale);
   size_t const offset = size_t(rhs.steps_ - lhs.steps_);
-  if (lhs == bigdecimal::ZERO) { return rhs; }
-  else if (rhs == bigdecimal::ZERO) { rhs.set_value(-lhs); }
-  else if (rhs.is_negative != lhs.is_negative) {
+  if (lhs == bigdecimal::ZERO) {
+    return rhs;
+  } else if (rhs == bigdecimal::ZERO) {
+    rhs.set_value(-lhs);
+  } else if (rhs.is_negative != lhs.is_negative) {
     detail::add(rhs.data, lhs.data, offset);
   } else {
     rhs.subtract_impl(lhs, true);
@@ -181,9 +183,7 @@ bigdecimal & math::operator*=(bigdecimal & rhs, bigdecimal const & lhs) {
   } else {
     detail::multiply(rhs.data, lhs.data);
     auto diff = add_scale(new_scale) - rhs.steps_ - lhs.steps_;
-    if (diff < 0) {
-      rhs.data.erase(rhs.data.begin(), rhs.data.begin() - diff);
-    }
+    if (diff < 0) { rhs.data.erase(rhs.data.begin(), rhs.data.begin() - diff); }
     rhs.set_scale(new_scale);
     return rhs;
   }
@@ -194,23 +194,24 @@ bigdecimal & math::operator*=(bigdecimal & rhs, bigdecimal const & lhs) {
 bigdecimal & math::operator/=(bigdecimal & rhs, bigdecimal const & lhs) {
   int32_t const new_scale = rhs.scale() - lhs.scale();
   rhs.is_negative ^= lhs.is_negative;
-  if (lhs == bigdecimal::ZERO) { throw std::domain_error("cannot divide by 0"); }
-  else if (rhs == bigdecimal::ZERO) {
+  if (lhs == bigdecimal::ZERO) {
+    throw std::domain_error("cannot divide by 0");
+  } else if (rhs == bigdecimal::ZERO) {
     rhs = bigdecimal::ZERO;
   } else if (!is_one(lhs.data, lhs.scale())) {
     if (rhs.scale() < new_scale) rhs.rescale(new_scale);
     auto cmp = detail::compare(rhs.data, lhs.data);
-    if (cmp < 0) { rhs = bigdecimal::ZERO; }
-    else if (cmp == 0) { return rhs = {1, new_scale}; }
-    else {
+    if (cmp < 0) {
+      rhs = bigdecimal::ZERO;
+    } else if (cmp == 0) {
+      return rhs = {1, new_scale};
+    } else {
       rhs.data = detail::divide(rhs.data, lhs.data);
       auto diff = add_scale(new_scale) - rhs.steps_ - lhs.steps_;
       if (diff > 0) {
         rhs.data.erase(rhs.data.begin(), rhs.data.begin() + diff);
       }
-      if (rhs.data.size() <= mul_scale(new_scale)) {
-        rhs.data.push_back(0);
-      }
+      if (rhs.data.size() <= mul_scale(new_scale)) { rhs.data.push_back(0); }
       rhs.set_scale(new_scale);
       return rhs;
     }
@@ -236,7 +237,8 @@ bigdecimal math::operator/(bigdecimal rhs, bigdecimal const & lhs) {
 }
 
 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;
+  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) {
@@ -247,43 +249,47 @@ 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) {
+  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) {
+bool math::operator>(bigdecimal const & rhs, bigdecimal const & lhs) {
   return lhs < rhs;
 }
 
-bigdecimal const bigdecimal::ZERO{0}, bigdecimal::ONE{1}, bigdecimal::NEGATIVE_ONE{-1};
+bigdecimal const bigdecimal::ZERO{0}, bigdecimal::ONE{1},
+    bigdecimal::NEGATIVE_ONE{-1};
 
 std::string bigdecimal::to_string() const {
   size_t const decimal_split = size_t(std::max(0, steps_));
-  int32_t const hidden = std::max(0, SEG_DIGITS * (-scale()/SEG_DIGITS));
+  int32_t const hidden = std::max(0, SEG_DIGITS * (-scale() / SEG_DIGITS));
   size_t const chars = SEG_DIGITS * data.size() + size_t(hidden);
   std::vector<char> output(chars + 3, '\0');
   char * ptr = output.data();
   if (is_negative) { *ptr++ = '-'; }
   ptr += sprintf(ptr, "%d", data.back());
-  for (size_t i = data.size()-1; i > decimal_split; --i) {
-    ptr += sprintf(ptr, "%0.*d", SEG_DIGITS, data[i-1]);
+  for (size_t i = data.size() - 1; i > decimal_split; --i) {
+    ptr += sprintf(ptr, "%0.*d", SEG_DIGITS, data[i - 1]);
   }
   if (scale() > 0) {
     *ptr++ = '.';
     for (size_t i = decimal_split; i > 1; --i) {
-      ptr += sprintf(ptr, "%0.*d", SEG_DIGITS, data[i-1]);
+      ptr += sprintf(ptr, "%0.*d", SEG_DIGITS, data[i - 1]);
     }
     int32_t const val = scale() % SEG_DIGITS;
-    sprintf(ptr, "%0.*d", val, data[0]/detail::powers[SEG_DIGITS-val]);
+    sprintf(ptr, "%0.*d", val, data[0] / detail::powers[SEG_DIGITS - val]);
   } else if (data.back()) {
     sprintf(ptr, "%0.*d", hidden, 0);
   }
   return output.data();
 }
-

+ 64 - 46
src/biginteger.cpp

@@ -5,8 +5,8 @@
 //  Created by Sam Jaffe on 6/30/17.
 //
 
-#include "biginteger.h"
-#include "bignum_helper.h"
+#include "math/biginteger.h"
+#include "math/bignum_helper.h"
 
 #include <cstdio>
 #include <cstdlib>
@@ -14,32 +14,29 @@
 
 using namespace math;
 
-static void read(int32_t & dst, char const * & str, size_t len) {
-  char seg[biginteger::SEG_DIGITS+1] = "";
+static void read(int32_t & dst, char const *& str, size_t len) {
+  char seg[biginteger::SEG_DIGITS + 1] = "";
   strncpy(seg, str, len);
   dst = atoi(seg);
   str += len;
 }
 
-biginteger::biginteger()
-: is_negative(false), data({0}) {}
+biginteger::biginteger() : is_negative(false), data({0}) {}
 
-biginteger::biginteger(char const * number)
-: is_negative(number[0] == '-') {
+biginteger::biginteger(char const * number) : is_negative(number[0] == '-') {
   if (is_negative) ++number;
   auto len = strlen(number);
-  auto elems = len/SEG_DIGITS;
+  auto elems = len / SEG_DIGITS;
   data.resize(elems);
-  if (auto small = len-(elems*SEG_DIGITS)) {
+  if (auto small = len - (elems * SEG_DIGITS)) {
     read(*data.insert(data.end(), 0), number, small);
   }
   for (data_type::size_type idx = elems; idx > 0; --idx) {
-    read(data[idx-1], number, SEG_DIGITS);
+    read(data[idx - 1], number, SEG_DIGITS);
   }
 }
 
-biginteger::biginteger(bool neg, uint64_t value) :
-is_negative(neg) {
+biginteger::biginteger(bool neg, uint64_t value) : is_negative(neg) {
   uint64_t next{0};
   do {
     next = value / OVER_SEG;
@@ -62,9 +59,11 @@ void biginteger::subtract_impl(biginteger const & lhs, bool is_sub) {
 }
 
 biginteger & math::operator+=(biginteger & rhs, biginteger const & lhs) {
-  if (lhs == biginteger::ZERO) { return rhs; }
-  else if (rhs == biginteger::ZERO) { rhs=lhs; }
-  else if (rhs.is_negative == lhs.is_negative) {
+  if (lhs == biginteger::ZERO) {
+    return rhs;
+  } else if (rhs == biginteger::ZERO) {
+    rhs = lhs;
+  } else if (rhs.is_negative == lhs.is_negative) {
     detail::add(rhs.data, lhs.data);
   } else {
     rhs.subtract_impl(lhs, false);
@@ -73,9 +72,11 @@ biginteger & math::operator+=(biginteger & rhs, biginteger const & lhs) {
 }
 
 biginteger & math::operator-=(biginteger & rhs, biginteger const & lhs) {
-  if (lhs == biginteger::ZERO) { return rhs; }
-  else if (rhs == biginteger::ZERO) { rhs = -lhs; }
-  else if (rhs.is_negative != lhs.is_negative) {
+  if (lhs == biginteger::ZERO) {
+    return rhs;
+  } else if (rhs == biginteger::ZERO) {
+    rhs = -lhs;
+  } else if (rhs.is_negative != lhs.is_negative) {
     detail::add(rhs.data, lhs.data);
   } else {
     rhs.subtract_impl(lhs, true);
@@ -100,20 +101,24 @@ biginteger & math::operator*=(biginteger & rhs, biginteger const & lhs) {
 
 biginteger & math::operator/=(biginteger & rhs, biginteger const & lhs) {
   rhs.is_negative ^= lhs.is_negative;
-  if (lhs == biginteger::ZERO) { throw std::domain_error("cannot divide by 0"); }
-  else if (rhs == biginteger::ZERO) { rhs = biginteger::ZERO; }
-  else if (detail::compare(lhs.data, biginteger::ONE.data) != 0) {
+  if (lhs == biginteger::ZERO) {
+    throw std::domain_error("cannot divide by 0");
+  } else if (rhs == biginteger::ZERO) {
+    rhs = biginteger::ZERO;
+  } else if (detail::compare(lhs.data, biginteger::ONE.data) != 0) {
     auto cmp = detail::compare(rhs.data, lhs.data);
-    if (cmp < 0) { rhs = biginteger::ZERO; }
-    else if (cmp == 0) { rhs.data = {1}; }
-    else { rhs.data = detail::divide(rhs.data, lhs.data); }
+    if (cmp < 0) {
+      rhs = biginteger::ZERO;
+    } else if (cmp == 0) {
+      rhs.data = {1};
+    } else {
+      rhs.data = detail::divide(rhs.data, lhs.data);
+    }
   }
   return rhs;
 }
 
-biginteger biginteger::operator-() const {
-  return (*this) * NEGATIVE_ONE;
-}
+biginteger biginteger::operator-() const { return (*this) * NEGATIVE_ONE; }
 
 biginteger math::operator+(biginteger rhs, biginteger const & lhs) {
   return rhs += lhs;
@@ -132,15 +137,19 @@ biginteger math::operator/(biginteger rhs, biginteger const & lhs) {
 }
 
 biginteger math::operator%(biginteger rhs, biginteger const & lhs) {
-  if (lhs == biginteger::ZERO) { throw std::domain_error("cannot divide by 0"); }
-  else if (lhs == biginteger::ONE ||
-           rhs == biginteger::ZERO) { return biginteger::ZERO; }
-  else {
+  if (lhs == biginteger::ZERO) {
+    throw std::domain_error("cannot divide by 0");
+  } else if (lhs == biginteger::ONE || rhs == biginteger::ZERO) {
+    return biginteger::ZERO;
+  } else {
     auto cmp = detail::compare(rhs.data, lhs.data);
-    if (cmp == 0) { return biginteger::ZERO; }
-    else if (cmp > 0) {
+    if (cmp == 0) {
+      return biginteger::ZERO;
+    } else if (cmp > 0) {
       detail::divide(rhs.data, lhs.data);
-      if (detail::compare(rhs.data, biginteger::ZERO.data) == 0) { return biginteger::ZERO; }
+      if (detail::compare(rhs.data, biginteger::ZERO.data) == 0) {
+        return biginteger::ZERO;
+      }
     }
     if (rhs.is_negative != lhs.is_negative) {
       rhs.is_negative = lhs.is_negative;
@@ -153,7 +162,8 @@ biginteger math::operator%(biginteger rhs, biginteger const & lhs) {
 }
 
 bool math::operator==(biginteger const & rhs, biginteger const & lhs) {
-  return rhs.is_negative == lhs.is_negative && detail::compare(rhs.data, lhs.data) == 0;
+  return rhs.is_negative == lhs.is_negative &&
+         detail::compare(rhs.data, lhs.data) == 0;
 }
 
 bool math::operator!=(biginteger const & rhs, biginteger const & lhs) {
@@ -164,29 +174,37 @@ bool math::operator<=(biginteger const & rhs, biginteger const & lhs) {
   return !(rhs > lhs);
 }
 
-bool math::operator< (biginteger const & rhs, biginteger const & lhs) {
-  if (rhs.is_negative != lhs.is_negative) { return rhs.is_negative; }
-  else if (rhs.is_negative) { return detail::compare(rhs.data, lhs.data) > 0; }
-  else { return detail::compare(rhs.data, lhs.data) < 0; }
+bool math::operator<(biginteger const & rhs, biginteger const & lhs) {
+  if (rhs.is_negative != lhs.is_negative) {
+    return rhs.is_negative;
+  } else if (rhs.is_negative) {
+    return detail::compare(rhs.data, lhs.data) > 0;
+  } else {
+    return detail::compare(rhs.data, lhs.data) < 0;
+  }
 }
 
 bool math::operator>=(biginteger const & rhs, biginteger const & lhs) {
   return !(rhs < lhs);
 }
 
-bool math::operator> (biginteger const & rhs, biginteger const & lhs) {
+bool math::operator>(biginteger const & rhs, biginteger const & lhs) {
   return lhs < rhs;
 }
 
-biginteger const biginteger::ZERO{0}, biginteger::ONE{1}, biginteger::NEGATIVE_ONE{-1};
+biginteger const biginteger::ZERO{0}, biginteger::ONE{1},
+    biginteger::NEGATIVE_ONE{-1};
 
 std::string biginteger::to_string() const {
   std::vector<char> output(biginteger::SEG_DIGITS * data.size() + 2, '\0');
   std::ptrdiff_t idx = 0;
-  if (is_negative) { output[0] = '-'; ++idx; }
-  idx += sprintf(output.data() + idx, "%d", data[data.size()-1]);
-  for (size_t i = data.size()-1; i > 0; --i, idx+=SEG_DIGITS) {
-    sprintf(output.data() + idx, "%0.*d", SEG_DIGITS, data[i-1]);
+  if (is_negative) {
+    output[0] = '-';
+    ++idx;
+  }
+  idx += sprintf(output.data() + idx, "%d", data[data.size() - 1]);
+  for (size_t i = data.size() - 1; i > 0; --i, idx += SEG_DIGITS) {
+    sprintf(output.data() + idx, "%0.*d", SEG_DIGITS, data[i - 1]);
   }
   return output.data();
 }

+ 41 - 37
src/bignum_helper.cpp

@@ -5,131 +5,135 @@
 //  Created by Sam Jaffe on 7/4/17.
 //
 
-#include "bignum_helper.h"
+#include "math/bignum_helper.h"
 
 #include <cmath>
 
 using namespace math::detail;
 
 namespace {
-  constexpr int32_t const MAX_SEG { 999999999};
+  constexpr int32_t const MAX_SEG{999999999};
   constexpr int32_t const OVER_SEG{1000000000};
   constexpr int32_t const SEG_DIGITS{9};
 }
 
 namespace math { namespace detail {
-#define IMPL_COMPARE(rexpr, lexpr) \
-  if (rhs rexpr < lhs lexpr) return -1; \
-  else if (lhs lexpr < rhs rexpr) return 1
+#define IMPL_COMPARE(rexpr, lexpr)                                             \
+  if (rhs rexpr < lhs lexpr)                                                   \
+    return -1;                                                                 \
+  else if (lhs lexpr < rhs rexpr)                                              \
+  return 1
   int compare(data_type const & rhs, data_type const & lhs, size_t offset) {
-    IMPL_COMPARE(.size(), .size()+offset);
+    IMPL_COMPARE(.size(), .size() + offset);
     for (size_t i = lhs.size(); i > 0; --i) {
-      IMPL_COMPARE([i+offset-1], [i-1]);
+      IMPL_COMPARE([i + offset - 1], [i - 1]);
     }
     return 0;
   }
 #undef IMPL_COMPARE
-  
+
   void carry(data_type & rhs, size_t start) {
     auto const ubnd = rhs.size() - 1;
     for (size_t i = start; i < ubnd; ++i) {
       if (rhs[i] > MAX_SEG) {
         rhs[i] -= OVER_SEG;
-        rhs[i+1] += 1;
+        rhs[i + 1] += 1;
       }
     }
     if (rhs[ubnd] == 0) { rhs.pop_back(); }
   }
-  
+
   void add(data_type & rhs, data_type const & lhs, size_t offset) {
-    rhs.resize(std::max(rhs.size(), lhs.size()+offset)+1);
+    rhs.resize(std::max(rhs.size(), lhs.size() + offset) + 1);
     auto const lbnd = lhs.size();
     for (size_t i = 0; i < lbnd; ++i) {
-      rhs[i+offset] += lhs[i];
+      rhs[i + offset] += lhs[i];
     }
     carry(rhs, offset);
   }
 
   void add(data_type & rhs, int32_t lhs, size_t offset) {
-    rhs.resize(std::max(rhs.size(), offset)+1);
+    rhs.resize(std::max(rhs.size(), offset) + 1);
     rhs[offset] += lhs;
     carry(rhs, offset);
   }
 
-  void subtract_nounderflow(data_type & rhs, data_type const & lhs, size_t offset) {
+  void subtract_nounderflow(data_type & rhs, data_type const & lhs,
+                            size_t offset) {
     size_t const rbnd = rhs.size(), lbnd = lhs.size();
     // Subtract
     for (size_t i = 0; i < lbnd; ++i) {
-      rhs[i+offset] -= lhs[i];
+      rhs[i + offset] -= lhs[i];
     }
     // Borrow
-    for (size_t i = 0; i < rbnd-1; ++i) {
+    for (size_t i = 0; i < rbnd - 1; ++i) {
       if (rhs[i] < 0) {
         rhs[i] += OVER_SEG;
-        rhs[i+1] -= 1;
+        rhs[i + 1] -= 1;
       }
     }
-    if (rhs[rbnd-1] == 0 && rbnd > 1) { rhs.pop_back(); }
+    if (rhs[rbnd - 1] == 0 && rbnd > 1) { rhs.pop_back(); }
   }
-  
+
   void multiply(data_type & rhs, data_type const & lhs) {
     size_t const rbnd = rhs.size(), lbnd = lhs.size();
     size_t const ubnd = rbnd + lbnd;
     rhs.resize(ubnd);
     // Multiply
     for (size_t i = rbnd; i > 0; --i) {
-      int32_t const value = rhs[i-1];
+      int32_t const value = rhs[i - 1];
       for (size_t j = lbnd; j > 0; --j) {
         // Max input              999,999,999
         // Max output 999,999,998,000,000,001
-        int64_t product = int64_t(value) * lhs[j-1];
+        int64_t product = int64_t(value) * lhs[j - 1];
         int64_t overflow = product / OVER_SEG;
-        size_t const to = i+j-2;
+        size_t const to = i + j - 2;
         rhs[to] += int32_t(product - (overflow * OVER_SEG));
-        rhs[to+1] += int32_t(overflow);
+        rhs[to + 1] += int32_t(overflow);
       }
-      rhs[i-1] -= value;
+      rhs[i - 1] -= value;
     }
     // Carry
-    for (size_t i = 0; i < ubnd-1; ++i) {
+    for (size_t i = 0; i < ubnd - 1; ++i) {
       if (rhs[i] > MAX_SEG) {
         int32_t overflow = rhs[i] / OVER_SEG;
         rhs[i] -= (overflow * OVER_SEG);
-        rhs[i+1] += overflow;
+        rhs[i + 1] += overflow;
       }
     }
-    while (rhs.back() == 0) { rhs.pop_back(); }
+    while (rhs.back() == 0) {
+      rhs.pop_back();
+    }
   }
-    
+
   data_type shift10(data_type const & data, int32_t places) {
     int32_t shift = places / SEG_DIGITS;
     int64_t const pow = powers[places - (shift * SEG_DIGITS)];
     size_t const bnd = data.size();
     data_type rval(size_t((int32_t)bnd + shift) + 1);
-    for (size_t i = 0, o = size_t(std::max(0, shift));
-         i < bnd; ++i, ++o) {
+    for (size_t i = 0, o = size_t(std::max(0, shift)); i < bnd; ++i, ++o) {
       int64_t product = int64_t(data[i]) * pow;
       int64_t overflow = product / OVER_SEG;
       rval[o] += int32_t(product - (overflow * OVER_SEG));
-      rval[o+1] += int32_t(overflow);
+      rval[o + 1] += int32_t(overflow);
     }
     if (rval.back() == 0 && rval.size() > 1) { rval.pop_back(); }
     return rval;
   }
-  
+
   size_t digits(int32_t val) {
     return val == 0 ? 1 : size_t(floor(log10(val))) + 1;
   }
-  
+
   size_t digits(data_type const & data) {
-    size_t segDig = SEG_DIGITS * (data.size()-1);
+    size_t segDig = SEG_DIGITS * (data.size() - 1);
     if (data.back() == 0) {
-      return segDig - SEG_DIGITS + digits(data[data.size()-2]);
+      return segDig - SEG_DIGITS + digits(data[data.size() - 2]);
     } else {
       return segDig + digits(data.back());
     }
   }
-  
+
   data_type divide(data_type & remainder, data_type const & divisor) {
     data_type accum{0};
     auto const dig = digits(divisor);
@@ -145,4 +149,4 @@ namespace math { namespace detail {
     } while (compare(remainder, divisor) >= 0);
     return accum;
   }
-} }
+}}

+ 49 - 49
test/bigdecimal_test.cpp

@@ -5,9 +5,6 @@
 //  Created by Sam Jaffe on 5/18/18.
 //
 
-#include <gmock/gmock.h>
-
-#include "bigdecimal.h"
 #include "bignumber_test_printers.h"
 
 TEST(BigDecimalTest, ConstructIntegerAsDecimal) {
@@ -16,7 +13,8 @@ TEST(BigDecimalTest, ConstructIntegerAsDecimal) {
 
 TEST(BigDecimalTest, ConstructDecimal) {
   EXPECT_THAT(math::bigdecimal("1000.10").to_string(), "1000.10");
-  EXPECT_THAT(math::bigdecimal("1000.0000000001").to_string(), "1000.0000000001");
+  EXPECT_THAT(math::bigdecimal("1000.0000000001").to_string(),
+              "1000.0000000001");
 }
 
 TEST(BigDecimalTest, ConstructIntWithScaleAndStep) {
@@ -65,14 +63,14 @@ TEST(BigDecimalTest, AddingEqualScalesDoesNotAddTrailingDigitsOrLoseData) {
   math::bigdecimal a("1000.10");
   math::bigdecimal b("1000.01");
   EXPECT_THAT(a.scale(), b.scale());
-  EXPECT_THAT((a+b).to_string(), "2000.11");
+  EXPECT_THAT((a + b).to_string(), "2000.11");
 }
 
 TEST(BigDecimalTest, AdditionNormalizeScaleToHighest) {
   math::bigdecimal a("1000.10");
   math::bigdecimal b("1000");
   EXPECT_THAT(a.scale(), testing::Gt(b.scale()));
-  EXPECT_THAT((a+b).scale(), a.scale());
+  EXPECT_THAT((a + b).scale(), a.scale());
 }
 
 TEST(BigDecimalTest, InverseOfNumberCarriesSameScale) {
@@ -84,8 +82,8 @@ TEST(BigDecimalTest, SubtractionNormalizeScaleToHighest) {
   math::bigdecimal a("900.10");
   math::bigdecimal b("1000");
   EXPECT_THAT(a.scale(), testing::Gt(b.scale()));
-  EXPECT_THAT((a-b).scale(), a.scale());
-  EXPECT_THAT((b-a).scale(), a.scale());
+  EXPECT_THAT((a - b).scale(), a.scale());
+  EXPECT_THAT((b - a).scale(), a.scale());
 }
 
 class MultiplicationScaleTest : public testing::TestWithParam<ArithTuple> {};
@@ -122,46 +120,48 @@ TEST_P(DecimalLtTest, IsLessThanEvenWithDifferentScales) {
 
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
-INSTANTIATE_TEST_CASE_P(BigDecimal, MultiplicationScaleTest,
-                        testing::Values(ArithTuple{{1, 1}, { 1,  0},  "1.0"},
-                                        ArithTuple{{1, 0}, { 1,  1},  "1.0"},
-                                        ArithTuple{{1, 0}, {10,  0}, "10"  },
-                                        ArithTuple{{1, 1}, {10,  0}, "10.0"},
-                                        ArithTuple{{1, 1}, {10, -1}, "10", },
-                                        ArithTuple{{"1.1"}, {"1.1"}, "1.21"},
-                                        ArithTuple{{"0.01"}, {100, -2}, "1"},
-                                        ArithTuple{{1, 5}, {1,  5}, "1.0000000000"},
-                                        ArithTuple{{1, 5}, {1000000000, -9}, "1000000000"},
-                                        ArithTuple{{100, -2}, {1000000000, -9}, "100000000000"},
-                                        ArithTuple{{10000, -4}, {100000, -5}, "1000000000"}));
-
-INSTANTIATE_TEST_CASE_P(BigDecimal, DivisionScaleTest,
-                        testing::Values(ArithTuple{{1, 1}, { 1,  0}, "1.0" },
-                                        ArithTuple{{1, 0}, { 1,  1}, "0"   },
-                                        ArithTuple{{1, 0}, {10,  0}, "0"   },
-                                        ArithTuple{{1, 1}, {10,  0}, "0.1" },
-                                        ArithTuple{{1, 1}, {10, -1}, "0.10"},
-                                        ArithTuple{{"1.1"}, {"1.1"}, "1"},
-                                        ArithTuple{{"0.01"}, {100, -2}, "0.0001"},
-                                        ArithTuple{{1, 5}, {1,  5}, "1"},
-                                        ArithTuple{{1, 5}, {1000000000, -9}, "0.00000000100000"},
-                                        ArithTuple{{100, -2}, {1000000000, -9}, "0.0000001"},
-                                        ArithTuple{{10000, -4}, {100000, -5}, "0.1"},
-                                        ArithTuple{{"11.0"}, {"1.10"}, "10"}));
-
-INSTANTIATE_TEST_CASE_P(BigDecimal, EqTest,
-                        testing::Values(BigDecPair{{  0}, {  0,  4}},
-                                        BigDecPair{{100}, {100, -2}},
-                                        BigDecPair{{1000000000, -4}, {1000000000, -9}},
-                                        BigDecPair{{"0.1", 1}, {"0.10", 2}}));
-
-INSTANTIATE_TEST_CASE_P(BigDecimal, DecimalLtTest,
-                        testing::Values(BigDecPair{{ 0, 0}, { 1, 4}},
-                                        BigDecPair{{ 0, 4}, { 1, 0}},
-                                        BigDecPair{{ 0, 4}, { 1, 4}},
-                                        BigDecPair{{-1, 4}, { 1, 4}},
-                                        BigDecPair{{-2, 0}, {-1, 4}},
-                                        BigDecPair{{-2, 4}, {-1, 0}},
-                                        BigDecPair{{-2, 4}, {-1, 4}}));
+INSTANTIATE_TEST_CASE_P(
+    BigDecimal, MultiplicationScaleTest,
+    testing::Values(ArithTuple{{1, 1}, {1, 0}, "1.0"},
+                    ArithTuple{{1, 0}, {1, 1}, "1.0"},
+                    ArithTuple{{1, 0}, {10, 0}, "10"},
+                    ArithTuple{{1, 1}, {10, 0}, "10.0"},
+                    ArithTuple{
+                        {1, 1},
+                        {10, -1},
+                        "10",
+                    },
+                    ArithTuple{{"1.1"}, {"1.1"}, "1.21"},
+                    ArithTuple{{"0.01"}, {100, -2}, "1"},
+                    ArithTuple{{1, 5}, {1, 5}, "1.0000000000"},
+                    ArithTuple{{1, 5}, {1000000000, -9}, "1000000000"},
+                    ArithTuple{{100, -2}, {1000000000, -9}, "100000000000"},
+                    ArithTuple{{10000, -4}, {100000, -5}, "1000000000"}));
+
+INSTANTIATE_TEST_CASE_P(
+    BigDecimal, DivisionScaleTest,
+    testing::Values(
+        ArithTuple{{1, 1}, {1, 0}, "1.0"}, ArithTuple{{1, 0}, {1, 1}, "0"},
+        ArithTuple{{1, 0}, {10, 0}, "0"}, ArithTuple{{1, 1}, {10, 0}, "0.1"},
+        ArithTuple{{1, 1}, {10, -1}, "0.10"}, ArithTuple{{"1.1"}, {"1.1"}, "1"},
+        ArithTuple{{"0.01"}, {100, -2}, "0.0001"},
+        ArithTuple{{1, 5}, {1, 5}, "1"},
+        ArithTuple{{1, 5}, {1000000000, -9}, "0.00000000100000"},
+        ArithTuple{{100, -2}, {1000000000, -9}, "0.0000001"},
+        ArithTuple{{10000, -4}, {100000, -5}, "0.1"},
+        ArithTuple{{"11.0"}, {"1.10"}, "10"}));
+
+INSTANTIATE_TEST_CASE_P(
+    BigDecimal, EqTest,
+    testing::Values(BigDecPair{{0}, {0, 4}}, BigDecPair{{100}, {100, -2}},
+                    BigDecPair{{1000000000, -4}, {1000000000, -9}},
+                    BigDecPair{{"0.1", 1}, {"0.10", 2}}));
+
+INSTANTIATE_TEST_CASE_P(
+    BigDecimal, DecimalLtTest,
+    testing::Values(BigDecPair{{0, 0}, {1, 4}}, BigDecPair{{0, 4}, {1, 0}},
+                    BigDecPair{{0, 4}, {1, 4}}, BigDecPair{{-1, 4}, {1, 4}},
+                    BigDecPair{{-2, 0}, {-1, 4}}, BigDecPair{{-2, 4}, {-1, 0}},
+                    BigDecPair{{-2, 4}, {-1, 4}}));
 
 #pragma clang diagnostic pop

+ 15 - 15
test/biginteger_test.cpp

@@ -6,40 +6,37 @@
 //
 
 #include "bignumber_test_printers.h"
-#include <gmock/gmock.h>
-
-#include "biginteger.h"
 
 TEST(BigIntegerTest, ModuloZeroThrows) {
   math::biginteger bi{1000};
-  EXPECT_THROW(bi%0, std::domain_error);
+  EXPECT_THROW(bi % 0, std::domain_error);
 }
 
 TEST(BigIntegerTest, ModuloBiggerIsSameValue) {
   math::biginteger bi{1000};
-  EXPECT_THAT(bi%2000, bi);
+  EXPECT_THAT(bi % 2000, bi);
 }
 
 TEST(BigIntegerTest, ModuloSameNumberIsZero) {
   math::biginteger bi{1000};
-  EXPECT_THAT(bi%1000, 0);
+  EXPECT_THAT(bi % 1000, 0);
 }
 
 TEST(BigIntegerTest, ModuloDivisorIsZero) {
   math::biginteger bi{1000};
-  EXPECT_THAT(bi%100, 0);
+  EXPECT_THAT(bi % 100, 0);
 }
 
 TEST(BigIntegerTest, ModuloDiffSignIsInverseElement) {
   math::biginteger bi{1000};
   math::biginteger mod{13};
-  EXPECT_THAT((bi%mod)+((-bi)%mod), mod);
+  EXPECT_THAT((bi % mod) + ((-bi) % mod), mod);
 }
 
 TEST(BigIntegerTest, ModuloNegativesIsNegative) {
   math::biginteger bi{1000};
   math::biginteger mod{13};
-  EXPECT_THAT((bi%mod), -((-bi)%(-mod)));
+  EXPECT_THAT((bi % mod), -((-bi) % (-mod)));
 }
 
 class BigIntModuloTest : public testing::TestWithParam<BigIntPair> {};
@@ -47,7 +44,7 @@ class BigIntModuloTest : public testing::TestWithParam<BigIntPair> {};
 TEST_P(BigIntModuloTest, IsZero) {
   auto & ZERO = math::biginteger::ZERO;
   auto pair = GetParam();
-  EXPECT_THAT(std::get<0>(pair)%std::get<1>(pair), ZERO);
+  EXPECT_THAT(std::get<0>(pair) % std::get<1>(pair), ZERO);
 }
 
 class LtTest : public testing::TestWithParam<BigIntPair> {};
@@ -60,17 +57,20 @@ TEST_P(LtTest, IsLessThan) {
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
 INSTANTIATE_TEST_CASE_P(BigInteger, LtTest,
-                        testing::Values(BigIntPair{-1,  1},
-                                        BigIntPair{ 0,  1},
+                        testing::Values(BigIntPair{-1, 1}, BigIntPair{0, 1},
                                         BigIntPair{-2, -1},
-                                        BigIntPair{ 1000000000,  1000000001},
+                                        BigIntPair{1000000000, 1000000001},
                                         BigIntPair{-1000000001, -1000000000}));
 
 INSTANTIATE_TEST_CASE_P(ZeroModAny, BigIntModuloTest,
                         testing::Combine(testing::Values(0),
-                        testing::Values(1, 2, 10, 100, -4, 1000000000, -1000000000)));
+                                         testing::Values(1, 2, 10, 100, -4,
+                                                         1000000000,
+                                                         -1000000000)));
 
 INSTANTIATE_TEST_CASE_P(AnyModOne, BigIntModuloTest,
-                        testing::Combine(testing::Values(1, 2, 10, 100, -4, 1000000000, -1000000000),
+                        testing::Combine(testing::Values(1, 2, 10, 100, -4,
+                                                         1000000000,
+                                                         -1000000000),
                                          testing::Values(1)));
 #pragma clang diagnostic pop

+ 41 - 48
test/bignumber_integral_test.cpp

@@ -5,14 +5,9 @@
 //  Created by Sam Jaffe on 5/18/18.
 //
 
-#include <gmock/gmock.h>
-
-#include "biginteger.h"
-#include "bigdecimal.h"
 #include "bignumber_test_printers.h"
 
-template <typename T>
-class BigIntLikeTest : public testing::Test {
+template <typename T> class BigIntLikeTest : public testing::Test {
 public:
   T typeget_;
 };
@@ -27,160 +22,158 @@ TYPED_TEST(BigIntLikeTest, DefaultConstructorCreatesZero) {
 }
 
 TYPED_TEST(BigIntLikeTest, StringAndNumberConstructorsEqual) {
-  EXPECT_THAT(BigNumber( "1000000"), BigNumber( 1000000));
+  EXPECT_THAT(BigNumber("1000000"), BigNumber(1000000));
   EXPECT_THAT(BigNumber("-1000000"), BigNumber(-1000000));
 }
 
 TYPED_TEST(BigIntLikeTest, AddPastBounds) {
   BigNumber bi{999999999ULL};
-  EXPECT_THAT((bi+1).to_string(), "1000000000");
+  EXPECT_THAT((bi + 1).to_string(), "1000000000");
 }
 
 TYPED_TEST(BigIntLikeTest, AddReciprocalIsZero) {
   BigNumber bi{1000};
-  EXPECT_THAT((bi+(-bi)).to_string(), "0");
+  EXPECT_THAT((bi + (-bi)).to_string(), "0");
 }
 
 TYPED_TEST(BigIntLikeTest, AddNegativeLargerGivesNegative) {
   BigNumber bi{1000};
-  EXPECT_THAT((bi+(-1001)).to_string(), "-1");
+  EXPECT_THAT((bi + (-1001)).to_string(), "-1");
 }
 
 TYPED_TEST(BigIntLikeTest, AddNegativeSmallerGivesPositive) {
   BigNumber bi{1000};
-  EXPECT_THAT((bi+(-999)).to_string(), "1");
+  EXPECT_THAT((bi + (-999)).to_string(), "1");
 }
 
 TYPED_TEST(BigIntLikeTest, AddNumberZeroGivesOriginal) {
   BigNumber bi{1000};
-  EXPECT_THAT(bi+0, bi);
+  EXPECT_THAT(bi + 0, bi);
 }
 
 TYPED_TEST(BigIntLikeTest, AddZeroNumberGivesOriginal) {
   BigNumber bi{1000};
-  EXPECT_THAT(0+bi, bi);
+  EXPECT_THAT(0 + bi, bi);
 }
 
 TYPED_TEST(BigIntLikeTest, SubSelfIsZero) {
   BigNumber bi{1000};
-  EXPECT_THAT((bi-bi).to_string(), "0");
+  EXPECT_THAT((bi - bi).to_string(), "0");
 }
 
 TYPED_TEST(BigIntLikeTest, SubtractZeroGivesOriginal) {
   BigNumber bi{1000};
-  EXPECT_THAT(bi-0, bi);
+  EXPECT_THAT(bi - 0, bi);
 }
 
 TYPED_TEST(BigIntLikeTest, ZeroMinusNumberEqualsReciprocal) {
   BigNumber bi{1000};
-  EXPECT_THAT((0-bi).to_string(), (-bi).to_string());
+  EXPECT_THAT((0 - bi).to_string(), (-bi).to_string());
 }
 
 TYPED_TEST(BigIntLikeTest, NegativeMinusNegativeIncreateAbs) {
   BigNumber bi{-1000};
-  EXPECT_THAT((bi-100).to_string(), "-1100");
+  EXPECT_THAT((bi - 100).to_string(), "-1100");
 }
 
 TYPED_TEST(BigIntLikeTest, SubLargerGivesNegative) {
   BigNumber bi{1000};
-  EXPECT_THAT((bi-1001).to_string(), "-1");
+  EXPECT_THAT((bi - 1001).to_string(), "-1");
 }
 
 TYPED_TEST(BigIntLikeTest, SubSmallerGivesPositive) {
   BigNumber bi{1000};
-  EXPECT_THAT((bi-999).to_string(), "1");
+  EXPECT_THAT((bi - 999).to_string(), "1");
 }
 
 TYPED_TEST(BigIntLikeTest, SubUnderflowBorrows) {
   BigNumber bi{1000000000ULL};
-  EXPECT_THAT((bi-1).to_string(), "999999999");
+  EXPECT_THAT((bi - 1).to_string(), "999999999");
 }
 
 TYPED_TEST(BigIntLikeTest, MultiplyZeroReturnsZero) {
-  auto &ZERO =  BigNumber::ZERO;
+  auto & ZERO = BigNumber::ZERO;
   BigNumber bi{999999999ULL};
-  EXPECT_THAT(bi*ZERO, ZERO);
-  EXPECT_THAT(ZERO*bi, ZERO);
+  EXPECT_THAT(bi * ZERO, ZERO);
+  EXPECT_THAT(ZERO * bi, ZERO);
 }
 
 TYPED_TEST(BigIntLikeTest, MultiplyOneReturnsValue) {
-  auto &ONE =  BigNumber::ONE;
+  auto & ONE = BigNumber::ONE;
   BigNumber bi{999999999ULL};
-  EXPECT_THAT((bi*ONE).to_string(), "999999999");
-  EXPECT_THAT((ONE*bi).to_string(), "999999999");
+  EXPECT_THAT((bi * ONE).to_string(), "999999999");
+  EXPECT_THAT((ONE * bi).to_string(), "999999999");
 }
 
 TYPED_TEST(BigIntLikeTest, MultiplyNegativeOneReturnsInverse) {
-  auto &NEGATIVE_ONE =  BigNumber::NEGATIVE_ONE;
+  auto & NEGATIVE_ONE = BigNumber::NEGATIVE_ONE;
   BigNumber bi{999999999ULL};
-  EXPECT_THAT((bi*NEGATIVE_ONE).to_string(), "-999999999");
-  EXPECT_THAT((NEGATIVE_ONE*bi).to_string(), "-999999999");
+  EXPECT_THAT((bi * NEGATIVE_ONE).to_string(), "-999999999");
+  EXPECT_THAT((NEGATIVE_ONE * bi).to_string(), "-999999999");
 }
 
 TYPED_TEST(BigIntLikeTest, MultiplyOverflowsIntoNextCell) {
   BigNumber bi{999999999ULL};
-  EXPECT_THAT((bi*bi).to_string(), "999999998000000001");
+  EXPECT_THAT((bi * bi).to_string(), "999999998000000001");
 }
 
 TYPED_TEST(BigIntLikeTest, MultiplyCarryIntoNextCell) {
   BigNumber bi{999999999ULL};
-  BigNumber big{bi*bi};
-  EXPECT_THAT((big*big).to_string(),
-                   "999999996000000005999999996000000001");
+  BigNumber big{bi * bi};
+  EXPECT_THAT((big * big).to_string(), "999999996000000005999999996000000001");
 }
 
 TYPED_TEST(BigIntLikeTest, MultiplyNoOverflow) {
   BigNumber bi{1000};
-  EXPECT_THAT((bi*bi).to_string(), "1000000");
+  EXPECT_THAT((bi * bi).to_string(), "1000000");
 }
 
 TYPED_TEST(BigIntLikeTest, DivideByZeroThrows) {
-  auto &ZERO =  BigNumber::ZERO;
+  auto & ZERO = BigNumber::ZERO;
   BigNumber bi{1000};
-  EXPECT_THROW(bi/ZERO, std::domain_error);
+  EXPECT_THROW(bi / ZERO, std::domain_error);
 }
 
 TYPED_TEST(BigIntLikeTest, DivideByOneReturnsValue) {
-  auto &ONE =  BigNumber::ONE;
+  auto & ONE = BigNumber::ONE;
   BigNumber bi{1000};
-  EXPECT_THAT(bi/ONE, bi);
+  EXPECT_THAT(bi / ONE, bi);
 }
 
 TYPED_TEST(BigIntLikeTest, DivideBySelfReturnsOne) {
-  auto &ONE =  BigNumber::ONE;
+  auto & ONE = BigNumber::ONE;
   BigNumber bi{1000};
-  EXPECT_THAT(bi/bi, ONE);
+  EXPECT_THAT(bi / bi, ONE);
 }
 
 TYPED_TEST(BigIntLikeTest, DivideByNegativeOneReturnsInverse) {
-  auto &NEGATIVE_ONE =  BigNumber::NEGATIVE_ONE;
+  auto & NEGATIVE_ONE = BigNumber::NEGATIVE_ONE;
   BigNumber bi{1000};
-  EXPECT_THAT((bi/NEGATIVE_ONE).to_string(), "-1000");
+  EXPECT_THAT((bi / NEGATIVE_ONE).to_string(), "-1000");
 }
 
 TYPED_TEST(BigIntLikeTest, DivisionWithMultipleMultSubSteps) {
   BigNumber bi{1112};
-  EXPECT_THAT((bi/2).to_string(), "556");
+  EXPECT_THAT((bi / 2).to_string(), "556");
 }
 
 TYPED_TEST(BigIntLikeTest, DivisionDroppingNumberOfCells) {
   BigNumber bi{1000000000ULL};
-  EXPECT_THAT((bi/2).to_string(), "500000000");
+  EXPECT_THAT((bi / 2).to_string(), "500000000");
 }
 
 TYPED_TEST(BigIntLikeTest, DivisionByBiggerNumberIsZero) {
   BigNumber bi{1000ULL};
-  EXPECT_THAT((bi/1001).to_string(), "0");
+  EXPECT_THAT((bi / 1001).to_string(), "0");
 }
 
 TYPED_TEST(BigIntLikeTest, DivisionWithLargeNumbers) {
   BigNumber big{"999999998000000001"};
   EXPECT_THAT(big.to_string(), "999999998000000001");
-  EXPECT_THAT((big/999999999ULL).to_string(),
-                   "999999999");
+  EXPECT_THAT((big / 999999999ULL).to_string(), "999999999");
 }
 
 TYPED_TEST(BigIntLikeTest, ZeroDividedByAnyReturnsZero) {
   auto & ZERO = BigNumber::ZERO;
-  EXPECT_THAT(ZERO/25, ZERO);
+  EXPECT_THAT(ZERO / 25, ZERO);
 }

+ 15 - 5
test/bignumber_test_printers.h

@@ -7,15 +7,25 @@
 
 #pragma once
 
-#include "biginteger.h"
-#include "bigdecimal.h"
+#include "math/bigdecimal.h"
+#include "math/biginteger.h"
 
-#include <string>
 #include <iosfwd>
+#include <string>
 #include <tuple>
 
-struct ArithTuple { math::bigdecimal lhs, rhs; std::string expected; };
-struct BigDecPair { math::bigdecimal lhs, rhs; };
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
+#include <gmock/gmock.h>
+#pragma clang diagnostic pop
+
+struct ArithTuple {
+  math::bigdecimal lhs, rhs;
+  std::string expected;
+};
+struct BigDecPair {
+  math::bigdecimal lhs, rhs;
+};
 using BigIntPair = std::tuple<math::biginteger, math::biginteger>;
 
 namespace math {