long-decimal 0.01.02 → 0.01.03

Sign up to get free protection for your applications and to get access to all the features.
Files changed (262) hide show
  1. data/README +58 -33
  2. data/Rakefile +1 -1
  3. data/VERSION +1 -1
  4. data/lib/long-decimal-extra.rb +378 -0
  5. data/lib/long-decimal.rb +277 -342
  6. data/test/testlongdecimal-extra.rb +645 -0
  7. data/test/testlongdecimal.rb +4 -605
  8. data/test/testlongdeclib.rb +4 -4
  9. data/test/testrandlib.rb +1 -1
  10. data/test/testrandom-extra.rb +76 -0
  11. data/test/testrandom.rb +4 -7
  12. data/test/testrandpower.rb +7 -4
  13. data/version.rb +1 -1
  14. metadata +5 -268
  15. data/doc/classes/Integer.html +0 -239
  16. data/doc/classes/Integer.src/M000036.html +0 -18
  17. data/doc/classes/Integer.src/M000039.html +0 -145
  18. data/doc/classes/LongDecimal.html +0 -1602
  19. data/doc/classes/LongDecimal.src/M000034.html +0 -18
  20. data/doc/classes/LongDecimal.src/M000035.html +0 -18
  21. data/doc/classes/LongDecimal.src/M000036.html +0 -18
  22. data/doc/classes/LongDecimal.src/M000037.html +0 -18
  23. data/doc/classes/LongDecimal.src/M000038.html +0 -18
  24. data/doc/classes/LongDecimal.src/M000039.html +0 -18
  25. data/doc/classes/LongDecimal.src/M000040.html +0 -18
  26. data/doc/classes/LongDecimal.src/M000041.html +0 -18
  27. data/doc/classes/LongDecimal.src/M000042.html +0 -18
  28. data/doc/classes/LongDecimal.src/M000043.html +0 -18
  29. data/doc/classes/LongDecimal.src/M000044.html +0 -18
  30. data/doc/classes/LongDecimal.src/M000045.html +0 -18
  31. data/doc/classes/LongDecimal.src/M000046.html +0 -20
  32. data/doc/classes/LongDecimal.src/M000047.html +0 -120
  33. data/doc/classes/LongDecimal.src/M000048.html +0 -35
  34. data/doc/classes/LongDecimal.src/M000049.html +0 -25
  35. data/doc/classes/LongDecimal.src/M000050.html +0 -41
  36. data/doc/classes/LongDecimal.src/M000051.html +0 -48
  37. data/doc/classes/LongDecimal.src/M000052.html +0 -33
  38. data/doc/classes/LongDecimal.src/M000053.html +0 -18
  39. data/doc/classes/LongDecimal.src/M000054.html +0 -29
  40. data/doc/classes/LongDecimal.src/M000055.html +0 -61
  41. data/doc/classes/LongDecimal.src/M000056.html +0 -18
  42. data/doc/classes/LongDecimal.src/M000057.html +0 -22
  43. data/doc/classes/LongDecimal.src/M000058.html +0 -20
  44. data/doc/classes/LongDecimal.src/M000059.html +0 -18
  45. data/doc/classes/LongDecimal.src/M000060.html +0 -29
  46. data/doc/classes/LongDecimal.src/M000061.html +0 -21
  47. data/doc/classes/LongDecimal.src/M000062.html +0 -18
  48. data/doc/classes/LongDecimal.src/M000063.html +0 -29
  49. data/doc/classes/LongDecimal.src/M000064.html +0 -27
  50. data/doc/classes/LongDecimal.src/M000065.html +0 -18
  51. data/doc/classes/LongDecimal.src/M000066.html +0 -18
  52. data/doc/classes/LongDecimal.src/M000067.html +0 -18
  53. data/doc/classes/LongDecimal.src/M000068.html +0 -19
  54. data/doc/classes/LongDecimal.src/M000069.html +0 -19
  55. data/doc/classes/LongDecimal.src/M000070.html +0 -18
  56. data/doc/classes/LongDecimal.src/M000071.html +0 -18
  57. data/doc/classes/LongDecimal.src/M000072.html +0 -22
  58. data/doc/classes/LongDecimal.src/M000073.html +0 -23
  59. data/doc/classes/LongDecimal.src/M000074.html +0 -23
  60. data/doc/classes/LongDecimal.src/M000075.html +0 -23
  61. data/doc/classes/LongDecimal.src/M000076.html +0 -18
  62. data/doc/classes/LongDecimal.src/M000077.html +0 -33
  63. data/doc/classes/LongDecimal.src/M000078.html +0 -23
  64. data/doc/classes/LongDecimal.src/M000079.html +0 -23
  65. data/doc/classes/LongDecimal.src/M000080.html +0 -35
  66. data/doc/classes/LongDecimal.src/M000081.html +0 -22
  67. data/doc/classes/LongDecimal.src/M000082.html +0 -19
  68. data/doc/classes/LongDecimal.src/M000083.html +0 -23
  69. data/doc/classes/LongDecimal.src/M000084.html +0 -23
  70. data/doc/classes/LongDecimal.src/M000085.html +0 -23
  71. data/doc/classes/LongDecimal.src/M000086.html +0 -18
  72. data/doc/classes/LongDecimal.src/M000087.html +0 -21
  73. data/doc/classes/LongDecimal.src/M000088.html +0 -21
  74. data/doc/classes/LongDecimal.src/M000089.html +0 -18
  75. data/doc/classes/LongDecimal.src/M000090.html +0 -18
  76. data/doc/classes/LongDecimal.src/M000091.html +0 -23
  77. data/doc/classes/LongDecimal.src/M000092.html +0 -23
  78. data/doc/classes/LongDecimal.src/M000093.html +0 -19
  79. data/doc/classes/LongDecimal.src/M000094.html +0 -23
  80. data/doc/classes/LongDecimal.src/M000095.html +0 -18
  81. data/doc/classes/LongDecimal.src/M000096.html +0 -18
  82. data/doc/classes/LongDecimal.src/M000097.html +0 -18
  83. data/doc/classes/LongDecimal.src/M000098.html +0 -18
  84. data/doc/classes/LongDecimal.src/M000099.html +0 -73
  85. data/doc/classes/LongDecimal.src/M000100.html +0 -18
  86. data/doc/classes/LongDecimal.src/M000101.html +0 -18
  87. data/doc/classes/LongDecimal.src/M000102.html +0 -18
  88. data/doc/classes/LongDecimal.src/M000103.html +0 -18
  89. data/doc/classes/LongDecimal.src/M000104.html +0 -19
  90. data/doc/classes/LongDecimal.src/M000105.html +0 -19
  91. data/doc/classes/LongDecimal.src/M000106.html +0 -18
  92. data/doc/classes/LongDecimal.src/M000107.html +0 -18
  93. data/doc/classes/LongDecimal.src/M000108.html +0 -18
  94. data/doc/classes/LongDecimal.src/M000109.html +0 -18
  95. data/doc/classes/LongDecimalBase.html +0 -359
  96. data/doc/classes/LongDecimalBase.src/M000101.html +0 -18
  97. data/doc/classes/LongDecimalBase.src/M000102.html +0 -18
  98. data/doc/classes/LongDecimalBase.src/M000103.html +0 -18
  99. data/doc/classes/LongDecimalBase.src/M000104.html +0 -18
  100. data/doc/classes/LongDecimalBase.src/M000105.html +0 -18
  101. data/doc/classes/LongDecimalBase.src/M000106.html +0 -18
  102. data/doc/classes/LongDecimalBase.src/M000107.html +0 -18
  103. data/doc/classes/LongDecimalBase.src/M000108.html +0 -18
  104. data/doc/classes/LongDecimalBase.src/M000109.html +0 -18
  105. data/doc/classes/LongDecimalBase.src/M000110.html +0 -18
  106. data/doc/classes/LongDecimalBase.src/M000111.html +0 -18
  107. data/doc/classes/LongDecimalBase.src/M000112.html +0 -18
  108. data/doc/classes/LongDecimalBase.src/M000113.html +0 -18
  109. data/doc/classes/LongDecimalBase.src/M000114.html +0 -18
  110. data/doc/classes/LongDecimalBase.src/M000115.html +0 -18
  111. data/doc/classes/LongDecimalBase.src/M000116.html +0 -18
  112. data/doc/classes/LongDecimalBase.src/M000117.html +0 -18
  113. data/doc/classes/LongDecimalBase.src/M000118.html +0 -23
  114. data/doc/classes/LongDecimalBase.src/M000121.html +0 -23
  115. data/doc/classes/LongDecimalBase.src/M000122.html +0 -19
  116. data/doc/classes/LongDecimalBase.src/M000123.html +0 -18
  117. data/doc/classes/LongDecimalQuot.html +0 -836
  118. data/doc/classes/LongDecimalQuot.src/M000003.html +0 -18
  119. data/doc/classes/LongDecimalQuot.src/M000004.html +0 -46
  120. data/doc/classes/LongDecimalQuot.src/M000005.html +0 -18
  121. data/doc/classes/LongDecimalQuot.src/M000006.html +0 -18
  122. data/doc/classes/LongDecimalQuot.src/M000007.html +0 -20
  123. data/doc/classes/LongDecimalQuot.src/M000008.html +0 -19
  124. data/doc/classes/LongDecimalQuot.src/M000009.html +0 -18
  125. data/doc/classes/LongDecimalQuot.src/M000010.html +0 -18
  126. data/doc/classes/LongDecimalQuot.src/M000011.html +0 -18
  127. data/doc/classes/LongDecimalQuot.src/M000012.html +0 -18
  128. data/doc/classes/LongDecimalQuot.src/M000013.html +0 -32
  129. data/doc/classes/LongDecimalQuot.src/M000014.html +0 -19
  130. data/doc/classes/LongDecimalQuot.src/M000015.html +0 -19
  131. data/doc/classes/LongDecimalQuot.src/M000016.html +0 -22
  132. data/doc/classes/LongDecimalQuot.src/M000017.html +0 -23
  133. data/doc/classes/LongDecimalQuot.src/M000018.html +0 -23
  134. data/doc/classes/LongDecimalQuot.src/M000019.html +0 -23
  135. data/doc/classes/LongDecimalQuot.src/M000020.html +0 -23
  136. data/doc/classes/LongDecimalQuot.src/M000021.html +0 -35
  137. data/doc/classes/LongDecimalQuot.src/M000022.html +0 -22
  138. data/doc/classes/LongDecimalQuot.src/M000023.html +0 -19
  139. data/doc/classes/LongDecimalQuot.src/M000024.html +0 -18
  140. data/doc/classes/LongDecimalQuot.src/M000025.html +0 -127
  141. data/doc/classes/LongDecimalQuot.src/M000026.html +0 -52
  142. data/doc/classes/LongDecimalQuot.src/M000027.html +0 -18
  143. data/doc/classes/LongDecimalQuot.src/M000028.html +0 -18
  144. data/doc/classes/LongDecimalQuot.src/M000029.html +0 -18
  145. data/doc/classes/LongDecimalQuot.src/M000030.html +0 -18
  146. data/doc/classes/LongDecimalQuot.src/M000031.html +0 -18
  147. data/doc/classes/LongDecimalQuot.src/M000032.html +0 -18
  148. data/doc/classes/LongDecimalQuot.src/M000033.html +0 -18
  149. data/doc/classes/LongDecimalQuot.src/M000034.html +0 -18
  150. data/doc/classes/LongDecimalQuot.src/M000035.html +0 -18
  151. data/doc/classes/LongDecimalRoundingMode.html +0 -242
  152. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.html +0 -214
  153. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000135.html +0 -22
  154. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000137.html +0 -22
  155. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000138.html +0 -22
  156. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000141.html +0 -22
  157. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000142.html +0 -18
  158. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000146.html +0 -22
  159. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000147.html +0 -18
  160. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000148.html +0 -22
  161. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000149.html +0 -18
  162. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000150.html +0 -22
  163. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000151.html +0 -18
  164. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000152.html +0 -18
  165. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000156.html +0 -22
  166. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000157.html +0 -18
  167. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000158.html +0 -18
  168. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000159.html +0 -18
  169. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000161.html +0 -25
  170. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000162.html +0 -18
  171. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000163.html +0 -18
  172. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000164.html +0 -18
  173. data/doc/classes/LongDecimalRoundingMode/ZeroRoundingModeClass.html +0 -178
  174. data/doc/classes/LongDecimalRoundingMode/ZeroRoundingModeClass.src/M000165.html +0 -25
  175. data/doc/classes/LongDecimalRoundingMode/ZeroRoundingModeClass.src/M000166.html +0 -18
  176. data/doc/classes/LongMath.html +0 -911
  177. data/doc/classes/LongMath.src/M000112.html +0 -19
  178. data/doc/classes/LongMath.src/M000113.html +0 -19
  179. data/doc/classes/LongMath.src/M000114.html +0 -18
  180. data/doc/classes/LongMath.src/M000115.html +0 -19
  181. data/doc/classes/LongMath.src/M000116.html +0 -19
  182. data/doc/classes/LongMath.src/M000117.html +0 -18
  183. data/doc/classes/LongMath.src/M000118.html +0 -19
  184. data/doc/classes/LongMath.src/M000119.html +0 -19
  185. data/doc/classes/LongMath.src/M000120.html +0 -18
  186. data/doc/classes/LongMath.src/M000121.html +0 -18
  187. data/doc/classes/LongMath.src/M000122.html +0 -19
  188. data/doc/classes/LongMath.src/M000123.html +0 -18
  189. data/doc/classes/LongMath.src/M000124.html +0 -19
  190. data/doc/classes/LongMath.src/M000125.html +0 -18
  191. data/doc/classes/LongMath.src/M000126.html +0 -18
  192. data/doc/classes/LongMath.src/M000127.html +0 -19
  193. data/doc/classes/LongMath.src/M000128.html +0 -18
  194. data/doc/classes/LongMath.src/M000129.html +0 -32
  195. data/doc/classes/LongMath.src/M000130.html +0 -32
  196. data/doc/classes/LongMath.src/M000131.html +0 -19
  197. data/doc/classes/LongMath.src/M000132.html +0 -43
  198. data/doc/classes/LongMath.src/M000133.html +0 -19
  199. data/doc/classes/LongMath.src/M000134.html +0 -71
  200. data/doc/classes/LongMath.src/M000135.html +0 -35
  201. data/doc/classes/LongMath.src/M000136.html +0 -50
  202. data/doc/classes/LongMath.src/M000137.html +0 -20
  203. data/doc/classes/LongMath.src/M000138.html +0 -47
  204. data/doc/classes/LongMath.src/M000139.html +0 -65
  205. data/doc/classes/LongMath.src/M000140.html +0 -21
  206. data/doc/classes/LongMath.src/M000141.html +0 -18
  207. data/doc/classes/LongMath.src/M000142.html +0 -18
  208. data/doc/classes/LongMath.src/M000143.html +0 -87
  209. data/doc/classes/LongMath.src/M000144.html +0 -58
  210. data/doc/classes/LongMath.src/M000145.html +0 -18
  211. data/doc/classes/LongMath.src/M000146.html +0 -18
  212. data/doc/classes/LongMath.src/M000147.html +0 -20
  213. data/doc/classes/LongMath.src/M000148.html +0 -34
  214. data/doc/classes/LongMath.src/M000149.html +0 -33
  215. data/doc/classes/LongMath.src/M000150.html +0 -58
  216. data/doc/classes/LongMath.src/M000151.html +0 -406
  217. data/doc/classes/LongMath.src/M000152.html +0 -63
  218. data/doc/classes/LongMath.src/M000153.html +0 -117
  219. data/doc/classes/LongMath.src/M000154.html +0 -150
  220. data/doc/classes/LongMath.src/M000155.html +0 -63
  221. data/doc/classes/LongMath.src/M000156.html +0 -18
  222. data/doc/classes/LongMath.src/M000157.html +0 -19
  223. data/doc/classes/LongMath.src/M000158.html +0 -18
  224. data/doc/classes/LongMath.src/M000159.html +0 -19
  225. data/doc/classes/LongMath/CacheKey.html +0 -164
  226. data/doc/classes/LongMath/CacheKey.src/M000140.html +0 -36
  227. data/doc/classes/LongMath/CacheKey.src/M000145.html +0 -36
  228. data/doc/classes/LongMath/CacheKey.src/M000147.html +0 -36
  229. data/doc/classes/LongMath/CacheKey.src/M000149.html +0 -36
  230. data/doc/classes/LongMath/CacheKey.src/M000155.html +0 -36
  231. data/doc/classes/LongMath/CacheKey.src/M000160.html +0 -36
  232. data/doc/classes/Numeric.html +0 -177
  233. data/doc/classes/Numeric.src/M000100.html +0 -23
  234. data/doc/classes/Numeric.src/M000102.html +0 -23
  235. data/doc/classes/Numeric.src/M000103.html +0 -18
  236. data/doc/classes/Numeric.src/M000104.html +0 -23
  237. data/doc/classes/Numeric.src/M000105.html +0 -23
  238. data/doc/classes/Numeric.src/M000106.html +0 -18
  239. data/doc/classes/Numeric.src/M000110.html +0 -23
  240. data/doc/classes/Numeric.src/M000111.html +0 -18
  241. data/doc/classes/Rational.html +0 -161
  242. data/doc/classes/Rational.src/M000101.html +0 -23
  243. data/doc/classes/Rational.src/M000103.html +0 -23
  244. data/doc/classes/Rational.src/M000104.html +0 -23
  245. data/doc/classes/Rational.src/M000106.html +0 -23
  246. data/doc/classes/Rational.src/M000107.html +0 -23
  247. data/doc/classes/Rational.src/M000112.html +0 -23
  248. data/doc/created.rid +0 -1
  249. data/doc/dot/f_0.dot +0 -166
  250. data/doc/dot/f_0.png +0 -0
  251. data/doc/dot/m_0_0.dot +0 -59
  252. data/doc/dot/m_0_0.png +0 -0
  253. data/doc/dot/m_0_1.dot +0 -62
  254. data/doc/dot/m_0_1.png +0 -0
  255. data/doc/files/lib/long-decimal_rb.html +0 -191
  256. data/doc/files/lib/long-decimal_rb.src/M000001.html +0 -22
  257. data/doc/files/lib/long-decimal_rb.src/M000002.html +0 -18
  258. data/doc/fr_class_index.html +0 -37
  259. data/doc/fr_file_index.html +0 -27
  260. data/doc/fr_method_index.html +0 -192
  261. data/doc/index.html +0 -24
  262. data/doc/rdoc-style.css +0 -208
