long-decimal 0.00.08 → 0.00.09

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. data/VERSION +1 -1
  2. data/doc/classes/LongDecimal.html +1432 -0
  3. data/doc/classes/LongDecimal.src/M000040.html +18 -0
  4. data/doc/classes/LongDecimal.src/M000041.html +18 -0
  5. data/doc/classes/LongDecimal.src/M000042.html +18 -0
  6. data/doc/classes/LongDecimal.src/M000043.html +18 -0
  7. data/doc/classes/LongDecimal.src/M000044.html +18 -0
  8. data/doc/classes/LongDecimal.src/M000045.html +18 -0
  9. data/doc/classes/LongDecimal.src/M000046.html +20 -0
  10. data/doc/classes/LongDecimal.src/M000047.html +109 -0
  11. data/doc/classes/LongDecimal.src/M000048.html +18 -0
  12. data/doc/classes/LongDecimal.src/M000049.html +18 -0
  13. data/doc/classes/LongDecimal.src/M000050.html +34 -0
  14. data/doc/classes/LongDecimal.src/M000051.html +41 -0
  15. data/doc/classes/LongDecimal.src/M000052.html +35 -0
  16. data/doc/classes/LongDecimal.src/M000053.html +18 -0
  17. data/doc/classes/LongDecimal.src/M000054.html +29 -0
  18. data/doc/classes/LongDecimal.src/M000055.html +18 -0
  19. data/doc/classes/LongDecimal.src/M000056.html +22 -0
  20. data/doc/classes/LongDecimal.src/M000057.html +18 -0
  21. data/doc/classes/LongDecimal.src/M000058.html +18 -0
  22. data/doc/classes/LongDecimal.src/M000059.html +20 -0
  23. data/doc/classes/LongDecimal.src/M000060.html +18 -0
  24. data/doc/classes/LongDecimal.src/M000062.html +29 -0
  25. data/doc/classes/LongDecimal.src/M000063.html +27 -0
  26. data/doc/classes/LongDecimal.src/M000064.html +18 -0
  27. data/doc/classes/LongDecimal.src/M000066.html +18 -0
  28. data/doc/classes/LongDecimal.src/M000067.html +18 -0
  29. data/doc/classes/LongDecimal.src/M000068.html +18 -0
  30. data/doc/classes/LongDecimal.src/M000069.html +18 -0
  31. data/doc/classes/LongDecimal.src/M000070.html +18 -0
  32. data/doc/classes/LongDecimal.src/M000071.html +22 -0
  33. data/doc/classes/LongDecimal.src/M000072.html +23 -0
  34. data/doc/classes/LongDecimal.src/M000073.html +23 -0
  35. data/doc/classes/LongDecimal.src/M000074.html +23 -0
  36. data/doc/classes/LongDecimal.src/M000075.html +18 -0
  37. data/doc/classes/LongDecimal.src/M000076.html +29 -0
  38. data/doc/classes/LongDecimal.src/M000077.html +23 -0
  39. data/doc/classes/LongDecimal.src/M000078.html +23 -0
  40. data/doc/classes/LongDecimal.src/M000079.html +34 -0
  41. data/doc/classes/LongDecimal.src/M000080.html +22 -0
  42. data/doc/classes/LongDecimal.src/M000081.html +19 -0
  43. data/doc/classes/LongDecimal.src/M000082.html +23 -0
  44. data/doc/classes/LongDecimal.src/M000083.html +23 -0
  45. data/doc/classes/LongDecimal.src/M000084.html +23 -0
  46. data/doc/classes/LongDecimal.src/M000085.html +18 -0
  47. data/doc/classes/LongDecimal.src/M000086.html +21 -0
  48. data/doc/classes/LongDecimal.src/M000087.html +21 -0
  49. data/doc/classes/LongDecimal.src/M000088.html +18 -0
  50. data/doc/classes/LongDecimal.src/M000089.html +18 -0
  51. data/doc/classes/LongDecimal.src/M000090.html +23 -0
  52. data/doc/classes/LongDecimal.src/M000091.html +23 -0
  53. data/doc/classes/LongDecimal.src/M000092.html +19 -0
  54. data/doc/classes/LongDecimal.src/M000093.html +23 -0
  55. data/doc/classes/LongDecimal.src/M000094.html +18 -0
  56. data/doc/classes/LongDecimal.src/M000095.html +30 -0
  57. data/doc/classes/LongDecimal.src/M000096.html +18 -0
  58. data/doc/classes/LongDecimal.src/M000097.html +18 -0
  59. data/doc/classes/LongDecimal.src/M000098.html +18 -0
  60. data/doc/classes/LongDecimal.src/M000099.html +23 -0
  61. data/doc/classes/LongDecimal.src/M000100.html +19 -0
  62. data/doc/classes/LongDecimal.src/M000101.html +18 -0
  63. data/doc/classes/LongDecimal.src/M000102.html +45 -0
  64. data/doc/classes/LongDecimal.src/M000103.html +18 -0
  65. data/doc/classes/LongDecimal.src/M000104.html +18 -0
  66. data/doc/classes/LongDecimal.src/M000107.html +18 -0
  67. data/doc/classes/LongDecimal.src/M000108.html +18 -0
  68. data/doc/classes/LongDecimal.src/M000109.html +18 -0
  69. data/doc/classes/LongDecimal.src/M000110.html +18 -0
  70. data/doc/classes/LongDecimalQuot.html +757 -0
  71. data/doc/classes/LongDecimalQuot.src/M000003.html +18 -0
  72. data/doc/classes/LongDecimalQuot.src/M000004.html +28 -0
  73. data/doc/classes/LongDecimalQuot.src/M000005.html +18 -0
  74. data/doc/classes/LongDecimalQuot.src/M000006.html +18 -0
  75. data/doc/classes/LongDecimalQuot.src/M000007.html +18 -0
  76. data/doc/classes/LongDecimalQuot.src/M000008.html +18 -0
  77. data/doc/classes/LongDecimalQuot.src/M000009.html +19 -0
  78. data/doc/classes/LongDecimalQuot.src/M000010.html +18 -0
  79. data/doc/classes/LongDecimalQuot.src/M000011.html +18 -0
  80. data/doc/classes/LongDecimalQuot.src/M000012.html +18 -0
  81. data/doc/classes/LongDecimalQuot.src/M000013.html +18 -0
  82. data/doc/classes/LongDecimalQuot.src/M000014.html +18 -0
  83. data/doc/classes/LongDecimalQuot.src/M000015.html +22 -0
  84. data/doc/classes/LongDecimalQuot.src/M000016.html +23 -0
  85. data/doc/classes/LongDecimalQuot.src/M000017.html +23 -0
  86. data/doc/classes/LongDecimalQuot.src/M000018.html +23 -0
  87. data/doc/classes/LongDecimalQuot.src/M000019.html +23 -0
  88. data/doc/classes/LongDecimalQuot.src/M000020.html +35 -0
  89. data/doc/classes/LongDecimalQuot.src/M000021.html +22 -0
  90. data/doc/classes/LongDecimalQuot.src/M000022.html +19 -0
  91. data/doc/classes/LongDecimalQuot.src/M000023.html +18 -0
  92. data/doc/classes/LongDecimalQuot.src/M000024.html +18 -0
  93. data/doc/classes/LongDecimalQuot.src/M000025.html +18 -0
  94. data/doc/classes/LongDecimalQuot.src/M000026.html +18 -0
  95. data/doc/classes/LongDecimalQuot.src/M000027.html +79 -0
  96. data/doc/classes/LongDecimalQuot.src/M000028.html +36 -0
  97. data/doc/classes/LongDecimalQuot.src/M000029.html +18 -0
  98. data/doc/classes/LongDecimalQuot.src/M000030.html +23 -0
  99. data/doc/classes/LongDecimalQuot.src/M000031.html +19 -0
  100. data/doc/classes/LongDecimalQuot.src/M000032.html +18 -0
  101. data/doc/classes/LongDecimalQuot.src/M000033.html +18 -0
  102. data/doc/classes/LongDecimalQuot.src/M000034.html +18 -0
  103. data/doc/classes/LongDecimalQuot.src/M000037.html +18 -0
  104. data/doc/classes/LongDecimalQuot.src/M000038.html +18 -0
  105. data/doc/classes/LongDecimalQuot.src/M000039.html +18 -0
  106. data/doc/classes/LongDecimalRoundingMode.html +185 -0
  107. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.html +155 -0
  108. data/doc/classes/LongDecimalRoundingMode/RoundingModeClass.src/M000122.html +22 -0
  109. data/doc/classes/LongMath.html +468 -0
  110. data/doc/classes/LongMath.src/M000112.html +19 -0
  111. data/doc/classes/LongMath.src/M000113.html +18 -0
  112. data/doc/classes/LongMath.src/M000114.html +18 -0
  113. data/doc/classes/LongMath.src/M000115.html +19 -0
  114. data/doc/classes/LongMath.src/M000116.html +18 -0
  115. data/doc/classes/LongMath.src/M000117.html +32 -0
  116. data/doc/classes/LongMath.src/M000118.html +32 -0
  117. data/doc/classes/LongMath.src/M000119.html +19 -0
  118. data/doc/classes/LongMath.src/M000120.html +43 -0
  119. data/doc/classes/LongMath.src/M000121.html +19 -0
  120. data/doc/classes/Numeric.html +149 -0
  121. data/doc/classes/Numeric.src/M000111.html +18 -0
  122. data/doc/created.rid +1 -0
  123. data/doc/dot/f_0.dot +113 -0
  124. data/doc/dot/f_0.png +0 -0
  125. data/doc/dot/m_0_0.dot +40 -0
  126. data/doc/dot/m_0_0.png +0 -0
  127. data/doc/dot/m_0_1.dot +49 -0
  128. data/doc/dot/m_0_1.png +0 -0
  129. data/doc/files/lib/longdecimal_rb.html +180 -0
  130. data/doc/files/lib/longdecimal_rb.src/M000001.html +22 -0
  131. data/doc/files/lib/longdecimal_rb.src/M000002.html +18 -0
  132. data/doc/fr_class_index.html +32 -0
  133. data/doc/fr_file_index.html +27 -0
  134. data/doc/fr_method_index.html +154 -0
  135. data/doc/index.html +24 -0
  136. data/doc/rdoc-style.css +208 -0
  137. data/lib/longdecimal.rb +216 -48
  138. data/test/testlongdecimal.rb +112 -24
  139. metadata +149 -2
