bigdecimal 1.2.3 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 60d3dce1a57a777beadceb1451b2e0972b60181a
4
- data.tar.gz: 65e7f3cab117bbbdc380fa3680187fa666b2ce9e
3
+ metadata.gz: 4c41d73d519030d6a97115486ade3119700dc79e
4
+ data.tar.gz: c4a3ca819835bb6db328a3d855afdd0a31860479
5
5
  SHA512:
6
- metadata.gz: 7c9dbd7e5132491e100390193c623310c24f24b65dfd5dbb351dd8254e353d0748f5c5fffb3c868fb0f889095d60080d5e2b026f74caf30eae8925a23c912c0a
7
- data.tar.gz: 827e65f0a6ad81a6a2d499aa4d53fd566f3d67338b9294d1bf17642e24dedcd3e9c5ad562064f32ab9b5ee256d6d5f24b355bd3f094cef6ecf6d668aa21ca532
6
+ metadata.gz: 46e465effb34908c3954dd120bca6693ae3dde3d666c7419e0a2d6729b111f1cbe120f4c1f97dec26e4085166cd578a72207191410b420a5f044d76ffb638277
7
+ data.tar.gz: eca4ce9b2faf70b4c6c7f12a51f8e6bc5e2d37a5a5c170a2a0e6a32f15e893e1f2814583cfc586e7daca28161eeeab6a44a80ff835085a15614a8d71e33b2541
data/bigdecimal.c CHANGED
@@ -18,6 +18,7 @@
18
18
  # define BIGDECIMAL_ENABLE_VPRINT 1
19
19
  #endif
20
20
  #include "bigdecimal.h"
21
+ #include "ruby/util.h"
21
22
 
22
23
  #ifndef BIGDECIMAL_DEBUG
23
24
  # define NDEBUG
@@ -126,6 +127,10 @@ static void VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v);
126
127
  static int VpLimitRound(Real *c, size_t ixDigit);
127
128
  static Real *VpCopy(Real *pv, Real const* const x);
128
129
 
130
+ #ifdef BIGDECIMAL_ENABLE_VPRINT
131
+ static int VPrint(FILE *fp,const char *cntl_chr,Real *a);
132
+ #endif
133
+
129
134
  /*
130
135
  * **** BigDecimal part ****
131
136
  */
@@ -199,14 +204,23 @@ GetVpValueWithPrec(VALUE v, long prec, int must)
199
204
  VALUE num, bg;
200
205
  char szD[128];
201
206
  VALUE orig = Qundef;
207
+ double d;
202
208
 
203
209
  again:
