bigdecimal 1.2.3 → 1.2.4

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.
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.