Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
bignum_tests.cpp
Go to the documentation of this file.
1 #include <boost/test/unit_test.hpp>
2 #include <limits>
3 
4 #include "bignum.h"
5 #include "util.h"
6 
7 BOOST_AUTO_TEST_SUITE(bignum_tests)
8 
9 // Unfortunately there's no standard way of preventing a function from being
10 // inlined, so we define a macro for it.
11 //
12 // You should use it like this:
13 // NOINLINE void function() {...}
14 #if defined(__GNUC__)
15 // This also works and will be defined for any compiler implementing GCC
16 // extensions, such as Clang and ICC.
17 #define NOINLINE __attribute__((noinline))
18 #elif defined(_MSC_VER)
19 #define NOINLINE __declspec(noinline)
20 #else
21 // We give out a warning because it impacts the correctness of one bignum test.
22 #warning You should define NOINLINE for your compiler.
23 #define NOINLINE
24 #endif
25 
26 // For the following test case, it is useful to use additional tools.
27 //
28 // The simplest one to use is the compiler flag -ftrapv, which detects integer
29 // overflows and similar errors. However, due to optimizations and compilers
30 // taking advantage of undefined behavior sometimes it may not actually detect
31 // anything.
32 //
33 // You can also use compiler-based stack protection to possibly detect possible
34 // stack buffer overruns.
35 //
36 // For more accurate diagnostics, you can use an undefined arithmetic operation
37 // detector such as the clang-based tool:
38 //
39 // "IOC: An Integer Overflow Checker for C/C++"
40 //
41 // Available at: http://embed.cs.utah.edu/ioc/
42 //
43 // It might also be useful to use Google's AddressSanitizer to detect
44 // stack buffer overruns, which valgrind can't currently detect.
45 
46 // Let's force this code not to be inlined, in order to actually
47 // test a generic version of the function. This increases the chance
48 // that -ftrapv will detect overflows.
50 {
51  num.setint64(n);
52 }
53 
54 // For each number, we do 2 tests: one with inline code, then we reset the
55 // value to 0, then the second one with a non-inlined function.
56 BOOST_AUTO_TEST_CASE(bignum_setint64)
57 {
58  int64 n;
59 
60  {
61  n = 0;
62  CBigNum num(n);
63  BOOST_CHECK(num.ToString() == "0");
64  num.setulong(0);
65  BOOST_CHECK(num.ToString() == "0");
66  mysetint64(num, n);
67  BOOST_CHECK(num.ToString() == "0");
68  }
69  {
70  n = 1;
71  CBigNum num(n);
72  BOOST_CHECK(num.ToString() == "1");
73  num.setulong(0);
74  BOOST_CHECK(num.ToString() == "0");
75  mysetint64(num, n);
76  BOOST_CHECK(num.ToString() == "1");
77  }
78  {
79  n = -1;
80  CBigNum num(n);
81  BOOST_CHECK(num.ToString() == "-1");
82  num.setulong(0);
83  BOOST_CHECK(num.ToString() == "0");
84  mysetint64(num, n);
85  BOOST_CHECK(num.ToString() == "-1");
86  }
87  {
88  n = 5;
89  CBigNum num(n);
90  BOOST_CHECK(num.ToString() == "5");
91  num.setulong(0);
92  BOOST_CHECK(num.ToString() == "0");
93  mysetint64(num, n);
94  BOOST_CHECK(num.ToString() == "5");
95  }
96  {
97  n = -5;
98  CBigNum num(n);
99  BOOST_CHECK(num.ToString() == "-5");
100  num.setulong(0);
101  BOOST_CHECK(num.ToString() == "0");
102  mysetint64(num, n);
103  BOOST_CHECK(num.ToString() == "-5");
104  }
105  {
106  n = std::numeric_limits<int64>::min();
107  CBigNum num(n);
108  BOOST_CHECK(num.ToString() == "-9223372036854775808");
109  num.setulong(0);
110  BOOST_CHECK(num.ToString() == "0");
111  mysetint64(num, n);
112  BOOST_CHECK(num.ToString() == "-9223372036854775808");
113  }
114  {
115  n = std::numeric_limits<int64>::max();
116  CBigNum num(n);
117  BOOST_CHECK(num.ToString() == "9223372036854775807");
118  num.setulong(0);
119  BOOST_CHECK(num.ToString() == "0");
120  mysetint64(num, n);
121  BOOST_CHECK(num.ToString() == "9223372036854775807");
122  }
123 }
124 
125 
126 BOOST_AUTO_TEST_CASE(bignum_SetCompact)
127 {
128  CBigNum num;
129  num.SetCompact(0);
130  BOOST_CHECK_EQUAL(num.GetHex(), "0");
131  BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
132 
133  num.SetCompact(0x00123456);
134  BOOST_CHECK_EQUAL(num.GetHex(), "0");
135  BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
136 
137  num.SetCompact(0x01123456);
138  BOOST_CHECK_EQUAL(num.GetHex(), "12");
139  BOOST_CHECK_EQUAL(num.GetCompact(), 0x01120000U);
140 
141  // Make sure that we don't generate compacts with the 0x00800000 bit set
142  num = 0x80;
143  BOOST_CHECK_EQUAL(num.GetCompact(), 0x02008000U);
144 
145  num.SetCompact(0x01fedcba);
146  BOOST_CHECK_EQUAL(num.GetHex(), "-7e");
147  BOOST_CHECK_EQUAL(num.GetCompact(), 0x01fe0000U);
148 
149  num.SetCompact(0x02123456);
150  BOOST_CHECK_EQUAL(num.GetHex(), "1234");
151  BOOST_CHECK_EQUAL(num.GetCompact(), 0x02123400U);
152 
153  num.SetCompact(0x03123456);
154  BOOST_CHECK_EQUAL(num.GetHex(), "123456");
155  BOOST_CHECK_EQUAL(num.GetCompact(), 0x03123456U);
156 
157  num.SetCompact(0x04123456);
158  BOOST_CHECK_EQUAL(num.GetHex(), "12345600");
159  BOOST_CHECK_EQUAL(num.GetCompact(), 0x04123456U);
160 
161  num.SetCompact(0x04923456);
162  BOOST_CHECK_EQUAL(num.GetHex(), "-12345600");
163  BOOST_CHECK_EQUAL(num.GetCompact(), 0x04923456U);
164 
165  num.SetCompact(0x05009234);
166  BOOST_CHECK_EQUAL(num.GetHex(), "92340000");
167  BOOST_CHECK_EQUAL(num.GetCompact(), 0x05009234U);
168 
169  num.SetCompact(0x20123456);
170  BOOST_CHECK_EQUAL(num.GetHex(), "1234560000000000000000000000000000000000000000000000000000000000");
171  BOOST_CHECK_EQUAL(num.GetCompact(), 0x20123456U);
172 
173  num.SetCompact(0xff123456);
174  BOOST_CHECK_EQUAL(num.GetHex(), "123456000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
175  BOOST_CHECK_EQUAL(num.GetCompact(), 0xff123456U);
176 }
177 
178 BOOST_AUTO_TEST_SUITE_END()
std::string GetHex() const
Definition: bignum.h:388
void setulong(unsigned long n)
Definition: bignum.h:100
void setint64(int64 sn)
Definition: bignum.h:125
#define NOINLINE
CBigNum & SetCompact(unsigned int nCompact)
Definition: bignum.h:289
C++ wrapper for BIGNUM (OpenSSL bignum)
Definition: bignum.h:51
BOOST_AUTO_TEST_CASE(bignum_setint64)
NOINLINE void mysetint64(CBigNum &num, int64 n)
unsigned int GetCompact() const
Definition: bignum.h:308
std::string ToString(int nBase=10) const
Definition: bignum.h:362
long long int64
Definition: serialize.h:25