204
210
  switch(TYPE(v)) {
205
211
  case T_FLOAT:
206
212
  if (prec < 0) goto unable_to_coerce_without_prec;
207
213
  if (prec > DBL_DIG+1) goto SomeOneMayDoIt;
208
- v = rb_funcall(v, id_to_r, 0);
209
- goto again;
214
+ d = RFLOAT_VALUE(v);
215
+ if (d != 0.0) {
216
+ v = rb_funcall(v, id_to_r, 0);
217
+ goto again;
218
+ }
219
+ if (1/d < 0.0) {
220
+ return VpCreateRbObject(prec, "-0");
221
+ }
222
+ return VpCreateRbObject(prec, "0");
223
+
210
224
  case T_RATIONAL:
211
225
  if (prec < 0) goto unable_to_coerce_without_prec;
212
226
 
@@ -788,7 +802,8 @@ BigDecimal_coerce(VALUE self, VALUE other)
788
802
  Real *b;
789
803
 
790
804
  if (RB_TYPE_P(other, T_FLOAT)) {
791
- obj = rb_assoc_new(other, BigDecimal_to_f(self));
805
+ GUARD_OBJ(b, GetVpValueWithPrec(other, DBL_DIG+1, 1));
806
+ obj = rb_assoc_new(ToValue(b), self);
792
807
  }
793
808
  else {
794
809
  if (RB_TYPE_P(other, T_RATIONAL)) {
@@ -1207,8 +1222,10 @@ BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r)
1207
1222
 
1208
1223
  *div = b;
1209
1224
  mx = a->Prec + vabs(a->exponent);
1210
- if (mx<b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent);
1211
- mx =(mx + 1) * VpBaseFig();
1225
+ if (mx < b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent);
1226
+ mx++; /* NOTE: An additional digit is needed for the compatibility to
1227
+ the version 1.2.1 and the former. */
1228
+ mx = (mx + 1) * VpBaseFig();
1212
1229
  GUARD_OBJ((*c), VpCreateRbObject(mx, "#0"));
1213
1230
  GUARD_OBJ((*res), VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0"));
1214
1231
  VpDivd(*c, *res, a, b);
@@ -2503,8 +2520,8 @@ BigDecimal_new(int argc, VALUE *argv)
2503
2520
  case T_RATIONAL:
2504
2521
  if (NIL_P(nFig)) {
2505
2522
  rb_raise(rb_eArgError,
2506
- "can't omit precision for a %s.",
2507
- rb_class2name(CLASS_OF(iniValue)));
2523
+ "can't omit precision for a %"PRIsVALUE".",
2524
+ rb_obj_class(iniValue));
2508
2525
  }
2509
2526
  return GetVpValueWithPrec(iniValue, mf, 1);
2510
2527
 
@@ -2517,7 +2534,7 @@ BigDecimal_new(int argc, VALUE *argv)
2517
2534
  return VpAlloc(mf, RSTRING_PTR(iniValue));
2518
2535
  }
2519
2536
 
2520
- /* See also BigDecimal::new */
2537
+ /* See also BigDecimal.new */
2521
2538
  static VALUE
2522
2539
  BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
2523
2540
  {
@@ -2905,8 +2922,8 @@ get_vp_value:
2905
2922
  RB_GC_GUARD(vn) = SSIZET2NUM(n);
2906
2923
  expo = VpExponent10(vx);
2907
2924
  if (expo < 0 || expo >= 3) {
2908
- char buf[16];
2909
- snprintf(buf, 16, "1E%"PRIdVALUE, -expo);
2925
+ char buf[DECIMAL_SIZE_OF_BITS(SIZEOF_VALUE * CHAR_BIT) + 4];
2926
+ snprintf(buf, sizeof(buf), "1E%"PRIdVALUE, -expo);
2910
2927
  x = BigDecimal_mult2(x, ToValue(VpCreateRbObject(1, buf)), vn);
2911
2928
  }
2912
2929
  else {
@@ -4175,6 +4192,7 @@ VpAddAbs(Real *a, Real *b, Real *c)
4175
4192
  a_pos = ap;
4176
4193
  b_pos = bp;
4177
4194
  c_pos = cp;
4195
+
4178
4196
  if (word_shift == (size_t)-1L) return 0; /* Overflow */
4179
4197
  if (b_pos == (size_t)-1L) goto Assign_a;
4180
4198
 
@@ -4182,14 +4200,14 @@ VpAddAbs(Real *a, Real *b, Real *c)
4182
4200
 
4183
4201
  /* Just assign the last few digits of b to c because a has no */
4184
4202
  /* corresponding digits to be added. */
4185
- while (b_pos + word_shift > a_pos) {
4186
- --c_pos;
4187
- if (b_pos > 0) {
4188
- c->frac[c_pos] = b->frac[--b_pos];
4203
+ if (b_pos > 0) {
4204
+ while (b_pos > 0 && b_pos + word_shift > a_pos) {
4205
+ c->frac[--c_pos] = b->frac[--b_pos];
4189
4206
  }
4190
- else {
4191
- --word_shift;
4192
- c->frac[c_pos] = 0;
4207
+ }
4208
+ if (b_pos == 0 && word_shift > a_pos) {
4209
+ while (word_shift-- > a_pos) {
4210
+ c->frac[--c_pos] = 0;
4193
4211
  }
4194
4212
  }
4195
4213
 
@@ -4285,16 +4303,16 @@ VpSubAbs(Real *a, Real *b, Real *c)
4285
4303
  /* each of the last few digits of the b because the a has no */
4286
4304
  /* corresponding digits to be subtracted. */
4287
4305
  if (b_pos + word_shift > a_pos) {
4288
- while (b_pos + word_shift > a_pos) {
4289
- --c_pos;
4290
- if (b_pos > 0) {
4291
- c->frac[c_pos] = BASE - b->frac[--b_pos] - borrow;
4292
- }
4293
- else {
4306
+ while (b_pos > 0 && b_pos + word_shift > a_pos) {
4307
+ c->frac[--c_pos] = BASE - b->frac[--b_pos] - borrow;
4308
+ borrow = 1;
4309
+ }
4310
+ if (b_pos == 0) {
4311
+ while (word_shift > a_pos) {
4294
4312
  --word_shift;
4295
- c->frac[c_pos] = BASE - borrow;
4313
+ c->frac[--c_pos] = BASE - borrow;
4314
+ borrow = 1;
4296
4315
  }
4297
- borrow = 1;
4298
4316
  }
4299
4317
  }
4300
4318
  /* Just assign the last few digits of a to c because b has no */
@@ -4366,12 +4384,19 @@ static size_t
4366
4384
  VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, BDIGIT *av, BDIGIT *bv)
4367
4385
  {
4368
4386
  size_t left_word, right_word, word_shift;
4387
+
4388
+ size_t const round_limit = (VpGetPrecLimit() + BASE_FIG - 1) / BASE_FIG;
4389
+
4390
+ assert(a->exponent >= b->expoennt);
4391
+
4369
4392
  c->frac[0] = 0;
4370
4393
  *av = *bv = 0;
4394
+
4371
4395
  word_shift = (a->exponent - b->exponent);
4372
4396
  left_word = b->Prec + word_shift;
4373
4397
  right_word = Max(a->Prec, left_word);
4374
4398
  left_word = c->MaxPrec - 1; /* -1 ... prepare for round up */
4399
+
4375
4400
  /*
4376
4401
  * check if 'round' is needed.
4377
4402
  */
@@ -4394,7 +4419,9 @@ VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos,
4394
4419
  * a_pos = |
4395
4420
  */
4396
4421
  *a_pos = left_word;
4397
- *av = a->frac[*a_pos]; /* av is 'A' shown in above. */
4422
+ if (*a_pos <= round_limit) {
4423
+ *av = a->frac[*a_pos]; /* av is 'A' shown in above. */
4424
+ }
4398
4425
  }
4399
4426
  else {
4400
4427
  /*
@@ -4413,7 +4440,9 @@ VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos,
4413
4440
  */
4414
4441
  if (c->MaxPrec >= word_shift + 1) {
4415
4442
  *b_pos = c->MaxPrec - word_shift - 1;
4416
- *bv = b->frac[*b_pos];
4443
+ if (*b_pos + word_shift <= round_limit) {
4444
+ *bv = b->frac[*b_pos];
4445
+ }
4417
4446
  }
4418
4447
  else {
4419
4448
  *b_pos = -1L;
@@ -4930,7 +4959,6 @@ Exit:
4930
4959
  return (int)val;
4931
4960
  }
4932
4961
 
4933
- #ifdef BIGDECIMAL_ENABLE_VPRINT
4934
4962
  /*
4935
4963
  * cntl_chr ... ASCIIZ Character, print control characters
4936
4964
  * Available control codes:
@@ -4941,10 +4969,11 @@ Exit:
4941
4969
  * Note: % must must not appear more than once
4942
4970
  * a ... VP variable to be printed
4943
4971
  */
4944
- VP_EXPORT int
4972
+ #ifdef BIGDECIMAL_ENABLE_VPRINT
4973
+ static int
4945
4974
  VPrint(FILE *fp, const char *cntl_chr, Real *a)
4946
4975
  {
4947
- size_t i, j, nc, nd, ZeroSup;
4976
+ size_t i, j, nc, nd, ZeroSup, sep = 10;
4948
4977
  BDIGIT m, e, nn;
4949
4978
 
4950
4979
  /* Check if NaN & Inf. */
@@ -4979,6 +5008,16 @@ VPrint(FILE *fp, const char *cntl_chr, Real *a)
4979
5008
  ++nc;
4980
5009
  }
4981
5010
  nc += fprintf(fp, "0.");
5011
+ switch (*(cntl_chr + j + 1)) {
5012
+ default:
5013
+ break;
5014
+
5015
+ case '0': case 'z':
5016
+ ZeroSup = 0;
5017
+ ++j;
5018
+ sep = cntl_chr[j] == 'z' ? RMPD_COMPONENT_FIGURES : 10;
5019
+ break;
5020
+ }
4982
5021
  for (i = 0; i < a->Prec; ++i) {
4983
5022
  m = BASE1;
4984
5023
  e = a->frac[i];
@@ -4991,7 +5030,7 @@ VPrint(FILE *fp, const char *cntl_chr, Real *a)
4991
5030
  ++nd;
4992
5031
  ZeroSup = 0; /* Set to print succeeding zeros */
4993
5032
  }
4994
- if (nd >= 10) { /* print ' ' after every 10 digits */
5033
+ if (nd >= sep) { /* print ' ' after every 10 digits */
4995
5034
  nd = 0;
4996
5035
  nc += fprintf(fp, " ");
4997
5036
  }
@@ -5000,6 +5039,7 @@ VPrint(FILE *fp, const char *cntl_chr, Real *a)
5000
5039
  }
5001
5040
  }
5002
5041
  nc += fprintf(fp, "E%"PRIdSIZE, VpExponent10(a));
5042
+ nc += fprintf(fp, " (%"PRIdVALUE", %lu, %lu)", a->exponent, a->Prec, a->MaxPrec);
5003
5043
  }
5004
5044
  else {
5005
5045
  nc += fprintf(fp, "0.0");
@@ -5033,9 +5073,10 @@ VPrint(FILE *fp, const char *cntl_chr, Real *a)
5033
5073
  }
5034
5074
  j++;
5035
5075
  }
5076
+
5036
5077
  return (int)nc;
5037
5078
  }
5038
- #endif /* BIGDECIMAL_ENABLE_VPRINT */
5079
+ #endif
5039
5080
 
5040
5081
  static void
5041
5082
  VpFormatSt(char *psz, size_t fFmt)
data/bigdecimal.gemspec CHANGED
@@ -1,9 +1,11 @@
1
1
  # -*- ruby -*-
2
- _VERSION = "1.2.3"
2
+ _VERSION = "1.2.4"
3
+ date = %w$Date:: $[1]
3
4
 
4
5
  Gem::Specification.new do |s|
5
6
  s.name = "bigdecimal"
6
7
  s.version = _VERSION
8
+ s.date = date
7
9
  s.summary = "Arbitrary-precision decimal floating-point number library."
8
10
  s.homepage = "http://www.ruby-lang.org"
9
11
  s.email = "mrkn@mrkn.jp"
data/bigdecimal.h CHANGED
@@ -310,7 +310,6 @@ VP_EXPORT Real *VpOne(void);
310
310
  #define VpExponent(a) (a->exponent)
311
311
  #ifdef BIGDECIMAL_DEBUG
312
312
  int VpVarCheck(Real * v);
313
- VP_EXPORT int VPrint(FILE *fp,const char *cntl_chr,Real *a);
314
313
  #endif /* BIGDECIMAL_DEBUG */
315
314
 
316
315
  #if defined(__cplusplus)
data/depend CHANGED
@@ -1 +1 @@
1
- bigdecimal.o: bigdecimal.c bigdecimal.h $(HDRS) $(ruby_headers)
1
+ bigdecimal.o: bigdecimal.c bigdecimal.h $(HDRS) $(ruby_headers) $(hdrdir)/ruby/util.h
@@ -75,7 +75,7 @@ module Jacobian
75
75
  # Computes the Jacobian of f at x. fx is the value of f at x.
76
76
  def jacobian(f,fx,x)
77
77
  n = x.size
78
- dfdx = Array::new(n*n)
78
+ dfdx = Array.new(n*n)
79
79
  for i in 0...n do
80
80
  df = dfdxi(f,fx,x,i)
81
81
  for j in 0...n do
@@ -36,8 +36,8 @@ module BigMath
36
36
  # Computes the square root of +decimal+ to the specified number of digits of
37
37
  # precision, +numeric+.
38
38
  #
39
- # BigMath::sqrt(BigDecimal.new('2'), 16).to_s
40
- # #=> "0.14142135623730950488016887242096975E1"
39
+ # BigMath.sqrt(BigDecimal.new('2'), 16).to_s
40
+ # #=> "0.1414213562373095048801688724E1"
41
41
  #
42
42
  def sqrt(x, prec)
43
43
  x.sqrt(prec)
@@ -51,7 +51,7 @@ module BigMath
51
51
  #
52
52
  # If +decimal+ is Infinity or NaN, returns NaN.
53
53
  #
54
- # BigMath::sin(BigMath::PI(5)/4, 5).to_s
54
+ # BigMath.sin(BigMath.PI(5)/4, 5).to_s
55
55
  # #=> "0.70710678118654752440082036563292800375E0"
56
56
  #
57
57
  def sin(x, prec)
@@ -95,7 +95,7 @@ module BigMath
95
95
  #
96
96
  # If +decimal+ is Infinity or NaN, returns NaN.
97
97
  #
98
- # BigMath::cos(BigMath::PI(4), 16).to_s
98
+ # BigMath.cos(BigMath.PI(4), 16).to_s
99
99
  # #=> "-0.999999999999999999999999999999856613163740061349E0"
100
100
  #
101
101
  def cos(x, prec)
@@ -139,7 +139,7 @@ module BigMath
139
139
  #
140
140
  # If +decimal+ is NaN, returns NaN.
141
141
  #
142
- # BigMath::atan(BigDecimal.new('-1'), 16).to_s
142
+ # BigMath.atan(BigDecimal.new('-1'), 16).to_s
143
143
  # #=> "-0.785398163397448309615660845819878471907514682065E0"
144
144
  #
145
145
  def atan(x, prec)
@@ -176,7 +176,7 @@ module BigMath
176
176
  # Computes the value of pi to the specified number of digits of precision,
177
177
  # +numeric+.
178
178
  #
179
- # BigMath::PI(10).to_s
179
+ # BigMath.PI(10).to_s
180
180
  # #=> "0.3141592653589793238462643388813853786957412E1"
181
181
  #
182
182
  def PI(prec)
@@ -221,7 +221,7 @@ module BigMath
221
221
  # Computes e (the base of natural logarithms) to the specified number of
222
222
  # digits of precision, +numeric+.
223
223
  #
224
- # BigMath::E(10).to_s
224
+ # BigMath.E(10).to_s
225
225
  # #=> "0.271828182845904523536028752390026306410273E1"
226
226
  #
227
227
  def E(prec)
data/sample/linear.rb CHANGED
@@ -16,8 +16,8 @@ require "bigdecimal/ludcmp"
16
16
 
17
17
  #
18
18
  # NOTE:
19
- # Change following BigDecimal::limit() if needed.
20
- BigDecimal::limit(100)
19
+ # Change following BigDecimal.limit() if needed.
20
+ BigDecimal.limit(100)
21
21
  #
22
22
 
23
23
  include LUSolve
@@ -27,8 +27,8 @@ def rd_order(na)
27
27
  end
28
28
 
29
29
  na = ARGV.size
30
- zero = BigDecimal::new("0.0")
31
- one = BigDecimal::new("1.0")
30
+ zero = BigDecimal.new("0.0")
31
+ one = BigDecimal.new("1.0")
32
32
 
33
33
  while (n=rd_order(na))>0
34
34
  a = []
@@ -40,10 +40,10 @@ while (n=rd_order(na))>0
40
40
  for i in 0...n do
41
41
  for j in 0...n do
42
42
  printf("A[%d,%d]? ",i,j); s = ARGF.gets
43
- a << BigDecimal::new(s);
44
- as << BigDecimal::new(s);
43
+ a << BigDecimal.new(s);
44
+ as << BigDecimal.new(s);
45
45
  end
46
- printf("Contatant vector element b[%d] ? ",i); b << BigDecimal::new(ARGF.gets);
46
+ printf("Contatant vector element b[%d] ? ",i); b << BigDecimal.new(ARGF.gets);
47
47
  end
48
48
  else
49
49
  # Read data from specified file.
@@ -53,10 +53,10 @@ while (n=rd_order(na))>0
53
53
  printf("%d) %s",i,s)
54
54
  s = s.split
55
55
  for j in 0...n do
56
- a << BigDecimal::new(s[j]);
57
- as << BigDecimal::new(s[j]);
56
+ a << BigDecimal.new(s[j]);
57
+ as << BigDecimal.new(s[j]);
58
58
  end
59
- b << BigDecimal::new(s[n]);
59
+ b << BigDecimal.new(s[n]);
60
60
  end
61
61
  end
62
62
  x = lusolve(a,b,ludecomp(a,n,zero,one),zero)
data/sample/nlsolve.rb CHANGED
@@ -11,11 +11,11 @@ include Newton
11
11
 
12
12
  class Function # :nodoc: all
13
13
  def initialize()
14
- @zero = BigDecimal::new("0.0")
15
- @one = BigDecimal::new("1.0")
16
- @two = BigDecimal::new("2.0")
17
- @ten = BigDecimal::new("10.0")
18
- @eps = BigDecimal::new("1.0e-16")
14
+ @zero = BigDecimal.new("0.0")
15
+ @one = BigDecimal.new("1.0")
16
+ @two = BigDecimal.new("2.0")
17
+ @ten = BigDecimal.new("10.0")
18
+ @eps = BigDecimal.new("1.0e-16")
19
19
  end
20
20
  def zero;@zero;end
21
21
  def one ;@one ;end
@@ -31,8 +31,9 @@ class Function # :nodoc: all
31
31
  f
32
32
  end
33
33
  end
34
- f = BigDecimal::limit(100)
35
- f = Function.new
36
- x = [f.zero,f.zero] # Initial values
37
- n = nlsolve(f,x)
38
- p x
34
+
35
+ f = BigDecimal.limit(100)
36
+ f = Function.new
37
+ x = [f.zero,f.zero] # Initial values
38
+ n = nlsolve(f,x)
39
+ p x
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bigdecimal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenta Murata
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-11-25 00:00:00.000000000 Z
13
+ date: 2014-01-13 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: This library provides arbitrary-precision decimal floating-point number
16
16
  class.
@@ -53,7 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
53
53
  version: '0'
54
54
  requirements: []
55
55
  rubyforge_project:
56
- rubygems_version: 2.2.0.preview.2
56
+ rubygems_version: 2.2.1
57
57
  signing_key:
58
58
  specification_version: 4
59
59
  summary: Arbitrary-precision decimal floating-point number library.