t_amount.cc 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394
  1. #define BOOST_TEST_DYN_LINK
  2. #define BOOST_TEST_MODULE math
  3. #include <boost/test/unit_test.hpp>
  4. #include <system.hh>
  5. #include "amount.h"
  6. #include "commodity.h"
  7. #define internalAmount(x) amount_t::exact(x)
  8. using namespace ledger;
  9. struct amount_fixture {
  10. amount_fixture() {
  11. times_initialize();
  12. amount_t::initialize();
  13. // Cause the display precision for dollars to be initialized to 2.
  14. amount_t x1("$1.00");
  15. BOOST_CHECK(x1);
  16. amount_t::stream_fullstrings = true; // make reports from UnitTests accurate
  17. }
  18. ~amount_fixture() {
  19. amount_t::stream_fullstrings = false;
  20. amount_t::shutdown();
  21. times_shutdown();
  22. }
  23. };
  24. BOOST_FIXTURE_TEST_SUITE(amount, amount_fixture)
  25. BOOST_AUTO_TEST_CASE(testParser)
  26. {
  27. amount_t x0;
  28. amount_t x1;
  29. amount_t x2;
  30. amount_t x3;
  31. amount_t x4("123.456");
  32. amount_t x5(x4);
  33. amount_t x6(x4);
  34. amount_t x7(x4);
  35. amount_t x8("$123.45");
  36. amount_t x9(x8);
  37. amount_t x10(x8);
  38. amount_t x11(x8);
  39. amount_t x12("$100");
  40. BOOST_CHECK_EQUAL(amount_t::precision_t(2), x12.commodity().precision());
  41. #ifndef NOT_FOR_PYTHON
  42. string buf("$100...");
  43. std::istringstream input(buf);
  44. amount_t x13;
  45. x13.parse(input);
  46. BOOST_CHECK_EQUAL(x12, x13);
  47. #endif // NOT_FOR_PYTHON
  48. amount_t x14;
  49. BOOST_CHECK_THROW(x14.parse("DM"), amount_error);
  50. amount_t x15("$1.000.000,00"); // parsing this switches us to European
  51. amount_t x16("$2000");
  52. BOOST_CHECK_EQUAL(string("$2.000,00"), x16.to_string());
  53. x16.parse("$2000,00");
  54. BOOST_CHECK_EQUAL(string("$2.000,00"), x16.to_string());
  55. // Since use of a decimal-comma is an additive quality, we must switch back
  56. // to decimal-period manually.
  57. x15.commodity().drop_flags(COMMODITY_STYLE_DECIMAL_COMMA);
  58. amount_t x17("$1,000,000.00"); // parsing this switches back to American
  59. amount_t x18("$2000");
  60. BOOST_CHECK_EQUAL(string("$2,000.00"), x18.to_string());
  61. x18.parse("$2,000");
  62. BOOST_CHECK_EQUAL(string("$2,000.00"), x18.to_string());
  63. BOOST_CHECK_EQUAL(x15, x17);
  64. amount_t x19("EUR 1000");
  65. amount_t x20("EUR 1000");
  66. BOOST_CHECK_EQUAL(string("EUR 1000"), x19.to_string());
  67. BOOST_CHECK_EQUAL(string("EUR 1000"), x20.to_string());
  68. x1.parse("$100.0000", PARSE_NO_MIGRATE);
  69. BOOST_CHECK_EQUAL(amount_t::precision_t(2), x12.commodity().precision());
  70. BOOST_CHECK_EQUAL(x1.commodity(), x12.commodity());
  71. BOOST_CHECK_EQUAL(x1, x12);
  72. x0.parse("$100.0000");
  73. BOOST_CHECK_EQUAL(amount_t::precision_t(4), x12.commodity().precision());
  74. BOOST_CHECK_EQUAL(x0.commodity(), x12.commodity());
  75. BOOST_CHECK_EQUAL(x0, x12);
  76. x2.parse("$100.00", PARSE_NO_REDUCE);
  77. BOOST_CHECK_EQUAL(x2, x12);
  78. x3.parse("$100.00", PARSE_NO_MIGRATE | PARSE_NO_REDUCE);
  79. BOOST_CHECK_EQUAL(x3, x12);
  80. x4.parse("$100.00");
  81. BOOST_CHECK_EQUAL(x4, x12);
  82. x5.parse("$100.00", PARSE_NO_MIGRATE);
  83. BOOST_CHECK_EQUAL(x5, x12);
  84. x6.parse("$100.00", PARSE_NO_REDUCE);
  85. BOOST_CHECK_EQUAL(x6, x12);
  86. x7.parse("$100.00", PARSE_NO_MIGRATE | PARSE_NO_REDUCE);
  87. BOOST_CHECK_EQUAL(x7, x12);
  88. x8.parse("$100.00");
  89. BOOST_CHECK_EQUAL(x8, x12);
  90. x9.parse("$100.00", PARSE_NO_MIGRATE);
  91. BOOST_CHECK_EQUAL(x9, x12);
  92. x10.parse("$100.00", PARSE_NO_REDUCE);
  93. BOOST_CHECK_EQUAL(x10, x12);
  94. x11.parse("$100.00", PARSE_NO_MIGRATE | PARSE_NO_REDUCE);
  95. BOOST_CHECK_EQUAL(x11, x12);
  96. BOOST_CHECK(x0.valid());
  97. BOOST_CHECK(x1.valid());
  98. BOOST_CHECK(x2.valid());
  99. BOOST_CHECK(x3.valid());
  100. BOOST_CHECK(x5.valid());
  101. BOOST_CHECK(x6.valid());
  102. BOOST_CHECK(x7.valid());
  103. BOOST_CHECK(x8.valid());
  104. BOOST_CHECK(x9.valid());
  105. BOOST_CHECK(x10.valid());
  106. BOOST_CHECK(x11.valid());
  107. BOOST_CHECK(x12.valid());
  108. }
  109. BOOST_AUTO_TEST_CASE(testConstructors)
  110. {
  111. amount_t x0;
  112. amount_t x1(123456L);
  113. amount_t x2(123456UL);
  114. amount_t x3("123.456");
  115. amount_t x5("123456");
  116. amount_t x6("123.456");
  117. amount_t x7(string("123456"));
  118. amount_t x8(string("123.456"));
  119. amount_t x9(x3);
  120. amount_t x10(x6);
  121. amount_t x11(x8);
  122. BOOST_CHECK_EQUAL(amount_t(), x0);
  123. BOOST_CHECK_NE(amount_t("0"), x0);
  124. BOOST_CHECK_NE(amount_t("0.0"), x0);
  125. BOOST_CHECK_EQUAL(x2, x1);
  126. BOOST_CHECK_EQUAL(x5, x1);
  127. BOOST_CHECK_EQUAL(x7, x1);
  128. BOOST_CHECK_EQUAL(x6, x3);
  129. BOOST_CHECK_EQUAL(x8, x3);
  130. BOOST_CHECK_EQUAL(x10, x3);
  131. BOOST_CHECK_EQUAL(x10, x9);
  132. BOOST_CHECK(x0.valid());
  133. BOOST_CHECK(x1.valid());
  134. BOOST_CHECK(x2.valid());
  135. BOOST_CHECK(x3.valid());
  136. BOOST_CHECK(x5.valid());
  137. BOOST_CHECK(x6.valid());
  138. BOOST_CHECK(x7.valid());
  139. BOOST_CHECK(x8.valid());
  140. BOOST_CHECK(x9.valid());
  141. BOOST_CHECK(x10.valid());
  142. BOOST_CHECK(x11.valid());
  143. }
  144. BOOST_AUTO_TEST_CASE(testCommodityConstructors)
  145. {
  146. amount_t x1("$123.45");
  147. amount_t x2("-$123.45");
  148. amount_t x3("$-123.45");
  149. amount_t x4("DM 123.45");
  150. amount_t x5("-DM 123.45");
  151. amount_t x6("DM -123.45");
  152. amount_t x7("123.45 euro");
  153. amount_t x8("-123.45 euro");
  154. amount_t x9("123.45€");
  155. amount_t x10("-123.45€");
  156. BOOST_CHECK_EQUAL(amount_t("$123.45"), x1);
  157. BOOST_CHECK_EQUAL(amount_t("-$123.45"), x2);
  158. BOOST_CHECK_EQUAL(amount_t("$-123.45"), x3);
  159. BOOST_CHECK_EQUAL(amount_t("DM 123.45"), x4);
  160. BOOST_CHECK_EQUAL(amount_t("-DM 123.45"), x5);
  161. BOOST_CHECK_EQUAL(amount_t("DM -123.45"), x6);
  162. BOOST_CHECK_EQUAL(amount_t("123.45 euro"), x7);
  163. BOOST_CHECK_EQUAL(amount_t("-123.45 euro"), x8);
  164. BOOST_CHECK_EQUAL(amount_t("123.45€"), x9);
  165. BOOST_CHECK_EQUAL(amount_t("-123.45€"), x10);
  166. BOOST_CHECK_EQUAL(string("$123.45"), x1.to_string());
  167. BOOST_CHECK_EQUAL(string("$-123.45"), x2.to_string());
  168. BOOST_CHECK_EQUAL(string("$-123.45"), x3.to_string());
  169. BOOST_CHECK_EQUAL(string("DM 123.45"), x4.to_string());
  170. BOOST_CHECK_EQUAL(string("DM -123.45"), x5.to_string());
  171. BOOST_CHECK_EQUAL(string("DM -123.45"), x6.to_string());
  172. BOOST_CHECK_EQUAL(string("123.45 euro"), x7.to_string());
  173. BOOST_CHECK_EQUAL(string("-123.45 euro"), x8.to_string());
  174. BOOST_CHECK_EQUAL(string("123.45€"), x9.to_string());
  175. BOOST_CHECK_EQUAL(string("-123.45€"), x10.to_string());
  176. BOOST_CHECK(x1.valid());
  177. BOOST_CHECK(x2.valid());
  178. BOOST_CHECK(x3.valid());
  179. BOOST_CHECK(x4.valid());
  180. BOOST_CHECK(x5.valid());
  181. BOOST_CHECK(x6.valid());
  182. BOOST_CHECK(x7.valid());
  183. BOOST_CHECK(x8.valid());
  184. BOOST_CHECK(x9.valid());
  185. BOOST_CHECK(x10.valid());
  186. }
  187. #ifndef NOT_FOR_PYTHON
  188. BOOST_AUTO_TEST_CASE(testAssignment)
  189. {
  190. amount_t x0;
  191. amount_t x1;
  192. amount_t x2;
  193. amount_t x3;
  194. amount_t x5;
  195. amount_t x6;
  196. amount_t x7;
  197. amount_t x8;
  198. amount_t x9;
  199. amount_t x10;
  200. x1 = 123456L;
  201. x2 = 123456UL;
  202. x3 = "123.456";
  203. x5 = "123456";
  204. x6 = "123.456";
  205. x7 = string("123456");
  206. x8 = string("123.456");
  207. x9 = x3;
  208. x10 = amount_t(x6);
  209. BOOST_CHECK_EQUAL(x2, x1);
  210. BOOST_CHECK_EQUAL(x5, x1);
  211. BOOST_CHECK_EQUAL(x7, x1);
  212. BOOST_CHECK_EQUAL(x6, x3);
  213. BOOST_CHECK_EQUAL(x8, x3);
  214. BOOST_CHECK_EQUAL(x10, x3);
  215. BOOST_CHECK_EQUAL(x10, x9);
  216. BOOST_CHECK(! x1.is_null());
  217. x1 = x0; // sets x1 back to uninitialized state
  218. BOOST_CHECK(x0.is_null());
  219. BOOST_CHECK(x1.is_null());
  220. BOOST_CHECK(x0.valid());
  221. BOOST_CHECK(x1.valid());
  222. BOOST_CHECK(x2.valid());
  223. BOOST_CHECK(x3.valid());
  224. BOOST_CHECK(x5.valid());
  225. BOOST_CHECK(x6.valid());
  226. BOOST_CHECK(x7.valid());
  227. BOOST_CHECK(x8.valid());
  228. BOOST_CHECK(x9.valid());
  229. BOOST_CHECK(x10.valid());
  230. }
  231. BOOST_AUTO_TEST_CASE(testCommodityAssignment)
  232. {
  233. amount_t x1;
  234. amount_t x2;
  235. amount_t x3;
  236. amount_t x4;
  237. amount_t x5;
  238. amount_t x6;
  239. amount_t x7;
  240. amount_t x8;
  241. amount_t x9;
  242. amount_t x10;
  243. x1 = "$123.45";
  244. x2 = "-$123.45";
  245. x3 = "$-123.45";
  246. x4 = "DM 123.45";
  247. x5 = "-DM 123.45";
  248. x6 = "DM -123.45";
  249. x7 = "123.45 euro";
  250. x8 = "-123.45 euro";
  251. x9 = "123.45€";
  252. x10 = "-123.45€";
  253. BOOST_CHECK_EQUAL(amount_t("$123.45"), x1);
  254. BOOST_CHECK_EQUAL(amount_t("-$123.45"), x2);
  255. BOOST_CHECK_EQUAL(amount_t("$-123.45"), x3);
  256. BOOST_CHECK_EQUAL(amount_t("DM 123.45"), x4);
  257. BOOST_CHECK_EQUAL(amount_t("-DM 123.45"), x5);
  258. BOOST_CHECK_EQUAL(amount_t("DM -123.45"), x6);
  259. BOOST_CHECK_EQUAL(amount_t("123.45 euro"), x7);
  260. BOOST_CHECK_EQUAL(amount_t("-123.45 euro"), x8);
  261. BOOST_CHECK_EQUAL(amount_t("123.45€"), x9);
  262. BOOST_CHECK_EQUAL(amount_t("-123.45€"), x10);
  263. BOOST_CHECK_EQUAL(string("$123.45"), x1.to_string());
  264. BOOST_CHECK_EQUAL(string("$-123.45"), x2.to_string());
  265. BOOST_CHECK_EQUAL(string("$-123.45"), x3.to_string());
  266. BOOST_CHECK_EQUAL(string("DM 123.45"), x4.to_string());
  267. BOOST_CHECK_EQUAL(string("DM -123.45"), x5.to_string());
  268. BOOST_CHECK_EQUAL(string("DM -123.45"), x6.to_string());
  269. BOOST_CHECK_EQUAL(string("123.45 euro"), x7.to_string());
  270. BOOST_CHECK_EQUAL(string("-123.45 euro"), x8.to_string());
  271. BOOST_CHECK_EQUAL(string("123.45€"), x9.to_string());
  272. BOOST_CHECK_EQUAL(string("-123.45€"), x10.to_string());
  273. BOOST_CHECK(x1.valid());
  274. BOOST_CHECK(x2.valid());
  275. BOOST_CHECK(x3.valid());
  276. BOOST_CHECK(x4.valid());
  277. BOOST_CHECK(x5.valid());
  278. BOOST_CHECK(x6.valid());
  279. BOOST_CHECK(x7.valid());
  280. BOOST_CHECK(x8.valid());
  281. BOOST_CHECK(x9.valid());
  282. BOOST_CHECK(x10.valid());
  283. }
  284. #endif // NOT_FOR_PYTHON
  285. BOOST_AUTO_TEST_CASE(testEquality)
  286. {
  287. amount_t x1(123456L);
  288. amount_t x2(456789L);
  289. amount_t x3(333333L);
  290. amount_t x4("123456.0");
  291. amount_t x5("123456.0");
  292. amount_t x6("123456.0");
  293. BOOST_CHECK(x1 == 123456L);
  294. BOOST_CHECK(x1 != x2);
  295. BOOST_CHECK(x1 == (x2 - x3));
  296. BOOST_CHECK(x1 == x4);
  297. BOOST_CHECK(x4 == x5);
  298. BOOST_CHECK(x4 == x6);
  299. BOOST_CHECK(x1 == 123456L);
  300. BOOST_CHECK(123456L == x1);
  301. BOOST_CHECK(x1 == 123456UL);
  302. BOOST_CHECK(123456UL == x1);
  303. BOOST_CHECK(x1 == amount_t("123456.0"));
  304. BOOST_CHECK(amount_t("123456.0") == x1);
  305. BOOST_CHECK(x1.valid());
  306. BOOST_CHECK(x2.valid());
  307. BOOST_CHECK(x3.valid());
  308. BOOST_CHECK(x4.valid());
  309. BOOST_CHECK(x5.valid());
  310. BOOST_CHECK(x6.valid());
  311. }
  312. BOOST_AUTO_TEST_CASE(testCommodityEquality)
  313. {
  314. amount_t x0;
  315. amount_t x1("$123.45");
  316. amount_t x2("-$123.45");
  317. amount_t x3("$-123.45");
  318. amount_t x4("DM 123.45");
  319. amount_t x5("-DM 123.45");
  320. amount_t x6("DM -123.45");
  321. amount_t x7("123.45 euro");
  322. amount_t x8("-123.45 euro");
  323. amount_t x9("123.45€");
  324. amount_t x10("-123.45€");
  325. BOOST_CHECK(x0.is_null());
  326. BOOST_CHECK_THROW(x0.is_zero(), amount_error);
  327. BOOST_CHECK_THROW(x0.is_realzero(), amount_error);
  328. BOOST_CHECK_THROW(x0.sign(), amount_error);
  329. BOOST_CHECK_THROW(x0.compare(x1), amount_error);
  330. BOOST_CHECK_THROW(x0.compare(x2), amount_error);
  331. BOOST_CHECK_THROW(x0.compare(x0), amount_error);
  332. BOOST_CHECK(x1 != x2);
  333. BOOST_CHECK(x1 != x4);
  334. BOOST_CHECK(x1 != x7);
  335. BOOST_CHECK(x1 != x9);
  336. BOOST_CHECK(x2 == x3);
  337. BOOST_CHECK(x4 != x5);
  338. BOOST_CHECK(x5 == x6);
  339. BOOST_CHECK(x7 == - x8);
  340. BOOST_CHECK(x9 == - x10);
  341. BOOST_CHECK(x0.valid());
  342. BOOST_CHECK(x1.valid());
  343. BOOST_CHECK(x2.valid());
  344. BOOST_CHECK(x3.valid());
  345. BOOST_CHECK(x4.valid());
  346. BOOST_CHECK(x5.valid());
  347. BOOST_CHECK(x6.valid());
  348. BOOST_CHECK(x7.valid());
  349. BOOST_CHECK(x8.valid());
  350. BOOST_CHECK(x9.valid());
  351. BOOST_CHECK(x10.valid());
  352. }
  353. BOOST_AUTO_TEST_CASE(testComparisons)
  354. {
  355. amount_t x0;
  356. amount_t x1(-123L);
  357. amount_t x2(123L);
  358. amount_t x3("-123.45");
  359. amount_t x4("123.45");
  360. amount_t x5("-123.45");
  361. amount_t x6("123.45");
  362. BOOST_CHECK_THROW(x0 > x1, amount_error);
  363. BOOST_CHECK_THROW(x0 < x2, amount_error);
  364. BOOST_CHECK_THROW(x0 > x3, amount_error);
  365. BOOST_CHECK_THROW(x0 < x4, amount_error);
  366. BOOST_CHECK_THROW(x0 > x5, amount_error);
  367. BOOST_CHECK_THROW(x0 < x6, amount_error);
  368. BOOST_CHECK(x1 > x3);
  369. BOOST_CHECK(x3 <= x5);
  370. BOOST_CHECK(x3 >= x5);
  371. BOOST_CHECK(x3 < x1);
  372. BOOST_CHECK(x3 < x4);
  373. BOOST_CHECK(x1 < 100L);
  374. BOOST_CHECK(100L > x1);
  375. BOOST_CHECK(x1 < 100UL);
  376. BOOST_CHECK(100UL > x1);
  377. #ifndef NOT_FOR_PYTHON
  378. BOOST_CHECK(x1 < 100.0);
  379. BOOST_CHECK(100.0 > x1);
  380. #endif // NOT_FOR_PYTHON
  381. BOOST_CHECK(x0.valid());
  382. BOOST_CHECK(x1.valid());
  383. BOOST_CHECK(x2.valid());
  384. BOOST_CHECK(x3.valid());
  385. BOOST_CHECK(x4.valid());
  386. BOOST_CHECK(x5.valid());
  387. BOOST_CHECK(x6.valid());
  388. }
  389. BOOST_AUTO_TEST_CASE(testCommodityComparisons)
  390. {
  391. amount_t x1("$-123");
  392. amount_t x2("$123.00");
  393. amount_t x3(internalAmount("$-123.4544"));
  394. amount_t x4(internalAmount("$123.4544"));
  395. amount_t x5("$-123.45");
  396. amount_t x6("$123.45");
  397. amount_t x7("DM 123.45");
  398. BOOST_CHECK(x1 > x3);
  399. BOOST_CHECK(x3 <= x5);
  400. BOOST_CHECK(x3 < x5);
  401. BOOST_CHECK(x3 <= x5);
  402. #ifndef NOT_FOR_PYTHON
  403. BOOST_CHECK(! (x3 == x5));
  404. #endif
  405. BOOST_CHECK(x3 < x1);
  406. BOOST_CHECK(x3 < x4);
  407. #ifndef NOT_FOR_PYTHON
  408. BOOST_CHECK(! (x6 == x7));
  409. #endif
  410. BOOST_CHECK_THROW(x6 < x7, amount_error);
  411. BOOST_CHECK(x1.valid());
  412. BOOST_CHECK(x2.valid());
  413. BOOST_CHECK(x3.valid());
  414. BOOST_CHECK(x4.valid());
  415. BOOST_CHECK(x5.valid());
  416. BOOST_CHECK(x6.valid());
  417. }
  418. BOOST_AUTO_TEST_CASE(testIntegerAddition)
  419. {
  420. amount_t x0;
  421. amount_t x1(123L);
  422. amount_t y1(456L);
  423. BOOST_CHECK_EQUAL(amount_t(579L), x1 + y1);
  424. BOOST_CHECK_EQUAL(amount_t(579L), x1 + 456L);
  425. BOOST_CHECK_EQUAL(amount_t(579L), 456L + x1);
  426. x1 += amount_t(456L);
  427. BOOST_CHECK_EQUAL(amount_t(579L), x1);
  428. x1 += 456L;
  429. BOOST_CHECK_EQUAL(amount_t(1035L), x1);
  430. amount_t x4("123456789123456789123456789");
  431. BOOST_CHECK_EQUAL(amount_t("246913578246913578246913578"), x4 + x4);
  432. BOOST_CHECK(x0.valid());
  433. BOOST_CHECK(x1.valid());
  434. BOOST_CHECK(y1.valid());
  435. BOOST_CHECK(x4.valid());
  436. }
  437. BOOST_AUTO_TEST_CASE(testFractionalAddition)
  438. {
  439. amount_t x1("123.123");
  440. amount_t y1("456.456");
  441. BOOST_CHECK_EQUAL(amount_t("579.579"), x1 + y1);
  442. BOOST_CHECK_EQUAL(amount_t("579.579"), x1 + amount_t("456.456"));
  443. BOOST_CHECK_EQUAL(amount_t("579.579"), amount_t("456.456") + x1);
  444. x1 += amount_t("456.456");
  445. BOOST_CHECK_EQUAL(amount_t("579.579"), x1);
  446. x1 += amount_t("456.456");
  447. BOOST_CHECK_EQUAL(amount_t("1036.035"), x1);
  448. x1 += 456L;
  449. BOOST_CHECK_EQUAL(amount_t("1492.035"), x1);
  450. amount_t x2("123456789123456789.123456789123456789");
  451. BOOST_CHECK_EQUAL(amount_t("246913578246913578.246913578246913578"), x2 + x2);
  452. BOOST_CHECK(x1.valid());
  453. BOOST_CHECK(y1.valid());
  454. BOOST_CHECK(x2.valid());
  455. }
  456. BOOST_AUTO_TEST_CASE(testCommodityAddition)
  457. {
  458. amount_t x0;
  459. amount_t x1("$123.45");
  460. amount_t x2(internalAmount("$123.456789"));
  461. amount_t x3("DM 123.45");
  462. amount_t x4("123.45 euro");
  463. amount_t x5("123.45€");
  464. amount_t x6("123.45");
  465. BOOST_CHECK_EQUAL(amount_t("$246.90"), x1 + x1);
  466. BOOST_CHECK_NE(amount_t("$246.91"), x1 + x2);
  467. BOOST_CHECK_EQUAL(internalAmount("$246.906789"), x1 + x2);
  468. // Converting to string drops internal precision
  469. BOOST_CHECK_EQUAL(string("$246.90"), (x1 + x1).to_string());
  470. BOOST_CHECK_EQUAL(string("$246.91"), (x1 + x2).to_string());
  471. BOOST_CHECK_THROW(x1 + x0, amount_error);
  472. BOOST_CHECK_THROW(x0 + x1, amount_error);
  473. BOOST_CHECK_THROW(x0 + x0, amount_error);
  474. BOOST_CHECK_THROW(x1 + x3, amount_error);
  475. BOOST_CHECK_THROW(x1 + x4, amount_error);
  476. BOOST_CHECK_THROW(x1 + x5, amount_error);
  477. BOOST_CHECK_EQUAL(string("$246.90"), (x1 + x6).to_string());
  478. #ifndef NOT_FOR_PYTHON
  479. BOOST_CHECK_EQUAL(string("$246.90"), (x1 + 123.45).to_string());
  480. #endif // NOT_FOR_PYTHON
  481. BOOST_CHECK_EQUAL(string("$246.45"), (x1 + 123L).to_string());
  482. BOOST_CHECK_EQUAL(amount_t("DM 246.90"), x3 + x3);
  483. BOOST_CHECK_EQUAL(amount_t("246.90 euro"), x4 + x4);
  484. BOOST_CHECK_EQUAL(amount_t("246.90€"), x5 + x5);
  485. BOOST_CHECK_EQUAL(string("DM 246.90"), (x3 + x3).to_string());
  486. BOOST_CHECK_EQUAL(string("246.90 euro"), (x4 + x4).to_string());
  487. BOOST_CHECK_EQUAL(string("246.90€"), (x5 + x5).to_string());
  488. x1 += amount_t("$456.45");
  489. BOOST_CHECK_EQUAL(amount_t("$579.90"), x1);
  490. x1 += amount_t("$456.45");
  491. BOOST_CHECK_EQUAL(amount_t("$1036.35"), x1);
  492. x1 += amount_t("$456");
  493. BOOST_CHECK_EQUAL(amount_t("$1492.35"), x1);
  494. amount_t x7(internalAmount("$123456789123456789.123456789123456789"));
  495. BOOST_CHECK_EQUAL(internalAmount("$246913578246913578.246913578246913578"), x7 + x7);
  496. BOOST_CHECK(x1.valid());
  497. BOOST_CHECK(x2.valid());
  498. BOOST_CHECK(x3.valid());
  499. BOOST_CHECK(x4.valid());
  500. BOOST_CHECK(x5.valid());
  501. BOOST_CHECK(x6.valid());
  502. BOOST_CHECK(x7.valid());
  503. }
  504. BOOST_AUTO_TEST_CASE(testIntegerSubtraction)
  505. {
  506. amount_t x1(123L);
  507. amount_t y1(456L);
  508. BOOST_CHECK_EQUAL(amount_t(333L), y1 - x1);
  509. BOOST_CHECK_EQUAL(amount_t(-333L), x1 - y1);
  510. BOOST_CHECK_EQUAL(amount_t(23L), x1 - 100L);
  511. BOOST_CHECK_EQUAL(amount_t(-23L), 100L - x1);
  512. x1 -= amount_t(456L);
  513. BOOST_CHECK_EQUAL(amount_t(-333L), x1);
  514. x1 -= 456L;
  515. BOOST_CHECK_EQUAL(amount_t(-789L), x1);
  516. amount_t x4("123456789123456789123456789");
  517. amount_t y4("8238725986235986");
  518. BOOST_CHECK_EQUAL(amount_t("123456789115218063137220803"), x4 - y4);
  519. BOOST_CHECK_EQUAL(amount_t("-123456789115218063137220803"), y4 - x4);
  520. BOOST_CHECK(x1.valid());
  521. BOOST_CHECK(y1.valid());
  522. BOOST_CHECK(x4.valid());
  523. BOOST_CHECK(y4.valid());
  524. }
  525. BOOST_AUTO_TEST_CASE(testFractionalSubtraction)
  526. {
  527. amount_t x1("123.123");
  528. amount_t y1("456.456");
  529. BOOST_CHECK_EQUAL(amount_t("-333.333"), x1 - y1);
  530. BOOST_CHECK_EQUAL(amount_t("333.333"), y1 - x1);
  531. x1 -= amount_t("456.456");
  532. BOOST_CHECK_EQUAL(amount_t("-333.333"), x1);
  533. x1 -= amount_t("456.456");
  534. BOOST_CHECK_EQUAL(amount_t("-789.789"), x1);
  535. x1 -= 456L;
  536. BOOST_CHECK_EQUAL(amount_t("-1245.789"), x1);
  537. amount_t x2("123456789123456789.123456789123456789");
  538. amount_t y2("9872345982459.248974239578");
  539. BOOST_CHECK_EQUAL(amount_t("123446916777474329.874482549545456789"), x2 - y2);
  540. BOOST_CHECK_EQUAL(amount_t("-123446916777474329.874482549545456789"), y2 - x2);
  541. BOOST_CHECK(x1.valid());
  542. BOOST_CHECK(y1.valid());
  543. BOOST_CHECK(x2.valid());
  544. BOOST_CHECK(y2.valid());
  545. }
  546. BOOST_AUTO_TEST_CASE(testCommoditySubtraction)
  547. {
  548. amount_t x0;
  549. amount_t x1("$123.45");
  550. amount_t x2(internalAmount("$123.456789"));
  551. amount_t x3("DM 123.45");
  552. amount_t x4("123.45 euro");
  553. amount_t x5("123.45€");
  554. amount_t x6("123.45");
  555. BOOST_CHECK_NE(amount_t(), x1 - x1);
  556. BOOST_CHECK_EQUAL(amount_t("$0"), x1 - x1);
  557. BOOST_CHECK_EQUAL(amount_t("$23.45"), x1 - amount_t("$100.00"));
  558. BOOST_CHECK_EQUAL(amount_t("$-23.45"), amount_t("$100.00") - x1);
  559. BOOST_CHECK_NE(amount_t("$-0.01"), x1 - x2);
  560. BOOST_CHECK_EQUAL(internalAmount("$-0.006789"), x1 - x2);
  561. // Converting to string drops internal precision. If an amount is
  562. // zero, it drops the commodity as well.
  563. BOOST_CHECK_EQUAL(string("$0.00"), (x1 - x1).to_string());
  564. BOOST_CHECK_EQUAL(string("$-0.01"), (x1 - x2).to_string());
  565. BOOST_CHECK_THROW(x1 - x0, amount_error);
  566. BOOST_CHECK_THROW(x0 - x1, amount_error);
  567. BOOST_CHECK_THROW(x0 - x0, amount_error);
  568. BOOST_CHECK_THROW(x1 - x3, amount_error);
  569. BOOST_CHECK_THROW(x1 - x4, amount_error);
  570. BOOST_CHECK_THROW(x1 - x5, amount_error);
  571. BOOST_CHECK_EQUAL(string("$0.00"), (x1 - x6).to_string());
  572. #ifndef NOT_FOR_PYTHON
  573. BOOST_CHECK_EQUAL(string("$-0.00"), (x1 - 123.45).to_string());
  574. #endif // NOT_FOR_PYTHON
  575. BOOST_CHECK_EQUAL(string("$0.45"), (x1 - 123L).to_string());
  576. BOOST_CHECK_EQUAL(amount_t("DM 0.00"), x3 - x3);
  577. BOOST_CHECK_EQUAL(amount_t("DM 23.45"), x3 - amount_t("DM 100.00"));
  578. BOOST_CHECK_EQUAL(amount_t("DM -23.45"), amount_t("DM 100.00") - x3);
  579. BOOST_CHECK_EQUAL(amount_t("0.00 euro"), x4 - x4);
  580. BOOST_CHECK_EQUAL(amount_t("23.45 euro"), x4 - amount_t("100.00 euro"));
  581. BOOST_CHECK_EQUAL(amount_t("-23.45 euro"), amount_t("100.00 euro") - x4);
  582. BOOST_CHECK_EQUAL(amount_t("0.00€"), x5 - x5);
  583. BOOST_CHECK_EQUAL(amount_t("23.45€"), x5 - amount_t("100.00€"));
  584. BOOST_CHECK_EQUAL(amount_t("-23.45€"), amount_t("100.00€") - x5);
  585. BOOST_CHECK_EQUAL(string("DM 0.00"), (x3 - x3).to_string());
  586. BOOST_CHECK_EQUAL(string("DM 23.45"), (x3 - amount_t("DM 100.00")).to_string());
  587. BOOST_CHECK_EQUAL(string("DM -23.45"), (amount_t("DM 100.00") - x3).to_string());
  588. BOOST_CHECK_EQUAL(string("0.00 euro"), (x4 - x4).to_string());
  589. BOOST_CHECK_EQUAL(string("23.45 euro"), (x4 - amount_t("100.00 euro")).to_string());
  590. BOOST_CHECK_EQUAL(string("-23.45 euro"), (amount_t("100.00 euro") - x4).to_string());
  591. BOOST_CHECK_EQUAL(string("0.00€"), (x5 - x5).to_string());
  592. BOOST_CHECK_EQUAL(string("23.45€"), (x5 - amount_t("100.00€")).to_string());
  593. BOOST_CHECK_EQUAL(string("-23.45€"), (amount_t("100.00€") - x5).to_string());
  594. x1 -= amount_t("$456.45");
  595. BOOST_CHECK_EQUAL(amount_t("$-333.00"), x1);
  596. x1 -= amount_t("$456.45");
  597. BOOST_CHECK_EQUAL(amount_t("$-789.45"), x1);
  598. x1 -= amount_t("$456");
  599. BOOST_CHECK_EQUAL(amount_t("$-1245.45"), x1);
  600. amount_t x7(internalAmount("$123456789123456789.123456789123456789"));
  601. amount_t x8(internalAmount("$2354974984698.98459845984598"));
  602. BOOST_CHECK_EQUAL(internalAmount("$123454434148472090.138858329277476789"), x7 - x8);
  603. BOOST_CHECK_EQUAL(string("$123454434148472090.138858329277476789"), (x7 - x8).to_string());
  604. BOOST_CHECK_EQUAL(string("$123454434148472090.14"),
  605. (amount_t("$1.00") * (x7 - x8)).to_string());
  606. BOOST_CHECK_EQUAL(internalAmount("$-123454434148472090.138858329277476789"), x8 - x7);
  607. BOOST_CHECK_EQUAL(string("$-123454434148472090.138858329277476789"), (x8 - x7).to_string());
  608. BOOST_CHECK_EQUAL(string("$-123454434148472090.14"),
  609. (amount_t("$1.00") * (x8 - x7)).to_string());
  610. BOOST_CHECK(x1.valid());
  611. BOOST_CHECK(x2.valid());
  612. BOOST_CHECK(x3.valid());
  613. BOOST_CHECK(x4.valid());
  614. BOOST_CHECK(x5.valid());
  615. BOOST_CHECK(x6.valid());
  616. BOOST_CHECK(x7.valid());
  617. BOOST_CHECK(x8.valid());
  618. }
  619. BOOST_AUTO_TEST_CASE(testIntegerMultiplication)
  620. {
  621. amount_t x1(123L);
  622. amount_t y1(456L);
  623. BOOST_CHECK_EQUAL(amount_t(0L), x1 * 0L);
  624. BOOST_CHECK_EQUAL(amount_t(0L), amount_t(0L) * x1);
  625. BOOST_CHECK_EQUAL(amount_t(0L), 0L * x1);
  626. BOOST_CHECK_EQUAL(x1, x1 * 1L);
  627. BOOST_CHECK_EQUAL(x1, amount_t(1L) * x1);
  628. BOOST_CHECK_EQUAL(x1, 1L * x1);
  629. BOOST_CHECK_EQUAL(- x1, x1 * -1L);
  630. BOOST_CHECK_EQUAL(- x1, amount_t(-1L) * x1);
  631. BOOST_CHECK_EQUAL(- x1, -1L * x1);
  632. BOOST_CHECK_EQUAL(amount_t(56088L), x1 * y1);
  633. BOOST_CHECK_EQUAL(amount_t(56088L), y1 * x1);
  634. BOOST_CHECK_EQUAL(amount_t(56088L), x1 * 456L);
  635. BOOST_CHECK_EQUAL(amount_t(56088L), amount_t(456L) * x1);
  636. BOOST_CHECK_EQUAL(amount_t(56088L), 456L * x1);
  637. x1 *= amount_t(123L);
  638. BOOST_CHECK_EQUAL(amount_t(15129L), x1);
  639. x1 *= 123L;
  640. BOOST_CHECK_EQUAL(amount_t(1860867L), x1);
  641. amount_t x4("123456789123456789123456789");
  642. BOOST_CHECK_EQUAL(amount_t("15241578780673678546105778281054720515622620750190521"),
  643. x4 * x4);
  644. BOOST_CHECK(x1.valid());
  645. BOOST_CHECK(y1.valid());
  646. BOOST_CHECK(x4.valid());
  647. }
  648. BOOST_AUTO_TEST_CASE(testFractionalMultiplication)
  649. {
  650. amount_t x1("123.123");
  651. amount_t y1("456.456");
  652. BOOST_CHECK_EQUAL(amount_t(0L), x1 * 0L);
  653. BOOST_CHECK_EQUAL(amount_t(0L), amount_t(0L) * x1);
  654. BOOST_CHECK_EQUAL(amount_t(0L), 0L * x1);
  655. BOOST_CHECK_EQUAL(x1, x1 * 1L);
  656. BOOST_CHECK_EQUAL(x1, amount_t(1L) * x1);
  657. BOOST_CHECK_EQUAL(x1, 1L * x1);
  658. BOOST_CHECK_EQUAL(- x1, x1 * -1L);
  659. BOOST_CHECK_EQUAL(- x1, amount_t(-1L) * x1);
  660. BOOST_CHECK_EQUAL(- x1, -1L * x1);
  661. BOOST_CHECK_EQUAL(amount_t("56200.232088"), x1 * y1);
  662. BOOST_CHECK_EQUAL(amount_t("56200.232088"), y1 * x1);
  663. BOOST_CHECK_EQUAL(amount_t("56200.232088"), x1 * amount_t("456.456"));
  664. BOOST_CHECK_EQUAL(amount_t("56200.232088"), amount_t("456.456") * x1);
  665. BOOST_CHECK_EQUAL(amount_t("56200.232088"), amount_t("456.456") * x1);
  666. x1 *= amount_t("123.123");
  667. BOOST_CHECK_EQUAL(amount_t("15159.273129"), x1);
  668. x1 *= amount_t("123.123");
  669. BOOST_CHECK_EQUAL(amount_t("1866455.185461867"), x1);
  670. x1 *= 123L;
  671. BOOST_CHECK_EQUAL(amount_t("229573987.811809641"), x1);
  672. amount_t x2("123456789123456789.123456789123456789");
  673. BOOST_CHECK_EQUAL(amount_t("15241578780673678546105778311537878.046486820281054720515622620750190521"),
  674. x2 * x2);
  675. BOOST_CHECK(x1.valid());
  676. BOOST_CHECK(y1.valid());
  677. BOOST_CHECK(x2.valid());
  678. }
  679. BOOST_AUTO_TEST_CASE(testCommodityMultiplication)
  680. {
  681. amount_t x0;
  682. amount_t x1("$123.12");
  683. amount_t y1("$456.45");
  684. amount_t x2(internalAmount("$123.456789"));
  685. amount_t x3("DM 123.45");
  686. amount_t x4("123.45 euro");
  687. amount_t x5("123.45€");
  688. BOOST_CHECK_EQUAL(amount_t("$0.00"), x1 * 0L);
  689. BOOST_CHECK_EQUAL(amount_t("$0.00"), 0L * x1);
  690. BOOST_CHECK_EQUAL(x1, x1 * 1L);
  691. BOOST_CHECK_EQUAL(x1, 1L * x1);
  692. BOOST_CHECK_EQUAL(- x1, x1 * -1L);
  693. BOOST_CHECK_EQUAL(- x1, -1L * x1);
  694. BOOST_CHECK_EQUAL(internalAmount("$56198.124"), x1 * y1);
  695. BOOST_CHECK_EQUAL(string("$56198.12"), (x1 * y1).to_string());
  696. BOOST_CHECK_EQUAL(internalAmount("$56198.124"), y1 * x1);
  697. BOOST_CHECK_EQUAL(string("$56198.12"), (y1 * x1).to_string());
  698. // Internal amounts retain their precision, even when being
  699. // converted to strings
  700. BOOST_CHECK_EQUAL(internalAmount("$15199.99986168"), x1 * x2);
  701. BOOST_CHECK_EQUAL(internalAmount("$15199.99986168"), x2 * x1);
  702. BOOST_CHECK_EQUAL(string("$15200.00"), (x1 * x2).to_string());
  703. BOOST_CHECK_EQUAL(string("$15199.99986168"), (x2 * x1).to_string());
  704. BOOST_CHECK_THROW(x1 * x0, amount_error);
  705. BOOST_CHECK_THROW(x0 * x1, amount_error);
  706. BOOST_CHECK_THROW(x0 * x0, amount_error);
  707. //BOOST_CHECK_THROW(x1 * x3, amount_error);
  708. //BOOST_CHECK_THROW(x1 * x4, amount_error);
  709. //BOOST_CHECK_THROW(x1 * x5, amount_error);
  710. x1 *= amount_t("123.12");
  711. BOOST_CHECK_EQUAL(internalAmount("$15158.5344"), x1);
  712. BOOST_CHECK_EQUAL(string("$15158.53"), x1.to_string());
  713. x1 *= amount_t("123.12");
  714. BOOST_CHECK_EQUAL(internalAmount("$1866318.755328"), x1);
  715. BOOST_CHECK_EQUAL(string("$1866318.76"), x1.to_string());
  716. x1 *= 123L;
  717. BOOST_CHECK_EQUAL(internalAmount("$229557206.905344"), x1);
  718. BOOST_CHECK_EQUAL(string("$229557206.91"), x1.to_string());
  719. amount_t x7(internalAmount("$123456789123456789.123456789123456789"));
  720. BOOST_CHECK_EQUAL(internalAmount("$15241578780673678546105778311537878.046486820281054720515622620750190521"),
  721. x7 * x7);
  722. BOOST_CHECK(x1.valid());
  723. BOOST_CHECK(x2.valid());
  724. BOOST_CHECK(x3.valid());
  725. BOOST_CHECK(x4.valid());
  726. BOOST_CHECK(x5.valid());
  727. BOOST_CHECK(x7.valid());
  728. }
  729. BOOST_AUTO_TEST_CASE(testIntegerDivision)
  730. {
  731. amount_t x1(123L);
  732. amount_t y1(456L);
  733. BOOST_CHECK_THROW(x1 / 0L, amount_error);
  734. BOOST_CHECK_EQUAL(amount_t(0L), amount_t(0L) / x1);
  735. BOOST_CHECK_EQUAL(amount_t(0L), 0L / x1);
  736. BOOST_CHECK_EQUAL(x1, x1 / 1L);
  737. BOOST_CHECK_EQUAL(string("0.00813"), (amount_t(1L) / x1).to_string());
  738. BOOST_CHECK_EQUAL(string("0.00813"), (1L / x1).to_string());
  739. BOOST_CHECK_EQUAL(- x1, x1 / -1L);
  740. BOOST_CHECK_EQUAL(string("-0.00813"), (amount_t(-1L) / x1).to_string());
  741. BOOST_CHECK_EQUAL(string("-0.00813"), (-1L / x1).to_string());
  742. BOOST_CHECK_EQUAL(string("0.269737"), (x1 / y1).to_string());
  743. BOOST_CHECK_EQUAL(string("3.707317"), (y1 / x1).to_string());
  744. BOOST_CHECK_EQUAL(string("0.269737"), (x1 / 456L).to_string());
  745. BOOST_CHECK_EQUAL(string("3.707317"), (amount_t(456L) / x1).to_string());
  746. BOOST_CHECK_EQUAL(string("3.707317"), (456L / x1).to_string());
  747. x1 /= amount_t(456L);
  748. BOOST_CHECK_EQUAL(string("0.269737"), x1.to_string());
  749. x1 /= 456L;
  750. BOOST_CHECK_EQUAL(string("0.000591528163"), x1.to_string());
  751. amount_t x4("123456789123456789123456789");
  752. amount_t y4("56");
  753. BOOST_CHECK_EQUAL(amount_t(1L), x4 / x4);
  754. BOOST_CHECK_EQUAL(string("2204585520061728377204585.517857"), (x4 / y4).to_string());
  755. BOOST_CHECK_EQUAL(amount_t("0.000000000000000000000000000001"),
  756. amount_t("10") / amount_t("10000000000000000000000000000000"));
  757. BOOST_CHECK(x1.valid());
  758. BOOST_CHECK(y1.valid());
  759. BOOST_CHECK(x4.valid());
  760. BOOST_CHECK(y4.valid());
  761. }
  762. BOOST_AUTO_TEST_CASE(testFractionalDivision)
  763. {
  764. amount_t x1("123.123");
  765. amount_t y1("456.456");
  766. BOOST_CHECK_THROW(x1 / 0L, amount_error);
  767. BOOST_CHECK_EQUAL(string("0.0081219593"), (amount_t("1.0") / x1).to_string());
  768. BOOST_CHECK_EQUAL(string("0.0081219593"), (amount_t("1.0") / x1).to_string());
  769. BOOST_CHECK_EQUAL(x1, x1 / amount_t("1.0"));
  770. BOOST_CHECK_EQUAL(string("0.0081219593"), (amount_t("1.0") / x1).to_string());
  771. BOOST_CHECK_EQUAL(string("0.0081219593"), (amount_t("1.0") / x1).to_string());
  772. BOOST_CHECK_EQUAL(- x1, x1 / amount_t("-1.0"));
  773. BOOST_CHECK_EQUAL(string("-0.0081219593"), (amount_t("-1.0") / x1).to_string());
  774. BOOST_CHECK_EQUAL(string("-0.0081219593"), (amount_t("-1.0") / x1).to_string());
  775. BOOST_CHECK_EQUAL(string("0.269736842105"), (x1 / y1).to_string());
  776. BOOST_CHECK_EQUAL(string("3.707317073171"), (y1 / x1).to_string());
  777. BOOST_CHECK_EQUAL(string("0.269736842105"), (x1 / amount_t("456.456")).to_string());
  778. BOOST_CHECK_EQUAL(string("3.707317073171"), (amount_t("456.456") / x1).to_string());
  779. BOOST_CHECK_EQUAL(string("3.707317073171"), (amount_t("456.456") / x1).to_string());
  780. x1 /= amount_t("456.456");
  781. BOOST_CHECK_EQUAL(string("0.269736842105"), x1.to_string());
  782. x1 /= amount_t("456.456");
  783. BOOST_CHECK_EQUAL(string("0.000590937225286255757"), x1.to_string());
  784. x1 /= 456L;
  785. BOOST_CHECK_EQUAL(string("0.000001295914967733017011337"), x1.to_string());
  786. amount_t x4("1234567891234567.89123456789");
  787. amount_t y4("56.789");
  788. BOOST_CHECK_EQUAL(amount_t("1.0"), x4 / x4);
  789. BOOST_CHECK_EQUAL(string("21739560323910.75544972737484371973"), (x4 / y4).to_string());
  790. BOOST_CHECK(x1.valid());
  791. BOOST_CHECK(y1.valid());
  792. BOOST_CHECK(x4.valid());
  793. BOOST_CHECK(y4.valid());
  794. }
  795. BOOST_AUTO_TEST_CASE(testCommodityDivision)
  796. {
  797. amount_t x0;
  798. amount_t x1("$123.12");
  799. amount_t y1("$456.45");
  800. amount_t x2(internalAmount("$123.456789"));
  801. amount_t x3("DM 123.45");
  802. amount_t x4("123.45 euro");
  803. amount_t x5("123.45€");
  804. BOOST_CHECK_THROW(x1 / 0L, amount_error);
  805. BOOST_CHECK_EQUAL(amount_t("$0.00"), 0L / x1);
  806. BOOST_CHECK_EQUAL(x1, x1 / 1L);
  807. BOOST_CHECK_EQUAL(string("$0.00812216"), (1L / x1).to_fullstring());
  808. BOOST_CHECK_EQUAL(- x1, x1 / -1L);
  809. BOOST_CHECK_EQUAL(string("$-0.00812216"), (-1L / x1).to_fullstring());
  810. BOOST_CHECK_EQUAL(string("$0.26973382"), (x1 / y1).to_fullstring());
  811. BOOST_CHECK_EQUAL(string("$0.27"), (x1 / y1).to_string());
  812. BOOST_CHECK_EQUAL(string("$3.70735867"), (y1 / x1).to_fullstring());
  813. BOOST_CHECK_EQUAL(string("$3.71"), (y1 / x1).to_string());
  814. // Internal amounts retain their precision, even when being
  815. // converted to strings
  816. BOOST_CHECK_EQUAL(string("$0.99727201"), (x1 / x2).to_fullstring());
  817. BOOST_CHECK_EQUAL(string("$1.00273545321637"), (x2 / x1).to_fullstring());
  818. BOOST_CHECK_EQUAL(string("$1.00"), (x1 / x2).to_string());
  819. BOOST_CHECK_EQUAL(string("$1.00273545321637"), (x2 / x1).to_string());
  820. BOOST_CHECK_THROW(x1 / x0, amount_error);
  821. BOOST_CHECK_THROW(x0 / x1, amount_error);
  822. BOOST_CHECK_THROW(x0 / x0, amount_error);
  823. //BOOST_CHECK_THROW(x1 / x3, amount_error);
  824. //BOOST_CHECK_THROW(x1 / x4, amount_error);
  825. //BOOST_CHECK_THROW(x1 / x5, amount_error);
  826. x1 /= amount_t("123.12");
  827. BOOST_CHECK_EQUAL(string("$1.00"), x1.to_string());
  828. x1 /= amount_t("123.12");
  829. BOOST_CHECK_EQUAL(string("$0.00812216"), x1.to_fullstring());
  830. BOOST_CHECK_EQUAL(string("$0.01"), x1.to_string());
  831. x1 /= 123L;
  832. BOOST_CHECK_EQUAL(string("$0.00006603"), x1.to_fullstring());
  833. BOOST_CHECK_EQUAL(string("$0.00"), x1.to_string());
  834. amount_t x6(internalAmount("$237235987235987.98723987235978"));
  835. amount_t x7(internalAmount("$123456789123456789.123456789123456789"));
  836. BOOST_CHECK_EQUAL(amount_t("$1"), x7 / x7);
  837. BOOST_CHECK_EQUAL(string("$0.0019216115121765559608381226612019501"),
  838. (x6 / x7).to_fullstring());
  839. BOOST_CHECK_EQUAL(string("$520.39654928343335571379527154924040947272"),
  840. (x7 / x6).to_fullstring());
  841. BOOST_CHECK(x1.valid());
  842. BOOST_CHECK(x2.valid());
  843. BOOST_CHECK(x3.valid());
  844. BOOST_CHECK(x4.valid());
  845. BOOST_CHECK(x5.valid());
  846. BOOST_CHECK(x6.valid());
  847. BOOST_CHECK(x7.valid());
  848. }
  849. BOOST_AUTO_TEST_CASE(testNegation)
  850. {
  851. amount_t x0;
  852. amount_t x1(-123456L);
  853. amount_t x3("-123.456");
  854. amount_t x5("-123456");
  855. amount_t x6("-123.456");
  856. amount_t x7(string("-123456"));
  857. amount_t x8(string("-123.456"));
  858. amount_t x9(- x3);
  859. BOOST_CHECK_THROW(x0.negated(), amount_error);
  860. BOOST_CHECK_EQUAL(x5, x1);
  861. BOOST_CHECK_EQUAL(x7, x1);
  862. BOOST_CHECK_EQUAL(x6, x3);
  863. BOOST_CHECK_EQUAL(x8, x3);
  864. BOOST_CHECK_EQUAL(- x6, x9);
  865. BOOST_CHECK_EQUAL(x3.negated(), x9);
  866. amount_t x10(x9.negated());
  867. BOOST_CHECK_EQUAL(x3, x10);
  868. BOOST_CHECK(x1.valid());
  869. BOOST_CHECK(x3.valid());
  870. BOOST_CHECK(x5.valid());
  871. BOOST_CHECK(x6.valid());
  872. BOOST_CHECK(x7.valid());
  873. BOOST_CHECK(x8.valid());
  874. BOOST_CHECK(x9.valid());
  875. BOOST_CHECK(x10.valid());
  876. }
  877. BOOST_AUTO_TEST_CASE(testCommodityNegation)
  878. {
  879. amount_t x1("$123.45");
  880. amount_t x2("-$123.45");
  881. amount_t x3("$-123.45");
  882. amount_t x4("DM 123.45");
  883. amount_t x5("-DM 123.45");
  884. amount_t x6("DM -123.45");
  885. amount_t x7("123.45 euro");
  886. amount_t x8("-123.45 euro");
  887. amount_t x9("123.45€");
  888. amount_t x10("-123.45€");
  889. BOOST_CHECK_EQUAL(amount_t("$-123.45"), - x1);
  890. BOOST_CHECK_EQUAL(amount_t("$123.45"), - x2);
  891. BOOST_CHECK_EQUAL(amount_t("$123.45"), - x3);
  892. BOOST_CHECK_EQUAL(amount_t("DM -123.45"), - x4);
  893. BOOST_CHECK_EQUAL(amount_t("DM 123.45"), - x5);
  894. BOOST_CHECK_EQUAL(amount_t("DM 123.45"), - x6);
  895. BOOST_CHECK_EQUAL(amount_t("-123.45 euro"), - x7);
  896. BOOST_CHECK_EQUAL(amount_t("123.45 euro"), - x8);
  897. BOOST_CHECK_EQUAL(amount_t("-123.45€"), - x9);
  898. BOOST_CHECK_EQUAL(amount_t("123.45€"), - x10);
  899. BOOST_CHECK_EQUAL(amount_t("$-123.45"), x1.negated());
  900. BOOST_CHECK_EQUAL(amount_t("$123.45"), x2.negated());
  901. BOOST_CHECK_EQUAL(amount_t("$123.45"), x3.negated());
  902. BOOST_CHECK_EQUAL(string("$-123.45"), (- x1).to_string());
  903. BOOST_CHECK_EQUAL(string("$123.45"), (- x2).to_string());
  904. BOOST_CHECK_EQUAL(string("$123.45"), (- x3).to_string());
  905. BOOST_CHECK_EQUAL(string("DM -123.45"), (- x4).to_string());
  906. BOOST_CHECK_EQUAL(string("DM 123.45"), (- x5).to_string());
  907. BOOST_CHECK_EQUAL(string("DM 123.45"), (- x6).to_string());
  908. BOOST_CHECK_EQUAL(string("-123.45 euro"), (- x7).to_string());
  909. BOOST_CHECK_EQUAL(string("123.45 euro"), (- x8).to_string());
  910. BOOST_CHECK_EQUAL(string("-123.45€"), (- x9).to_string());
  911. BOOST_CHECK_EQUAL(string("123.45€"), (- x10).to_string());
  912. BOOST_CHECK_EQUAL(amount_t("$-123.45"), x1.negated());
  913. BOOST_CHECK_EQUAL(amount_t("$123.45"), x2.negated());
  914. BOOST_CHECK_EQUAL(amount_t("$123.45"), x3.negated());
  915. BOOST_CHECK(x1.valid());
  916. BOOST_CHECK(x2.valid());
  917. BOOST_CHECK(x3.valid());
  918. BOOST_CHECK(x4.valid());
  919. BOOST_CHECK(x5.valid());
  920. BOOST_CHECK(x6.valid());
  921. BOOST_CHECK(x7.valid());
  922. BOOST_CHECK(x8.valid());
  923. BOOST_CHECK(x9.valid());
  924. BOOST_CHECK(x10.valid());
  925. }
  926. BOOST_AUTO_TEST_CASE(testAbs)
  927. {
  928. amount_t x0;
  929. amount_t x1(-1234L);
  930. amount_t x2(1234L);
  931. BOOST_CHECK_THROW(x0.abs(), amount_error);
  932. BOOST_CHECK_EQUAL(amount_t(1234L), x1.abs());
  933. BOOST_CHECK_EQUAL(amount_t(1234L), x2.abs());
  934. BOOST_CHECK(x0.valid());
  935. BOOST_CHECK(x1.valid());
  936. BOOST_CHECK(x2.valid());
  937. }
  938. BOOST_AUTO_TEST_CASE(testCommodityAbs)
  939. {
  940. amount_t x1("$-1234.56");
  941. amount_t x2("$1234.56");
  942. BOOST_CHECK_EQUAL(amount_t("$1234.56"), x1.abs());
  943. BOOST_CHECK_EQUAL(amount_t("$1234.56"), x2.abs());
  944. BOOST_CHECK(x1.valid());
  945. BOOST_CHECK(x2.valid());
  946. }
  947. BOOST_AUTO_TEST_CASE(testFloor)
  948. {
  949. amount_t x0;
  950. amount_t x1("123.123");
  951. amount_t x2("-123.123");
  952. BOOST_CHECK_THROW(x0.floored(), amount_error);
  953. BOOST_CHECK_EQUAL(amount_t(123L), x1.floored());
  954. BOOST_CHECK_EQUAL(amount_t(-124L), x2.floored());
  955. BOOST_CHECK(x0.valid());
  956. BOOST_CHECK(x1.valid());
  957. BOOST_CHECK(x2.valid());
  958. }
  959. BOOST_AUTO_TEST_CASE(testCommodityFloor)
  960. {
  961. amount_t x1("$1234.56");
  962. amount_t x2("$-1234.56");
  963. BOOST_CHECK_EQUAL(amount_t("$1234"), x1.floored());
  964. BOOST_CHECK_EQUAL(amount_t("$-1235"), x2.floored());
  965. BOOST_CHECK(x1.valid());
  966. BOOST_CHECK(x2.valid());
  967. }
  968. BOOST_AUTO_TEST_CASE(testCeiling)
  969. {
  970. amount_t x0;
  971. amount_t x1("123.123");
  972. amount_t x2("-123.123");
  973. BOOST_CHECK_THROW(x0.ceilinged(), amount_error);
  974. BOOST_CHECK_EQUAL(amount_t(124L), x1.ceilinged());
  975. BOOST_CHECK_EQUAL(amount_t(-123L), x2.ceilinged());
  976. BOOST_CHECK(x0.valid());
  977. BOOST_CHECK(x1.valid());
  978. BOOST_CHECK(x2.valid());
  979. }
  980. BOOST_AUTO_TEST_CASE(testCommodityCeiling)
  981. {
  982. amount_t x1("$1234.56");
  983. amount_t x2("$-1234.56");
  984. BOOST_CHECK_EQUAL(amount_t("$1235"), x1.ceilinged());
  985. BOOST_CHECK_EQUAL(amount_t("$-1234"), x2.ceilinged());
  986. BOOST_CHECK(x1.valid());
  987. BOOST_CHECK(x2.valid());
  988. }
  989. #ifndef NOT_FOR_PYTHON
  990. #if 0
  991. BOOST_AUTO_TEST_CASE(testReduction)
  992. {
  993. amount_t x0;
  994. amount_t x1("60s");
  995. amount_t x2("600s");
  996. amount_t x3("6000s");
  997. amount_t x4("360000s");
  998. amount_t x5("10m"); // 600s
  999. amount_t x6("100m"); // 6000s
  1000. amount_t x7("1000m"); // 60000s
  1001. amount_t x8("10000m"); // 600000s
  1002. amount_t x9("10h"); // 36000s
  1003. amount_t x10("100h"); // 360000s
  1004. amount_t x11("1000h"); // 3600000s
  1005. amount_t x12("10000h"); // 36000000s
  1006. BOOST_CHECK_THROW(x0.reduce(), amount_error);
  1007. BOOST_CHECK_THROW(x0.unreduce(), amount_error);
  1008. BOOST_CHECK_EQUAL(x2, x5.reduce());
  1009. BOOST_CHECK_EQUAL(x3, x6.reduce());
  1010. BOOST_CHECK_EQUAL(x10, x4.reduce());
  1011. BOOST_CHECK_EQUAL(string("100.0h"), x4.unreduce().to_string());
  1012. }
  1013. #endif
  1014. #endif // NOT_FOR_PYTHON
  1015. BOOST_AUTO_TEST_CASE(testSign)
  1016. {
  1017. amount_t x0;
  1018. amount_t x1("0.0000000000000000000000000000000000001");
  1019. amount_t x2("-0.0000000000000000000000000000000000001");
  1020. amount_t x3("1");
  1021. amount_t x4("-1");
  1022. BOOST_CHECK_THROW(x0.sign(), amount_error);
  1023. BOOST_CHECK(x1.sign() > 0);
  1024. BOOST_CHECK(x2.sign() < 0);
  1025. BOOST_CHECK(x3.sign() > 0);
  1026. BOOST_CHECK(x4.sign() < 0);
  1027. BOOST_CHECK(x0.valid());
  1028. BOOST_CHECK(x1.valid());
  1029. BOOST_CHECK(x2.valid());
  1030. BOOST_CHECK(x3.valid());
  1031. BOOST_CHECK(x4.valid());
  1032. }
  1033. BOOST_AUTO_TEST_CASE(testCommoditySign)
  1034. {
  1035. amount_t x1(internalAmount("$0.0000000000000000000000000000000000001"));
  1036. amount_t x2(internalAmount("$-0.0000000000000000000000000000000000001"));
  1037. amount_t x3("$1");
  1038. amount_t x4("$-1");
  1039. BOOST_CHECK(x1.sign() != 0);
  1040. BOOST_CHECK(x2.sign() != 0);
  1041. BOOST_CHECK(x3.sign() > 0);
  1042. BOOST_CHECK(x4.sign() < 0);
  1043. BOOST_CHECK(x1.valid());
  1044. BOOST_CHECK(x2.valid());
  1045. BOOST_CHECK(x3.valid());
  1046. BOOST_CHECK(x4.valid());
  1047. }
  1048. BOOST_AUTO_TEST_CASE(testTruth)
  1049. {
  1050. amount_t x0;
  1051. amount_t x1("1234");
  1052. amount_t x2("1234.56");
  1053. #ifndef NOT_FOR_PYTHON
  1054. BOOST_CHECK_THROW(x0.operator bool(), amount_error);
  1055. #endif // NOT_FOR_PYTHON
  1056. BOOST_CHECK(x1);
  1057. BOOST_CHECK(x2);
  1058. BOOST_CHECK(x0.valid());
  1059. BOOST_CHECK(x1.valid());
  1060. BOOST_CHECK(x2.valid());
  1061. }
  1062. BOOST_AUTO_TEST_CASE(testCommodityTruth)
  1063. {
  1064. amount_t x1("$1234");
  1065. amount_t x2("$1234.56");
  1066. if (x1)
  1067. BOOST_CHECK(true);
  1068. if (x2)
  1069. BOOST_CHECK(true);
  1070. BOOST_CHECK(x1.valid());
  1071. BOOST_CHECK(x2.valid());
  1072. }
  1073. BOOST_AUTO_TEST_CASE(testForZero)
  1074. {
  1075. amount_t x0;
  1076. amount_t x1("0.000000000000000000001");
  1077. BOOST_CHECK(x1);
  1078. BOOST_CHECK_THROW(x0.is_zero(), amount_error);
  1079. BOOST_CHECK_THROW(x0.is_realzero(), amount_error);
  1080. BOOST_CHECK(! x1.is_zero());
  1081. BOOST_CHECK(! x1.is_realzero());
  1082. BOOST_CHECK(x0.valid());
  1083. BOOST_CHECK(x1.valid());
  1084. }
  1085. BOOST_AUTO_TEST_CASE(testCommodityForZero)
  1086. {
  1087. amount_t x1(internalAmount("$0.000000000000000000001"));
  1088. BOOST_CHECK(x1); // an internal amount never betrays its precision
  1089. BOOST_CHECK(! x1.is_zero());
  1090. BOOST_CHECK(! x1.is_realzero());
  1091. BOOST_CHECK(x1.valid());
  1092. }
  1093. BOOST_AUTO_TEST_CASE(testIntegerConversion)
  1094. {
  1095. amount_t x0;
  1096. amount_t x1(123456L);
  1097. amount_t x2("12345682348723487324");
  1098. BOOST_CHECK_THROW(x0.to_long(), amount_error);
  1099. BOOST_CHECK_THROW(x0.to_double(), amount_error);
  1100. BOOST_CHECK(! x2.fits_in_long());
  1101. BOOST_CHECK_EQUAL(123456L, x1.to_long());
  1102. BOOST_CHECK_EQUAL(123456.0, x1.to_double());
  1103. BOOST_CHECK_EQUAL(string("123456"), x1.to_string());
  1104. BOOST_CHECK_EQUAL(string("123456"), x1.quantity_string());
  1105. BOOST_CHECK(x1.valid());
  1106. }
  1107. BOOST_AUTO_TEST_CASE(testFractionalConversion)
  1108. {
  1109. amount_t x1("1234.56");
  1110. amount_t x2("1234.5683787634678348734");
  1111. BOOST_CHECK_EQUAL(1235L, x1.to_long());
  1112. BOOST_CHECK_EQUAL(1234.56, x1.to_double());
  1113. BOOST_CHECK_EQUAL(string("1234.56"), x1.to_string());
  1114. BOOST_CHECK_EQUAL(string("1234.56"), x1.quantity_string());
  1115. BOOST_CHECK(x1.valid());
  1116. }
  1117. BOOST_AUTO_TEST_CASE(testCommodityConversion)
  1118. {
  1119. amount_t x1("$1234.56");
  1120. BOOST_CHECK_EQUAL(1235L, x1.to_long());
  1121. BOOST_CHECK_EQUAL(1234.56, x1.to_double());
  1122. BOOST_CHECK_EQUAL(string("$1234.56"), x1.to_string());
  1123. BOOST_CHECK_EQUAL(string("1234.56"), x1.quantity_string());
  1124. BOOST_CHECK(x1.valid());
  1125. }
  1126. #ifndef NOT_FOR_PYTHON
  1127. BOOST_AUTO_TEST_CASE(testPrinting)
  1128. {
  1129. amount_t x0;
  1130. amount_t x1("982340823.380238098235098235098235098");
  1131. {
  1132. std::ostringstream bufstr;
  1133. x0.print(bufstr);
  1134. BOOST_CHECK_EQUAL(std::string("<null>"), bufstr.str());
  1135. }
  1136. {
  1137. std::ostringstream bufstr;
  1138. x1.print(bufstr);
  1139. BOOST_CHECK_EQUAL(std::string("982340823.380238098235098235098235098"),
  1140. bufstr.str());
  1141. }
  1142. BOOST_CHECK(x0.valid());
  1143. BOOST_CHECK(x1.valid());
  1144. }
  1145. BOOST_AUTO_TEST_CASE(testCommodityPrinting)
  1146. {
  1147. amount_t x1(internalAmount("$982340823.386238098235098235098235098"));
  1148. amount_t x2("$982340823.38");
  1149. {
  1150. std::ostringstream bufstr;
  1151. x1.print(bufstr);
  1152. BOOST_CHECK_EQUAL(std::string("$982340823.386238098235098235098235098"),
  1153. bufstr.str());
  1154. }
  1155. {
  1156. std::ostringstream bufstr;
  1157. (x1 * x2).print(bufstr);
  1158. BOOST_CHECK_EQUAL(std::string("$964993493285024293.18099172508158508135413499124"),
  1159. bufstr.str());
  1160. }
  1161. {
  1162. std::ostringstream bufstr;
  1163. (x2 * x1).print(bufstr);
  1164. BOOST_CHECK_EQUAL(std::string("$964993493285024293.18"), bufstr.str());
  1165. }
  1166. BOOST_CHECK(x1.valid());
  1167. BOOST_CHECK(x2.valid());
  1168. }
  1169. #endif // NOT_FOR_PYTHON
  1170. BOOST_AUTO_TEST_SUITE_END()