decimal 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +57 -0
- data/GPL +340 -0
- data/INSTALL +5 -0
- data/README +1 -0
- data/decimal.c +1614 -0
- data/decimal.gemspec +17 -0
- data/depend +3 -0
- data/extconf.rb +3 -0
- data/inum18.h +302 -0
- metadata +63 -0
data/decimal.gemspec
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = "decimal"
|
|
3
|
+
s.rubyforge_project = s.name
|
|
4
|
+
s.version = "0.0.2"
|
|
5
|
+
s.date = "2009-06-18"
|
|
6
|
+
s.summary = "(yet another) multi-precision decimal arithmetic library"
|
|
7
|
+
s.homepage = "http://decimal.rubyforge.org/"
|
|
8
|
+
s.description = <<-EOS.split("\n").map{|l|l.lstrip}.join(" ")
|
|
9
|
+
Decimal is (yet another) multi-precision decimal arithmetic library. It just
|
|
10
|
+
provides simple, compact, fast, precise, stable and easy-to-use solution.
|
|
11
|
+
EOS
|
|
12
|
+
s.extensions = "extconf.rb"
|
|
13
|
+
s.files = %w(COPYING GPL INSTALL README decimal.c decimal.gemspec depend extconf.rb inum18.h)
|
|
14
|
+
s.has_rdoc = false
|
|
15
|
+
s.authors = "Tadashi Saito"
|
|
16
|
+
s.email = "shiba@mail2.accsnet.ne.jp"
|
|
17
|
+
end
|
data/depend
ADDED
data/extconf.rb
ADDED
data/inum18.h
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Ruby's Integer part from ruby_1_8, r15364.
|
|
3
|
+
*
|
|
4
|
+
* These are hand copies (with a few modification) taken from original
|
|
5
|
+
* Ruby's code in "numeric.c" and "bignum.c," so the copyrights are
|
|
6
|
+
* held by matz and other contributors:
|
|
7
|
+
*
|
|
8
|
+
* Copyright (C) 1993-2008 Yukihiro Matsumoto
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* copied from bignum.c
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#define BDIGITS(x) ((BDIGIT*)RBIGNUM(x)->digits)
|
|
17
|
+
|
|
18
|
+
static VALUE
|
|
19
|
+
rb_big_cmp(VALUE x, VALUE y)
|
|
20
|
+
{
|
|
21
|
+
long xlen = RBIGNUM(x)->len;
|
|
22
|
+
|
|
23
|
+
switch (TYPE(y)) {
|
|
24
|
+
case T_FIXNUM:
|
|
25
|
+
y = rb_int2big(FIX2LONG(y));
|
|
26
|
+
break;
|
|
27
|
+
|
|
28
|
+
case T_BIGNUM:
|
|
29
|
+
break;
|
|
30
|
+
|
|
31
|
+
default:
|
|
32
|
+
rb_bug("rb_big_cmp(): not reached"); /* modified */
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (RBIGNUM(x)->sign > RBIGNUM(y)->sign) return INT2FIX(1);
|
|
36
|
+
if (RBIGNUM(x)->sign < RBIGNUM(y)->sign) return INT2FIX(-1);
|
|
37
|
+
if (xlen < RBIGNUM(y)->len)
|
|
38
|
+
return (RBIGNUM(x)->sign) ? INT2FIX(-1) : INT2FIX(1);
|
|
39
|
+
if (xlen > RBIGNUM(y)->len)
|
|
40
|
+
return (RBIGNUM(x)->sign) ? INT2FIX(1) : INT2FIX(-1);
|
|
41
|
+
|
|
42
|
+
while(xlen-- && (BDIGITS(x)[xlen]==BDIGITS(y)[xlen]));
|
|
43
|
+
if (-1 == xlen) return INT2FIX(0);
|
|
44
|
+
return (BDIGITS(x)[xlen] > BDIGITS(y)[xlen]) ?
|
|
45
|
+
(RBIGNUM(x)->sign ? INT2FIX(1) : INT2FIX(-1)) :
|
|
46
|
+
(RBIGNUM(x)->sign ? INT2FIX(-1) : INT2FIX(1));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static VALUE
|
|
50
|
+
rb_big_eq(VALUE x, VALUE y)
|
|
51
|
+
{
|
|
52
|
+
switch (TYPE(y)) {
|
|
53
|
+
case T_FIXNUM:
|
|
54
|
+
y = rb_int2big(FIX2LONG(y));
|
|
55
|
+
break;
|
|
56
|
+
case T_BIGNUM:
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
rb_bug("rb_big_eq(): not reached"); /* modified */
|
|
60
|
+
}
|
|
61
|
+
if (RBIGNUM(x)->sign != RBIGNUM(y)->sign) return Qfalse;
|
|
62
|
+
if (RBIGNUM(x)->len != RBIGNUM(y)->len) return Qfalse;
|
|
63
|
+
if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM(y)->len) != 0) return Qfalse;
|
|
64
|
+
return Qtrue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static VALUE
|
|
68
|
+
big_uminus(VALUE x)
|
|
69
|
+
{
|
|
70
|
+
VALUE z = rb_big_clone(x);
|
|
71
|
+
|
|
72
|
+
RBIGNUM(z)->sign = !RBIGNUM(x)->sign;
|
|
73
|
+
|
|
74
|
+
return rb_big_norm(z); /* modified to use exported one */
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static VALUE
|
|
78
|
+
rb_big_hash(VALUE x)
|
|
79
|
+
{
|
|
80
|
+
long i, len, key;
|
|
81
|
+
BDIGIT *digits;
|
|
82
|
+
|
|
83
|
+
key = 0; digits = BDIGITS(x); len = RBIGNUM(x)->len;
|
|
84
|
+
for (i=0; i<len; i++) {
|
|
85
|
+
key ^= *digits++;
|
|
86
|
+
}
|
|
87
|
+
return LONG2FIX(key);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/*
|
|
91
|
+
* copied from numeric.c
|
|
92
|
+
*/
|
|
93
|
+
|
|
94
|
+
static VALUE
|
|
95
|
+
fix_plus(VALUE x, VALUE y)
|
|
96
|
+
{
|
|
97
|
+
if (FIXNUM_P(y)) {
|
|
98
|
+
long a, b, c;
|
|
99
|
+
VALUE r;
|
|
100
|
+
|
|
101
|
+
a = FIX2LONG(x);
|
|
102
|
+
b = FIX2LONG(y);
|
|
103
|
+
c = a + b;
|
|
104
|
+
r = LONG2NUM(c);
|
|
105
|
+
|
|
106
|
+
return r;
|
|
107
|
+
}
|
|
108
|
+
return rb_big_plus(y, x); /* modified */
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static VALUE
|
|
112
|
+
fix_minus(VALUE x, VALUE y)
|
|
113
|
+
{
|
|
114
|
+
if (FIXNUM_P(y)) {
|
|
115
|
+
long a, b, c;
|
|
116
|
+
VALUE r;
|
|
117
|
+
|
|
118
|
+
a = FIX2LONG(x);
|
|
119
|
+
b = FIX2LONG(y);
|
|
120
|
+
c = a - b;
|
|
121
|
+
r = LONG2NUM(c);
|
|
122
|
+
|
|
123
|
+
return r;
|
|
124
|
+
}
|
|
125
|
+
return rb_big_minus(rb_int2big(FIX2LONG(x)), y); /* modified */
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static VALUE
|
|
129
|
+
fix_mul(VALUE x, VALUE y)
|
|
130
|
+
{
|
|
131
|
+
if (FIXNUM_P(y)) {
|
|
132
|
+
long a, b, c;
|
|
133
|
+
VALUE r;
|
|
134
|
+
|
|
135
|
+
a = FIX2LONG(x);
|
|
136
|
+
if (a == 0) return x;
|
|
137
|
+
|
|
138
|
+
b = FIX2LONG(y);
|
|
139
|
+
c = a * b;
|
|
140
|
+
r = LONG2FIX(c);
|
|
141
|
+
|
|
142
|
+
if (FIX2LONG(r) != c || c/a != b) {
|
|
143
|
+
r = rb_big_mul(rb_int2big(a), rb_int2big(b));
|
|
144
|
+
}
|
|
145
|
+
return r;
|
|
146
|
+
}
|
|
147
|
+
return rb_big_mul(y, x); /* modified */
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
static void
|
|
151
|
+
fixdivmod(long x, long y, long *divp, long *modp)
|
|
152
|
+
{
|
|
153
|
+
long div, mod;
|
|
154
|
+
|
|
155
|
+
if (y == 0) rb_bug("fixdivmod(): not reached"); /* modified */
|
|
156
|
+
if (y < 0) {
|
|
157
|
+
if (x < 0)
|
|
158
|
+
div = -x / -y;
|
|
159
|
+
else
|
|
160
|
+
div = - (x / -y);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
if (x < 0)
|
|
164
|
+
div = - (-x / y);
|
|
165
|
+
else
|
|
166
|
+
div = x / y;
|
|
167
|
+
}
|
|
168
|
+
mod = x - div*y;
|
|
169
|
+
if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
|
|
170
|
+
mod += y;
|
|
171
|
+
div -= 1;
|
|
172
|
+
}
|
|
173
|
+
if (divp) *divp = div;
|
|
174
|
+
if (modp) *modp = mod;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static VALUE
|
|
178
|
+
fix_div(VALUE x, VALUE y)
|
|
179
|
+
{
|
|
180
|
+
if (FIXNUM_P(y)) {
|
|
181
|
+
long div;
|
|
182
|
+
|
|
183
|
+
fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, 0);
|
|
184
|
+
return LONG2NUM(div);
|
|
185
|
+
}
|
|
186
|
+
/* modified */
|
|
187
|
+
return RARRAY(rb_big_divmod(rb_int2big(FIX2LONG(x)), y))->ptr[0];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
static VALUE
|
|
191
|
+
fix_divmod(VALUE x, VALUE y)
|
|
192
|
+
{
|
|
193
|
+
if (FIXNUM_P(y)) {
|
|
194
|
+
long div, mod;
|
|
195
|
+
|
|
196
|
+
fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, &mod);
|
|
197
|
+
|
|
198
|
+
return rb_assoc_new(LONG2NUM(div), LONG2NUM(mod));
|
|
199
|
+
}
|
|
200
|
+
return rb_big_divmod(rb_int2big(FIX2LONG(x)), y); /* modified */
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
static VALUE
|
|
204
|
+
int_pow(long x, unsigned long y)
|
|
205
|
+
{
|
|
206
|
+
int neg = x < 0;
|
|
207
|
+
long z = 1;
|
|
208
|
+
|
|
209
|
+
if (neg) x = -x;
|
|
210
|
+
if (y & 1)
|
|
211
|
+
z = x;
|
|
212
|
+
else
|
|
213
|
+
neg = 0;
|
|
214
|
+
y &= ~1;
|
|
215
|
+
do {
|
|
216
|
+
while (y % 2 == 0) {
|
|
217
|
+
long x2 = x * x;
|
|
218
|
+
if (x2/x != x || !POSFIXABLE(x2)) {
|
|
219
|
+
VALUE v;
|
|
220
|
+
bignum:
|
|
221
|
+
v = rb_big_pow(rb_int2big(x), LONG2NUM(y));
|
|
222
|
+
if (z != 1) v = rb_big_mul(rb_int2big(neg ? -z : z), v);
|
|
223
|
+
return v;
|
|
224
|
+
}
|
|
225
|
+
x = x2;
|
|
226
|
+
y >>= 1;
|
|
227
|
+
}
|
|
228
|
+
{
|
|
229
|
+
long xz = x * z;
|
|
230
|
+
if (!POSFIXABLE(xz) || xz / x != z) {
|
|
231
|
+
goto bignum;
|
|
232
|
+
}
|
|
233
|
+
z = xz;
|
|
234
|
+
}
|
|
235
|
+
} while (--y);
|
|
236
|
+
if (neg) z = -z;
|
|
237
|
+
return LONG2NUM(z);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
static VALUE
|
|
241
|
+
fix_pow(VALUE x, VALUE y)
|
|
242
|
+
{
|
|
243
|
+
long a = FIX2LONG(x);
|
|
244
|
+
|
|
245
|
+
if (FIXNUM_P(y)) {
|
|
246
|
+
long b = FIX2LONG(y);
|
|
247
|
+
|
|
248
|
+
if (b == 0) return INT2FIX(1);
|
|
249
|
+
if (b == 1) return x;
|
|
250
|
+
if (a == 0) {
|
|
251
|
+
if (b > 0) return INT2FIX(0);
|
|
252
|
+
/* modified */
|
|
253
|
+
rb_bug("fix_pow(): infinity returned");
|
|
254
|
+
return Qnil;
|
|
255
|
+
}
|
|
256
|
+
if (a == 1) return INT2FIX(1);
|
|
257
|
+
if (a == -1) {
|
|
258
|
+
if (b % 2 == 0)
|
|
259
|
+
return INT2FIX(1);
|
|
260
|
+
else
|
|
261
|
+
return INT2FIX(-1);
|
|
262
|
+
}
|
|
263
|
+
if (b > 0) {
|
|
264
|
+
return int_pow(a, b);
|
|
265
|
+
}
|
|
266
|
+
/* modified */
|
|
267
|
+
rb_bug("fix_pow(): Float returned");
|
|
268
|
+
return Qnil;
|
|
269
|
+
}
|
|
270
|
+
/* modified to treat with Bignums only */
|
|
271
|
+
if (a == 0) return INT2FIX(0);
|
|
272
|
+
if (a == 1) return INT2FIX(1);
|
|
273
|
+
if (a == -1) {
|
|
274
|
+
if ((BDIGITS(y)[0] & 1) == 0) return INT2FIX(1); /* modified */
|
|
275
|
+
else return INT2FIX(-1);
|
|
276
|
+
}
|
|
277
|
+
x = rb_int2big(FIX2LONG(x));
|
|
278
|
+
return rb_big_pow(x, y);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
static VALUE
|
|
282
|
+
fix_equal(VALUE x, VALUE y)
|
|
283
|
+
{
|
|
284
|
+
if (x == y) return Qtrue;
|
|
285
|
+
if (FIXNUM_P(y)) return Qfalse;
|
|
286
|
+
return rb_big_eq(y, x); /* modified */
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
static VALUE
|
|
290
|
+
fix_cmp(VALUE x, VALUE y)
|
|
291
|
+
{
|
|
292
|
+
if (x == y) return INT2FIX(0);
|
|
293
|
+
if (FIXNUM_P(y)) {
|
|
294
|
+
long a = FIX2LONG(x), b = FIX2LONG(y);
|
|
295
|
+
|
|
296
|
+
if (a > b) return INT2FIX(1);
|
|
297
|
+
return INT2FIX(-1);
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
return rb_big_cmp(rb_int2big(FIX2LONG(x)), y); /* modified */
|
|
301
|
+
}
|
|
302
|
+
}
|
metadata
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: decimal
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Tadashi Saito
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-06-18 00:00:00 +09:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description: Decimal is (yet another) multi-precision decimal arithmetic library. It just provides simple, compact, fast, precise, stable and easy-to-use solution.
|
|
17
|
+
email: shiba@mail2.accsnet.ne.jp
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions:
|
|
21
|
+
- extconf.rb
|
|
22
|
+
extra_rdoc_files: []
|
|
23
|
+
|
|
24
|
+
files:
|
|
25
|
+
- COPYING
|
|
26
|
+
- GPL
|
|
27
|
+
- INSTALL
|
|
28
|
+
- README
|
|
29
|
+
- decimal.c
|
|
30
|
+
- decimal.gemspec
|
|
31
|
+
- depend
|
|
32
|
+
- extconf.rb
|
|
33
|
+
- inum18.h
|
|
34
|
+
has_rdoc: true
|
|
35
|
+
homepage: http://decimal.rubyforge.org/
|
|
36
|
+
licenses: []
|
|
37
|
+
|
|
38
|
+
post_install_message:
|
|
39
|
+
rdoc_options: []
|
|
40
|
+
|
|
41
|
+
require_paths:
|
|
42
|
+
- lib
|
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: "0"
|
|
48
|
+
version:
|
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: "0"
|
|
54
|
+
version:
|
|
55
|
+
requirements: []
|
|
56
|
+
|
|
57
|
+
rubyforge_project: decimal
|
|
58
|
+
rubygems_version: 1.3.4
|
|
59
|
+
signing_key:
|
|
60
|
+
specification_version: 3
|
|
61
|
+
summary: (yet another) multi-precision decimal arithmetic library
|
|
62
|
+
test_files: []
|
|
63
|
+
|