data/doc/index.html ADDED
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
5
+
6
+ <!--
7
+
8
+ RDoc Documentation
9
+
10
+ -->
11
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
12
+ <head>
13
+ <title>RDoc Documentation</title>
14
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
15
+ </head>
16
+ <frameset rows="20%, 80%">
17
+ <frameset cols="25%,35%,45%">
18
+ <frame src="fr_file_index.html" title="Files" name="Files" />
19
+ <frame src="fr_class_index.html" name="Classes" />
20
+ <frame src="fr_method_index.html" name="Methods" />
21
+ </frameset>
22
+ <frame src="files/lib/longdecimal_rb.html" name="docwin" />
23
+ </frameset>
24
+ </html>
@@ -0,0 +1,208 @@
1
+
2
+ body {
3
+ font-family: Verdana,Arial,Helvetica,sans-serif;
4
+ font-size: 90%;
5
+ margin: 0;
6
+ margin-left: 40px;
7
+ padding: 0;
8
+ background: white;
9
+ }
10
+
11
+ h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
12
+ h1 { font-size: 150%; }
13
+ h2,h3,h4 { margin-top: 1em; }
14
+
15
+ a { background: #eef; color: #039; text-decoration: none; }
16
+ a:hover { background: #039; color: #eef; }
17
+
18
+ /* Override the base stylesheet's Anchor inside a table cell */
19
+ td > a {
20
+ background: transparent;
21
+ color: #039;
22
+ text-decoration: none;
23
+ }
24
+
25
+ /* and inside a section title */
26
+ .section-title > a {
27
+ background: transparent;
28
+ color: #eee;
29
+ text-decoration: none;
30
+ }
31
+
32
+ /* === Structural elements =================================== */
33
+
34
+ div#index {
35
+ margin: 0;
36
+ margin-left: -40px;
37
+ padding: 0;
38
+ font-size: 90%;
39
+ }
40
+
41
+
42
+ div#index a {
43
+ margin-left: 0.7em;
44
+ }
45
+
46
+ div#index .section-bar {
47
+ margin-left: 0px;
48
+ padding-left: 0.7em;
49
+ background: #ccc;
50
+ font-size: small;
51
+ }
52
+
53
+
54
+ div#classHeader, div#fileHeader {
55
+ width: auto;
56
+ color: white;
57
+ padding: 0.5em 1.5em 0.5em 1.5em;
58
+ margin: 0;
59
+ margin-left: -40px;
60
+ border-bottom: 3px solid #006;
61
+ }
62
+
63
+ div#classHeader a, div#fileHeader a {
64
+ background: inherit;
65
+ color: white;
66
+ }
67
+
68
+ div#classHeader td, div#fileHeader td {
69
+ background: inherit;
70
+ color: white;
71
+ }
72
+
73
+
74
+ div#fileHeader {
75
+ background: #057;
76
+ }
77
+
78
+ div#classHeader {
79
+ background: #048;
80
+ }
81
+
82
+
83
+ .class-name-in-header {
84
+ font-size: 180%;
85
+ font-weight: bold;
86
+ }
87
+
88
+
89
+ div#bodyContent {
90
+ padding: 0 1.5em 0 1.5em;
91
+ }
92
+
93
+ div#description {
94
+ padding: 0.5em 1.5em;
95
+ background: #efefef;
96
+ border: 1px dotted #999;
97
+ }
98
+
99
+ div#description h1,h2,h3,h4,h5,h6 {
100
+ color: #125;;
101
+ background: transparent;
102
+ }
103
+
104
+ div#validator-badges {
105
+ text-align: center;
106
+ }
107
+ div#validator-badges img { border: 0; }
108
+
109
+ div#copyright {
110
+ color: #333;
111
+ background: #efefef;
112
+ font: 0.75em sans-serif;
113
+ margin-top: 5em;
114
+ margin-bottom: 0;
115
+ padding: 0.5em 2em;
116
+ }
117
+
118
+
119
+ /* === Classes =================================== */
120
+
121
+ table.header-table {
122
+ color: white;
123
+ font-size: small;
124
+ }
125
+
126
+ .type-note {
127
+ font-size: small;
128
+ color: #DEDEDE;
129
+ }
130
+
131
+ .xxsection-bar {
132
+ background: #eee;
133
+ color: #333;
134
+ padding: 3px;
135
+ }
136
+
137
+ .section-bar {
138
+ color: #333;
139
+ border-bottom: 1px solid #999;
140
+ margin-left: -20px;
141
+ }
142
+
143
+
144
+ .section-title {
145
+ background: #79a;
146
+ color: #eee;
147
+ padding: 3px;
148
+ margin-top: 2em;
149
+ margin-left: -30px;
150
+ border: 1px solid #999;
151
+ }
152
+
153
+ .top-aligned-row { vertical-align: top }
154
+ .bottom-aligned-row { vertical-align: bottom }
155
+
156
+ /* --- Context section classes ----------------------- */
157
+
158
+ .context-row { }
159
+ .context-item-name { font-family: monospace; font-weight: bold; color: black; }
160
+ .context-item-value { font-size: small; color: #448; }
161
+ .context-item-desc { color: #333; padding-left: 2em; }
162
+
163
+ /* --- Method classes -------------------------- */
164
+ .method-detail {
165
+ background: #efefef;
166
+ padding: 0;
167
+ margin-top: 0.5em;
168
+ margin-bottom: 1em;
169
+ border: 1px dotted #ccc;
170
+ }
171
+ .method-heading {
172
+ color: black;
173
+ background: #ccc;
174
+ border-bottom: 1px solid #666;
175
+ padding: 0.2em 0.5em 0 0.5em;
176
+ }
177
+ .method-signature { color: black; background: inherit; }
178
+ .method-name { font-weight: bold; }
179
+ .method-args { font-style: italic; }
180
+ .method-description { padding: 0 0.5em 0 0.5em; }
181
+
182
+ /* --- Source code sections -------------------- */
183
+
184
+ a.source-toggle { font-size: 90%; }
185
+ div.method-source-code {
186
+ background: #262626;
187
+ color: #ffdead;
188
+ margin: 1em;
189
+ padding: 0.5em;
190
+ border: 1px dashed #999;
191
+ overflow: hidden;
192
+ }
193
+
194
+ div.method-source-code pre { color: #ffdead; overflow: hidden; }
195
+
196
+ /* --- Ruby keyword styles --------------------- */
197
+
198
+ .standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
199
+
200
+ .ruby-constant { color: #7fffd4; background: transparent; }
201
+ .ruby-keyword { color: #00ffff; background: transparent; }
202
+ .ruby-ivar { color: #eedd82; background: transparent; }
203
+ .ruby-operator { color: #00ffee; background: transparent; }
204
+ .ruby-identifier { color: #ffdead; background: transparent; }
205
+ .ruby-node { color: #ffa07a; background: transparent; }
206
+ .ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
207
+ .ruby-regexp { color: #ffa07a; background: transparent; }
208
+ .ruby-value { color: #7fffd4; background: transparent; }
data/lib/longdecimal.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # longdecimal.rb -- Arbitrary precision decimals with fixed decimal point
3
3
  #
4
- # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/lib/longdecimal.rb,v 1.4 2006/03/02 20:20:12 bk1 Exp $
5
- # CVS-Label: $Name: PRE_ALPHA_0_08 $
4
+ # CVS-ID: $Header: /var/cvs/long-decimal/long-decimal/lib/longdecimal.rb,v 1.5 2006/03/04 21:49:00 bk1 Exp $
5
+ # CVS-Label: $Name: PRE_ALPHA_0_09 $
6
6
  # Author: $Author: bk1 $ (Karl Brodowsky)
7
7
  #
8
8
  require "complex"
@@ -11,25 +11,89 @@ require "bigdecimal"
11
11
 
12
12
  # require "bigdecimal/math"
13
13
 
14
+ #
15
+ # define rounding modes to be used for LongDecimal
16
+ # this serves the purpose of an "enum" in C/C++
17
+ #
18
+ module LongDecimalRoundingMode
19
+ RoundingModeClass = Struct.new(:name, :num)
20
+ class RoundingModeClass
21
+ include Comparable
22
+
23
+ #
24
+ # introduce some ordering for rounding modes
25
+ #
26
+ def <=>(o)
27
+ if o.respond_to?:num
28
+ self.num <=> o.num
29
+ else
30
+ self.num <=> o
31
+ end
32
+ end
33
+ end
34
+
35
+ #
36
+ # rounding modes as constants
37
+ #
38
+ ROUND_UP = RoundingModeClass.new(:ROUND_UP, 0)
39
+ ROUND_DOWN = RoundingModeClass.new(:ROUND_DOWN, 1)
40
+ ROUND_CEILING = RoundingModeClass.new(:ROUND_CEILING, 2)
41
+ ROUND_FLOOR = RoundingModeClass.new(:ROUND_FLOOR, 3)
42
+ ROUND_HALF_UP = RoundingModeClass.new(:ROUND_HALF_UP, 4)
43
+ ROUND_HALF_DOWN = RoundingModeClass.new(:ROUND_HALF_DOWN, 5)
44
+ ROUND_HALF_EVEN = RoundingModeClass.new(:ROUND_HALF_EVEN, 6)
45
+ ROUND_UNNECESSARY = RoundingModeClass.new(:ROUND_UNNECESSARY, 7)
46
+
47
+ end
48
+
14
49
  #
15
50
  # helper functions to support LongDecimal and LongDecimalQuot
16
51
  # functions for LongDecimal that do not go as methods of LongDecimal
17
52
  #
18
53
  module LongMath
19
54
 
55
+ include LongDecimalRoundingMode
56
+
20
57
  MAX_FLOATABLE = Float::MAX.to_i
21
- MIN_FLOATABLE = Float::MIN.to_i
58
+ MAX_EXP_ABLE = Math.log(MAX_FLOATABLE).to_i
22
59
 
23
60
  #
24
61
  # helper method: checks if word_len is of reasonable for splitting a
25
62
  # number into parts
26
63
  #
27
- def LongMath.check_word_len(word_len)
28
- raise TypeError, "word_len must be a positive number <= 1024" unless (word_len.kind_of? Fixnum) && word_len > 0 && word_len <= 1024
64
+ def LongMath.check_word_len(word_len, name="word_len")
65
+ raise TypeError, "#{name} must be a positive number <= 1024" unless (word_len.kind_of? Fixnum) && word_len > 0 && word_len <= 1024
29
66
  word_len
30
67
  end
31
68
 
32
- # private :check_word_len
69
+ #
70
+ # helper method: checks if parameter x is an Integer
71
+ #
72
+ def LongMath.check_is_int(x, name="x")
73
+ raise TypeError, "#{name}=#{x.inspect} must be Integer" unless x.kind_of? Integer
74
+ end
75
+
76
+ #
77
+ # helper method: checks if parameter x is a LongDecimal
78
+ #
79
+ def LongMath.check_is_ld(x, name="x")
80
+ raise TypeError, "x=#{x.inspect} must be LongDecimal" unless x.kind_of? LongDecimal
81
+ end
82
+
83
+ #
84
+ # helper method: checks if parameter x is a LongDecimal
85
+ #
86
+ def LongMath.check_is_prec(prec, name="prec")
87
+ check_is_int(prec, "prec")
88
+ raise TypeError, "#{name}=#{prec.inspect} must be >= 0" unless prec >= 0
89
+ end
90
+
91
+ #
92
+ # helper method: checks if parameter x is a LongDecimal
93
+ #
94
+ def LongMath.check_is_mode(mode, name="mode")
95
+ raise TypeError, "#{name}=#{mode.inspect} must be legal rounding mode" unless mode.kind_of? RoundingModeClass
96
+ end
33
97
 
34
98
  #
35
99
  # split number x into parts of word_len bits each
@@ -37,7 +101,7 @@ module LongMath
37
101
  #
38
102
  def LongMath.split_to_words(x, word_len = 32)
39
103
  check_word_len(word_len)
40
- raise TypeError, "x must be Integer" unless x.kind_of? Integer
104
+ check_is_int(x)
41
105
  m = x.abs
42
106
  s = (x <=> 0)
43
107
  bit_pattern = (1 << word_len) - 1
@@ -82,8 +146,14 @@ module LongMath
82
146
  a[0]
83
147
  end
84
148
 
149
+ #
150
+ # calculate the an integer s >= 0 and a remainder r >= 0 such that
151
+ # x = s**2 + r and x < (x.succ)**2
152
+ # the bitwise algorithm is used, which works well for relatively
153
+ # small values of x.
154
+ #
85
155
  def LongMath.sqrtb_with_remainder(x)
86
- raise TypeError, "x must be integer" unless x.kind_of? Integer
156
+ check_is_int(x)
87
157
 
88
158
  s = (x <=> 0)
89
159
  if (s == 0) then
@@ -119,12 +189,20 @@ module LongMath
119
189
  a[0]
120
190
  end
121
191
 
192
+ #
193
+ # calculate the an integer s >= 0 and a remainder r >= 0 such that
194
+ # x = s**2 + r and x < (x.succ)**2
195
+ # the wordwise algorithm is used, which works well for relatively
196
+ # large values of x. n defines the word size to be used for the
197
+ # algorithm. It is good to use half of the machine word, but the
198
+ # algorithm would also work for other values.
199
+ #
122
200
  def LongMath.sqrtw_with_remainder(x, n = 16)
123
- raise TypeError, "x must be integer" unless x.kind_of? Integer
124
- raise TypeError, "n must be an integer" unless (n.kind_of? Integer)
201
+ check_is_int(x)
202
+ check_is_int(n, "n")
125
203
  n2 = n<<1
126
204
  n1 = n+1
127
- check_word_len(n2)
205
+ check_word_len(n2, "2*n")
128
206
 
129
207
  s = (x <=> 0)
130
208
  if (s == 0) then
@@ -184,9 +262,9 @@ module LongMath
184
262
  # for all m, n > n0
185
263
  #
186
264
  def LongMath.gcd_with_high_power(x, b)
187
- raise TypeError, "gcd_with_high_power can only be calculated for integers, but x=#{x.inspect} is no integer." unless x.kind_of? Integer
265
+ check_is_int(x, "x")
188
266
  raise ZeroDivisionError, "gcd_with_high_power of zero with \"#{b.inspect}\" would be infinity" if x.zero?
189
- raise TypeError, "gcd_with_high_power can only be calculated for integers \"#{b.inspect}\" is no integer" unless b.kind_of? Integer
267
+ check_is_int(b, "b")
190
268
  raise ZeroDivisionError, "gcd_with_high_power with b < 2 is not defined. b=\"#{b.inspect}\"" if b < 2
191
269
  s = x.abs
192
270
  exponent = 1
@@ -253,6 +331,7 @@ module LongMath
253
331
  # for more digits, you will find a specialized and optimized program
254
332
  # for this specific purpose.
255
333
  # (this is the easter egg ;-) )
334
+ #
256
335
  def LongMath.calc_pi(prec, final_mode = LongDecimal::ROUND_HALF_DOWN)
257
336
  mode = LongDecimal::ROUND_HALF_DOWN
258
337
  iprec = 5*(prec+1)
@@ -286,39 +365,118 @@ module LongMath
286
365
  pi.round_to_scale(prec, final_mode)
287
366
  end
288
367
 
289
- end
368
+ #
369
+ # calc the exponential function of x to the given precision as
370
+ # LongDecimal. Only supports values of x such that the result still
371
+ # fits into a float (x <= 709)
372
+ #
373
+ def LongMath.exp(x, prec, mode = LongDecimal::ROUND_HALF_DOWN)
374
+ check_is_ld(x, "x")
375
+ check_is_prec(prec, "prec")
376
+ check_is_mode(mode, "mode")
377
+ exp_internal(x, prec, mode)
378
+ end
290
379
 
291
- #
292
- # define rounding modes to be used for LongDecimal
293
- # this serves the purpose of an "enum" in C/C++
294
- #
295
- module LongDecimalRoundingMode
296
- RoundingModeClass = Struct.new(:name, :num)
297
- class RoundingModeClass
298
- include Comparable
380
+ #
381
+ # internal functionality of exp. exposes some more parameters, that
382
+ # should usually be set to defaut values, in order to allow better testing.
383
+ # do not actually call this method unless you are testing exp.
384
+ # create a bug report, if the default settings for the parameters do
385
+ # not work correctly
386
+ #
387
+ def LongMath.exp_internal(x, prec = nil, final_mode = LongDecimal::ROUND_HALF_DOWN, j = nil, k = nil, iprec = nil, mode = LongDecimal::ROUND_HALF_DOWN)
388
+ check_is_ld(x)
389
+ raise TypeError, "x=#{x.inspect} must not be greater #{MAX_EXP_ABLE}" unless x <= MAX_EXP_ABLE
390
+ if (prec == nil) then
391
+ prec = x.scale
392
+ end
393
+ check_is_prec(prec, "prec")
299
394
 
300
- #
301
- # introduce some ordering for rounding modes
302
- #
303
- def <=>(o)
304
- if o.respond_to?:num
305
- self.num <=> o.num
306
- else
307
- self.num <=> o
395
+ if (final_mode == nil)
396
+ final_mode = LongDecimal::ROUND_HALF_DOWN
397
+ end
398
+ check_is_mode(final_mode, "final_mode")
399
+ check_is_mode(mode, "mode")
400
+
401
+ # if the result would come out to zero anyway, cut the work
402
+ xi = x.to_i
403
+ if (xi < -LongMath::MAX_FLOATABLE) || -((xi.to_f - 1) / Math.log(10)) > prec+1 then
404
+ return LongDecimal(25, prec+2).round_to_scale(prec, final_mode)
405
+ end
406
+
407
+ if j == nil || k == nil then
408
+ l2 = Math.log(2.0)
409
+ lb = Math.log(10.0)
410
+ s1 = (prec * lb / l2) ** (1.0/3.0)
411
+ if (j == nil) then
412
+ j = s1.round
413
+ end
414
+ if (k == nil) then
415
+ k = (s1 + Math.log([1, prec].max) / l2).round
308
416
  end
309
417
  end
310
- end
418
+ if (j <= 0) then
419
+ j = 1
420
+ end
421
+ if (k < 0) then
422
+ k = 0
423
+ end
424
+ check_is_int(j, "j")
425
+ check_is_int(k, "k")
426
+
427
+ iprec_extra = 0
428
+ if (x > 1) then
429
+ xf = x.to_f
430
+ k += (Math.log(xf) / Math.log(2)).abs.round
431
+ iprec_extra = (xf / Math.log(10)).abs
432
+ end
433
+ if (iprec == nil) then
434
+ iprec = ((prec+10)*1.20 + iprec_extra).round
435
+ end
436
+ if (iprec < prec) then
437
+ iprec = prec
438
+ end
439
+ check_is_prec(iprec, "iprec")
311
440
 
312
- # rounding modes as constants
313
- #
314
- ROUND_UP = RoundingModeClass.new(:ROUND_UP, 0)
315
- ROUND_DOWN = RoundingModeClass.new(:ROUND_DOWN, 1)
316
- ROUND_CEILING = RoundingModeClass.new(:ROUND_CEILING, 2)
317
- ROUND_FLOOR = RoundingModeClass.new(:ROUND_FLOOR, 3)
318
- ROUND_HALF_UP = RoundingModeClass.new(:ROUND_HALF_UP, 4)
319
- ROUND_HALF_DOWN = RoundingModeClass.new(:ROUND_HALF_DOWN, 5)
320
- ROUND_HALF_EVEN = RoundingModeClass.new(:ROUND_HALF_EVEN, 6)
321
- ROUND_UNNECESSARY = RoundingModeClass.new(:ROUND_UNNECESSARY, 7)
441
+ dprec = [ iprec, (prec + 1) << 1 ].min
442
+
443
+ x_k = (x / (1 << k)).round_to_scale(iprec, mode)
444
+ x_j = (x_k ** j).round_to_scale(iprec, mode)
445
+ s = [ LongDecimal(0) ] * j
446
+ t = LongDecimal(1)
447
+ last_t = 1
448
+ f = 0
449
+ loop do
450
+ j.times do |i|
451
+ s[i] += t
452
+ f += 1
453
+ t = (t / f).round_to_scale(iprec, mode)
454
+ end
455
+ t = (t * x_j).round_to_scale(iprec, mode)
456
+ break if (t.zero?)
457
+ tr = t.round_to_scale(dprec, LongDecimal::ROUND_DOWN).abs
458
+ break if (t.zero?)
459
+ tu = t.unit
460
+ break if (tr <= tu && last_t <= tu)
461
+ last_t = tr
462
+ end
463
+ x_i = 1
464
+ y_k = LongDecimal(0)
465
+ j.times do |i|
466
+ if (i > 0) then
467
+ x_i = (x_i * x_k).round_to_scale(iprec, mode)
468
+ end
469
+ # puts("y_k=#{y_k}\ni=#{i} j=#{j} k=#{k} x=#{x}\nx_k=#{x_k}\nx_j=#{x_j}\nx_i=#{x_i}\ns[i]=#{s[i]}\n\n")
470
+ y_k += (s[i] * x_i).round_to_scale(iprec, mode)
471
+ end
472
+ # puts("y_k = #{y_k}\n")
473
+ k.times do |i|
474
+ y_k = y_k.square.round_to_scale(iprec, mode)
475
+ # puts("i=#{i} y_k = #{y_k}\n")
476
+ end
477
+ y = y_k.round_to_scale(prec, final_mode)
478
+ y
479
+ end
322
480
 
323
481
  end
324
482
 
@@ -328,7 +486,7 @@ end
328
486
  # digits and the other one the position of the decimal point.
329
487
  #
330
488
  class LongDecimal < Numeric
331
- @RCS_ID='-$Id: longdecimal.rb,v 1.4 2006/03/02 20:20:12 bk1 Exp $-'
489
+ @RCS_ID='-$Id: longdecimal.rb,v 1.5 2006/03/04 21:49:00 bk1 Exp $-'
332
490
 
333
491
  include LongDecimalRoundingMode
334
492
 
@@ -372,7 +530,7 @@ class LongDecimal < Numeric
372
530
  # digits after the decimal point (scale=s)
373
531
  #
374
532
  def LongDecimal.two!(s = 0)
375
- new(2, s)
533
+ new(2*10**s, s)
376
534
  end
377
535
 
378
536
 
@@ -381,7 +539,7 @@ class LongDecimal < Numeric
381
539
  # digits after the decimal point (scale=s)
382
540
  #
383
541
  def LongDecimal.ten!(s = 0)
384
- new(10, s)
542
+ new(10**(s+1), s)
385
543
  end
386
544
 
387
545
 
@@ -390,7 +548,7 @@ class LongDecimal < Numeric
390
548
  # digits after the decimal point (scale=s)
391
549
  #
392
550
  def LongDecimal.minus_one!(s = 0)
393
- new(-1, s)
551
+ new(-1*10**s, s)
394
552
  end
395
553
 
396
554
 
@@ -400,7 +558,9 @@ class LongDecimal < Numeric
400
558
  # point (scale=s)
401
559
  #
402
560
  def LongDecimal.power_of_ten!(e, s = 0)
403
- new(10**e, s)
561
+ raise TypeError, "non integer 1st arg \"#{e.inspect}\"" if ! e.kind_of? Integer
562
+ raise TypeError, "negative 1st arg \"#{e.inspect}\"" if e < 0
563
+ new(10**(s+e), s)
404
564
  end
405
565
 
406
566
 
@@ -643,7 +803,11 @@ class LongDecimal < Numeric
643
803
  # float-arithmetic.
644
804
  #
645
805
  def to_f
646
- int_val.to_f / 10**scale
806
+ if int_val.abs <= LongMath::MAX_FLOATABLE then
807
+ int_val.to_f / 10**scale
808
+ else
809
+ (int_val / 10**scale).to_f
810
+ end
647
811
  end
648
812
 
649
813
  #
@@ -1111,6 +1275,10 @@ class LongDecimal < Numeric
1111
1275
  elsif other.kind_of? BigDecimal then
1112
1276
  s, o = other.coerce(self.to_bd)
1113
1277
  return o, s
1278
+ elsif other.kind_of? Complex then
1279
+ # s, o = other.coerce(Complex(self.to_bd, 0))
1280
+ s, o = other.coerce(Complex(self.to_f, 0))
1281
+ return o, s
1114
1282
  elsif (other.kind_of? Float) && size > 8 then
1115
1283
  return coerce(BigDecimal(other.to_s))
1116
1284
  elsif other.kind_of? Numeric then
@@ -1163,7 +1331,7 @@ end
1163
1331
  #
1164
1332
  class LongDecimalQuot < Numeric
1165
1333
 
1166
- @RCS_ID='-$Id: longdecimal.rb,v 1.4 2006/03/02 20:20:12 bk1 Exp $-'
1334
+ @RCS_ID='-$Id: longdecimal.rb,v 1.5 2006/03/04 21:49:00 bk1 Exp $-'
1167
1335
 
1168
1336
  include LongDecimalRoundingMode
1169
1337