data/README CHANGED
@@ -1,13 +1,32 @@
1
1
  Version
2
2
  -------
3
3
 
4
- This version ($Name: ALPHA_01_01 $) is functionally identical with the previous
5
- alpha-0.01.00. The runit tests have been extended and further tests
6
- have been added. A lot of additional testing has been done using
7
- random numbers as parameters with testrandom.rb and values for which
8
- these random tests have failed have been added to the regular tests in
9
- testlongdecimal.rb . So this release is mostly bug-fixing, enough to
10
- justify declaring itself as alpha-version.
4
+ This version ($Name: ALPHA_01_03 $) is functionally mostly identical with the
5
+ previous alpha-0.01.02. Support for rounding to any given set of last
6
+ digits, for example allowing only 0 and 5 as last digit, has been
7
+ added and tests for this kind of functionality are considered to be
8
+ complete. This functionality is useful for rounding patterns within
9
+ currencies where the smallest unit is 0.05, not 0.01, like CHF. In
10
+ this case, remainders 0 and 5 modulo 10 are required. For currencies
11
+ where the smallest unit is 0.02, it would be 0, 2, 4, 8 modulo 10.
12
+ But this has been implemented in a more general way, so it would also
13
+ be possible to restrict the rounding results to any set modulo any
14
+ integral number >= 2.
15
+
16
+ Extensive testing has shown that apart from this new functionality
17
+ there seems to be an issue when calculating powers of LongDecimal
18
+ where the base is slightly less than 1 and the exponent is a big
19
+ positive number. In some cases where this should result in 0, the
20
+ calculations seem to take time forever. This issue should not stop
21
+ long-decimal from becoming beta, so its solution will be postponed and
22
+ it will be resolved temporarily by moving it to a different library.
23
+ Ideas how to solve these issues are there, so eventually this
24
+ power-functionality will be working even for these cases.
25
+
26
+ All other functionality did not show any bugs during intensive
27
+ testing, so it could be assumed that the whole library is good for
28
+ beta and maybe even production/stable, apart from the issues
29
+ mentioned above, which are being separated into another library.
11
30
 
12
31
  This software development effort is hosted on RubyForge (
13
32
  http://rubyforge.org/ ) under the project name "long-decimal", to be
@@ -15,25 +34,26 @@ found directly with http://rubyforge.org/projects/long-decimal/ . So
15
34
  you should feel encouraged to look if there is a newer version, when
16
35
  you install long-decimal.
17
36
 
18
- This version is an alpha-version. Operations +, -, *, / and sqrt
19
- should be working properly and would justify calling this release at
20
- least beta. Even log, exp and power should be fine. log, log2, log10
21
- and exp have been tested for about a million random values and the
22
- current version should cover all of these correctly. But it is still
23
- possible,that in some cases the result deviates in the last digit by 1
24
- or 2 from the real result. A deviation of slightly more than half of
25
- the unit of the last digit is already present. Improving on this
26
- would require an extensive extension of internal functionality to
27
- provide rounding information in case of last digits being 50000...,
28
- where additional digits would reveal if this really needs to be
29
- rounded up or down. Because these functions are transcendental, at
30
- least exp and log will always have either one of these true, it will
31
- never be exactly ....5. Speed could be improved as well.
37
+ This version is an alpha-version, which might also be called
38
+ "pre-beta". Operations +, -, *, / and sqrt should be working properly
39
+ and would justify calling this release at least beta. Even log and exp
40
+ should be fine. log, log2, log10 and exp have been tested
41
+ for more than a million random values and the current version should
42
+ cover all of these correctly. But it is still possible, that in some
43
+ cases the result deviates in the last digit by 1 or 2 from the real
44
+ result. A deviation of slightly more than half of the unit of the
45
+ last digit is already present. Improving on this would require an
46
+ extensive extension of internal functionality to provide rounding
47
+ information in case of last digits being 50000..., where additional
48
+ digits would reveal if this really needs to be rounded up or down.
49
+ Because these functions are transcendental, at least exp and log will
50
+ always have either one of these true, it will never be exactly ....5.
51
+ Speed could be improved as well.
32
52
 
33
53
  It would be a good idea to do some more mathematical analysis on how
34
54
  many digits are needed internally to guarantee the correctness of the
35
55
  digits that are provided. But this will not be considered as a
36
- requirement for the alpha-version.
56
+ requirement for the beta-version.
37
57
 
38
58
  Test
39
59
  ----
@@ -43,12 +63,12 @@ correctness of this library and allow changes to be checked in order
43
63
  to make sure that what was running before would still work afterwards.
44
64
  Tests for a library as complex as long-decimal can never be
45
65
  exhaustive, but they give a good indication that methods are working
46
- correctly. About 95% of the tests that will be eventually needed are
47
- already present. As a policy a release is not created unless all
48
- tests succeed. Running the tests can take a few minutes, depending on
49
- your machine. It is about 15 minutes on my machine (1300 MHz).
50
- Whatever is gained by making the software run faster is used up again
51
- by adding more tests. This is the result of the test:
66
+ correctly. The set of tests that is available now is considered to be
67
+ complete. As a policy a release is not created unless all tests
68
+ succeed. Running all tests can take a few minutes or even hours,
69
+ depending on your machine. Whatever is gained by making the software
70
+ run faster is used up again by adding more tests. This is the result
71
+ of the test:
52
72
 
53
73
  Finished in 1160.808707 seconds.
54
74
 
@@ -90,7 +110,7 @@ ruby 1.8.4 and on Windows XP with Cygwin and ruby 1.8.4 and on Windows
90
110
  - Usage from your ruby-programs:
91
111
 
92
112
  require "rubygems"
93
- require_gem "long-decimal"
113
+ require "long-decimal"
94
114
 
95
115
  - documentation will be found in HTML-format in the directory
96
116
  $RUBY_DIR/gems/$RUBY_VERSION/doc/long-decimal-$LONG_DECIMAL_VERSION/rdoc/index.html
@@ -106,14 +126,14 @@ ruby 1.8.4 and on Windows XP with Cygwin and ruby 1.8.4 and on Windows
106
126
  2. Installing from the sources (it is preferred to use the
107
127
  gem-installation, but since long-decimal is open-source-software you
108
128
  are off course granted the right to download the source and change
109
- it and install your own version.
129
+ it and install your own version.)
110
130
 
111
131
  - download the newest source-tar.gz-file from long-decimal project at rubyforge
112
132
  which can be found by
113
133
  http://rubyforge.org/projects/long-decimal/ -> Files
114
134
  ( http://rubyforge.org/frs/?group_id=1334 )
115
135
  - open a shell window
116
- cd to the directory where you have downloaded the gem-file
136
+ cd to the directory where you have downloaded the .tar.gz-file
117
137
  unpack the file using tar
118
138
  tar xfzvv long-decimal-alpha-1_00.tar.gz
119
139
  cd long-decimal
@@ -134,8 +154,13 @@ in the gem-file. It is not provided as a separate file any more.
134
154
  Bugs
135
155
  ----
136
156
 
137
- There are no known bugs against the current specification and bugs
138
- that occur are usually fixed within a few days.
157
+ Calculations of the kind
158
+ 0.99999999999 ** 12423153125316415423512345234
159
+ that are performed using LongMath.power tend to take forever, if the
160
+ exponent is really big.
161
+
162
+ Method round_to_allowed_remainders() of LongDecimal has not been
163
+ tested enough.
139
164
 
140
165
  It is considered somewhat arbitrary to disallow calculation
141
166
  exponential functions if the result could not be expressed as Float.
data/Rakefile CHANGED
@@ -2,7 +2,7 @@
2
2
  # Rakefile for long-decimal project
3
3
  #
4
4
  # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/Rakefile,v 1.3 2006/04/01 08:52:06 bk1 Exp $
5
- # CVS-Label: $Name: ALPHA_01_01 $
5
+ # CVS-Label: $Name: ALPHA_01_03 $
6
6
  # Author: $Author: bk1 $ (Karl Brodowsky)
7
7
  #
8
8
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.01.02
1
+ 0.01.03
@@ -0,0 +1,378 @@
1
+ #
2
+ # long-decimal-extra.rb -- Arbitrary precision decimals with fixed decimal point
3
+ #
4
+ # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/lib/long-decimal-extra.rb,v 1.1 2007/08/19 19:23:33 bk1 Exp $
5
+ # CVS-Label: $Name: ALPHA_01_03 $
6
+ # Author: $Author: bk1 $ (Karl Brodowsky)
7
+ #
8
+ require "complex"
9
+ require "rational"
10
+ require "bigdecimal"
11
+
12
+ # require "long-decimal.rb"
13
+
14
+ # require "bigdecimal/math"
15
+
16
+ #
17
+ # LongMath provides some helper functions to support LongDecimal and
18
+ # LongDecimalQuot, mostly operating on integers. They are used
19
+ # internally here, but possibly they can be used elsewhere as well.
20
+ # In addition LongMath provides methods like those in Math, but for
21
+ # LongDecimal instead of Float.
22
+ #
23
+ module LongMath
24
+
25
+ #
26
+ # calc the base-2-exponential function of x to the given precision as
27
+ # LongDecimal. Only supports values of x such that the result still
28
+ # fits into a float (x <= 709). This limitation is somewhat
29
+ # arbitrary, but it is enforced in order to avoid producing numbers
30
+ # with the exponential function that exceed the memory.
31
+ #
32
+ def LongMath.exp2(x, prec, mode = LongMath.standard_mode) # down?
33
+ LongMath.power(2, x, prec, mode)
34
+ end
35
+
36
+ #
37
+ # calc the base-10-exponential function of x to the given precision as
38
+ # LongDecimal. Only supports values of x such that the result still
39
+ # fits into a float (x <= 709). This limitation is somewhat
40
+ # arbitrary, but it is enforced in order to avoid producing numbers
41
+ # with the exponential function that exceed the memory.
42
+ #
43
+ def LongMath.exp10(x, prec, mode = LongMath.standard_mode) # down?
44
+ LongMath.power(10, x, prec, mode)
45
+ end
46
+
47
+ #
48
+ # calculate the base 10 logarithm of x to the given precision as
49
+ # LongDecimal.
50
+ #
51
+ def LongMath.log10(x, prec, mode = LongMath.standard_mode) # down?
52
+
53
+ check_is_prec(prec, "prec")
54
+ check_is_mode(mode, "mode")
55
+ iprec = prec + 6
56
+ unless (x.kind_of? LongDecimal)
57
+ x = x.to_ld(iprec, mode)
58
+ end
59
+ if (x.one?) then
60
+ return LongDecimal.zero!(prec)
61
+ end
62
+
63
+ id = x.int_digits10
64
+ xx = x.move_point_left(id)
65
+ lnxx = log_internal(xx, iprec, mode)
66
+ ln10 = log_internal(10, iprec, mode)
67
+ y = id + (lnxx / ln10).round_to_scale(prec, mode)
68
+ return y
69
+ end
70
+
71
+ #
72
+ # calculate the base 2 logarithm of x to the given precision as
73
+ # LongDecimal.
74
+ #
75
+ def LongMath.log2(x, prec, mode = LongMath.standard_mode)
76
+
77
+ check_is_prec(prec, "prec")
78
+ check_is_mode(mode, "mode")
79
+ iprec = prec + 6
80
+ unless (x.kind_of? LongDecimal)
81
+ x = x.to_ld(iprec, mode)
82
+ end
83
+ if (x.one?) then
84
+ return LongDecimal.zero!(prec)
85
+ end
86
+ id = x.int_digits2
87
+ xx = (x / (1 << id)).round_to_scale(x.scale+id)
88
+ lnxx = log_internal(xx, iprec, mode)
89
+ ln2 = log_internal(2.to_ld, iprec, mode)
90
+ y = id + (lnxx / ln2).round_to_scale(prec, mode)
91
+ return y
92
+ end
93
+
94
+ private
95
+
96
+ #
97
+ # internal helper method for calculating the internal precision for power
98
+ #
99
+ def LongMath.calc_iprec_for_power(x, y, prec)
100
+
101
+ logx_f = nil
102
+ if (x.abs <= LongMath::MAX_FLOATABLE)
103
+ x_f = x.to_f
104
+ logx_f = Math.log(x_f.abs)
105
+ else
106
+ logx_f = LongMath.log(x, 15, LongMath::ROUND_UP)
107
+ end
108
+
109
+ y_f = nil
110
+ if (y.abs <= LongMath::MAX_FLOATABLE) then
111
+ y_f = y.to_f
112
+ else
113
+ y_f = y.round_to_scale(15, LongMath::ROUND_UP)
114
+ end
115
+
116
+ logx_y_f = logx_f * y_f
117
+ if (logx_y_f.abs > LongMath::MAX_FLOATABLE) then
118
+ raise ArgumentError, "power would be way too big: y*log(x)=#{logx_y_f}";
119
+ end
120
+ logx_y_f = logx_y_f.to_f unless logx_y_f.kind_of? Float
121
+
122
+ iprec_x = calc_iprec_for_exp(logx_y_f.abs.ceil, prec, logx_y_f < 0)
123
+ iprec_y = iprec_x
124
+ iprec = iprec_x + 2
125
+ if (logx_f < 0)
126
+ iprec_x -= (logx_f/LOG10).round
127
+ end
128
+ if (y_f.abs < 1)
129
+ logy_f = nil
130
+ if (y_f.kind_of? Float) then
131
+ logy_f = Math.log(y_f.abs)
132
+ else
133
+ logy_f = LongMath.log(y_f.abs, 15, LongMath::ROUND_UP)
134
+ if (logy_f.abs > LongMath::MAX_FLOATABLE) then
135
+ raise ArgumentError, "exponent would be way too big: y=#{y} logy_f=#{logy_f}";
136
+ end
137
+ logy_f = logy_f.to_f
138
+ end
139
+ # puts("x=#{x} y=#{y} x_f=#{x_f} y_f=#{y_f} logx_f=#{logx_f} logy_f=#{logy_f} logx_y_f=#{logx_y_f}\n")
140
+ iprec_y -= (logy_f/LOG10).round
141
+ end
142
+ # puts("x=#{x} y=#{y} x_f=#{x_f} y_f=#{y_f} logx_f=#{logx_f} logy_f=#{logy_f} logx_y_f=#{logx_y_f}\n")
143
+ # puts("\niprec: x=#{x} y=#{y} iprec=#{iprec} iprec_x=#{iprec_x} iprec_y=#{iprec_y}\n")
144
+ [ iprec, iprec_x, iprec_y, logx_y_f ]
145
+
146
+ end
147
+
148
+ public
149
+
150
+ #
151
+ # calc the power of x with exponent y to the given precision as
152
+ # LongDecimal. Only supports values of y such that exp(y) still
153
+ # fits into a float (y <= 709)
154
+ #
155
+ def LongMath.power(x, y, prec, mode = LongMath.standard_mode)
156
+
157
+ raise TypeError, "x=#{x} must be numeric" unless x.kind_of? Numeric
158
+ raise TypeError, "y=#{y} must be numeric" unless y.kind_of? Numeric
159
+ raise TypeError, "x=#{x.inspect} must not be greater #{MAX_FLOATABLE}" unless x.abs <= MAX_FLOATABLE
160
+ raise TypeError, "y=#{y.inspect} must not be greater #{MAX_FLOATABLE}" unless y.abs <= MAX_FLOATABLE
161
+ # raise TypeError, "y=#{y.inspect} must not be greater #{MAX_EXP_ABLE}" unless y <= MAX_EXP_ABLE
162
+ # raise TypeError, "x=#{x.inspect} must not negative" unless x >= 0 || (y.kind_of? Integer) || (y.kind_of? LongDecimalBase) && y.is_int?
163
+ raise TypeError, "x=#{x.inspect} must not negative" unless x >= 0
164
+ check_is_prec(prec, "prec")
165
+ check_is_mode(mode, "mode")
166
+
167
+ # handle the special cases where base or exponent are 0 or 1 explicitely
168
+ if y.zero? then
169
+ return LongDecimal.one!(prec)
170
+ elsif x.zero? then
171
+ return LongDecimal.zero!(prec)
172
+ elsif y.one? then
173
+ return x.to_ld(prec, mode)
174
+ elsif x.one? then
175
+ return LongDecimal.one!(prec)
176
+ end
177
+
178
+ # els
179
+ # could be result with our precision
180
+ # x ** y <= 10**-s/2 <=> y * log(x) <= -s log(10) - log(2)
181
+
182
+ iprec, iprec_x, iprec_y, logx_y_f = calc_iprec_for_power(x, y, prec)
183
+ if (x < 1 && y > 0 || x > 1 && y < 0) then
184
+ if (logx_y_f <= - prec * LOG10 - LOG2) then
185
+ return LongDecimal.zero!(prec)
186
+ end
187
+ end
188
+ # puts("x=#{x} y=#{y} iprec=#{iprec} iprec_x=#{iprec_x} iprec_y=#{iprec_y} prec=#{prec}")
189
+
190
+ unless (x.kind_of? LongDecimalBase) || (x.kind_of? Integer)
191
+ x = x.to_ld(iprec_x, mode)
192
+ end
193
+ unless (y.kind_of? LongDecimalBase) || (y.kind_of? Integer)
194
+ y = y.to_ld(iprec_y, mode)
195
+ end
196
+
197
+ # try shortcut if exponent is an integer
198
+ if (y.kind_of? LongDecimalBase) && y.is_int? then
199
+ y = y.to_i
200
+ end
201
+ unless (y.kind_of? Integer)
202
+ y2 = y*2
203
+ if (y2.kind_of? LongDecimalBase) && y2.is_int? then
204
+ y2 = y2.to_i
205
+ puts("y2=#{y2}")
206
+ end
207
+ if (y2.kind_of? Integer)
208
+ x = LongMath.sqrt(x, 2*iprec_x, mode)
209
+ y = y2
210
+ end
211
+ end
212
+ if (y.kind_of? Integer)
213
+ unless x.kind_of? LongDecimal
214
+ # x = x.to_ld(prec)
215
+ x = x.to_ld(iprec_x)
216
+ end
217
+ # z = x ** y
218
+ z = LongMath.ipower(x, y, 2*iprec, mode)
219
+ # puts("x=#{x} y=#{y} z=#{z} y int")
220
+ return z.to_ld(prec, mode)
221
+ end
222
+
223
+ # it can be assumed that the exponent is not an integer, so it should
224
+ # be converted into LongDecimal
225
+ unless (y.kind_of? LongDecimal)
226
+ # y = y.to_ld(prec, mode)
227
+ y = y.to_ld(iprec_y, mode)
228
+ end
229
+
230
+ # if x < 1 && y < 0 then
231
+ # working with x < 1 should be improved, less precision needed
232
+ if x < 1 then
233
+ # since we do not allow x < 0 and we have handled x = 0 already,
234
+ # we can be sure that x is no integer, so it has been converted
235
+ # if necessary to LongDecimalBase
236
+ y = -y
237
+ x = (1/x).round_to_scale(iprec_x*2, mode)
238
+ iprec, iprec_x, iprec_y = calc_iprec_for_power(x, y, prec)
239
+ end
240
+
241
+ # exponent is split in two parts, an integer part and a
242
+ # LongDecimal with absolute value <= 0.5
243
+ y0 = y.round_to_scale(0, LongMath.standard_imode).to_i
244
+ # z0 = x**y0
245
+ z0 = LongMath.ipower(x, y0, 2*iprec, mode)
246
+ y1 = y - y0
247
+ prec_extra = 0
248
+ if (y0 > 0)
249
+ prec_extra = (y0*Math.log10(x.to_f).abs).ceil
250
+ end
251
+ # z1 = LongMath.power_internal(x, y1, prec+prec_extra , mode)
252
+ z1 = LongMath.power_internal(x, y1, prec+prec_extra + 4, mode)
253
+ z = z0 * z1
254
+ # puts("x=#{x} y=#{y} z=#{z} y not int")
255
+ return z.to_ld(prec, mode)
256
+ end
257
+
258
+ #
259
+ # internal functionality to calculate the y-th power of x assuming
260
+ # that y is an integer
261
+ # prec is a hint on how much internal precision is needed at most
262
+ # final rounding is left to the caller
263
+ #
264
+ def LongMath.ipower(x, y, prec, mode)
265
+
266
+ raise TypeError, "x=#{x} must be numeric" unless x.kind_of? Numeric
267
+ raise TypeError, "y=#{y} must be integer" unless y.kind_of? Integer
268
+ raise TypeError, "x=#{x.inspect} must not be greater #{MAX_FLOATABLE}" unless x.abs <= MAX_FLOATABLE
269
+ raise TypeError, "y=#{y.inspect} must not be greater #{MAX_FLOATABLE}" unless y.abs <= MAX_FLOATABLE
270
+ check_is_prec(prec, "prec")
271
+ check_is_mode(mode, "mode")
272
+
273
+ cnt = 0
274
+
275
+ if (y.zero?)
276
+ return 1
277
+ elsif ! (x.kind_of? LongDecimalBase) || x.scale * y.abs <= prec
278
+ return x ** y
279
+ elsif (y < 0)
280
+ l = Math.log10(x.abs.to_f)
281
+ if (l > 0)
282
+ prec += (2*l).ceil
283
+ end
284
+ return 1/LongMath.ipower(x, -y, prec, mode)
285
+ else
286
+ # y > 0
287
+ # puts("ipower y>0 x=#{x} y=#{y} prec=#{prec}")
288
+ z = x
289
+ while true do
290
+
291
+ cnt++
292
+ y -= 1
293
+ if (y.zero?)
294
+ break
295
+ end
296
+ while (y & 0x01) == 0 do
297
+
298
+ cnt++
299
+ y = y >> 1
300
+ x = (x*x)
301
+ if (x.kind_of? LongDecimalBase)
302
+ x = x.round_to_scale(prec, mode)
303
+ end
304
+ if (cnt > 1000)
305
+ puts("ipower x=#{x} y=#{y} cnt=#{cnt} z=#{z}")
306
+ cnt = 0
307
+ end
308
+
309
+ end
310
+ z = (z*x)
311
+ if (z.kind_of? LongDecimalBase)
312
+ z = z.round_to_scale(prec, mode)
313
+ end
314
+
315
+ end
316
+ end
317
+ return z
318
+ end
319
+
320
+ #
321
+ # internal functionality of exp. exposes some more parameters, that
322
+ # should usually be set to defaut values, in order to allow better testing.
323
+ # do not actually call this method unless you are testing exp.
324
+ # create a bug report, if the default settings for the parameters do
325
+ # not work correctly
326
+ #
327
+ def LongMath.power_internal(x, y, prec = nil, final_mode = LongMath.standard_mode, iprec = nil, mode = LongMath.standard_imode)
328
+
329
+ if (prec.nil?) then
330
+ if (x.kind_of? LongDecimalBase) && (y.kind_of? LongDecimalBase)
331
+ prec = [x.scale, y.scale].max
332
+ elsif (x.kind_of? LongDecimalBase)
333
+ prec = x.scale
334
+ elsif (y.kind_of? LongDecimalBase)
335
+ prec = y.scale
336
+ else
337
+ raise ArgumentError, "precision must be supplied either as precision of x=#{x} or explicitely"
338
+ end
339
+ end
340
+ check_is_prec(prec, "prec")
341
+
342
+ if (final_mode.nil?)
343
+ final_mode = LongMath.standard_mode
344
+ end
345
+ check_is_mode(final_mode, "final_mode")
346
+ check_is_mode(mode, "mode")
347
+
348
+ if y.zero? then
349
+ return LongDecimal.one!(prec)
350
+ elsif x.zero? then
351
+ return LongDecimal.zero!(prec)
352
+ end
353
+
354
+ if (iprec.nil?) then
355
+ iprec, iprec_x, iprec_y = calc_iprec_for_power(x, y, prec)
356
+ end
357
+ unless (x.kind_of? LongDecimal)
358
+ # x = x.to_ld(iprec, mode)
359
+ x = x.to_ld(iprec_x, mode)
360
+ end
361
+ unless (y.kind_of? LongDecimal)
362
+ # y = y.to_ld(iprec, mode)
363
+ y = y.to_ld(iprec_y, mode)
364
+ end
365
+
366
+ # logx = log(x, iprec, mode)
367
+ logx = log(x, iprec + 20, mode)
368
+ logx_y = logx*y
369
+ # xy = exp_internal(logx_y, prec + 1, mode)
370
+ # xy = exp_internal(logx_y, prec + 4, mode)
371
+ xy = exp_internal(logx_y, prec + 3, mode)
372
+ xy.round_to_scale(prec, final_mode)
373
+
374
+ end # power_internal
375
+
376
+ end # LongMath
377
+
378
+ # end of file long-decimal-extra.rb