bigdecimal 1.3.5 → 1.4.0.pre.20181121a

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
  SHA256:
3
- metadata.gz: 73213efa446db0aae9dc184b48255acbd670ac6dc1fff31c8e6361bba7288103
4
- data.tar.gz: e092ee3be9410d2b888690e5c88b1c7f4e66307f2b01592512ef33f9cfb6ab00
3
+ metadata.gz: 99a815d308c0d5b1b7322467c01377b875f93c77d4fa889bc111cc2cf3d65a5f
4
+ data.tar.gz: 9d678c52b52993a8b095861bf042f7032058bd5cb382dc5825c5b1095d5ac11f
5
5
  SHA512:
6
- metadata.gz: d314519b706ac6ddb2e8c71723138109ba09d1f399c150b0b1095ff5081b1fd5b96aef5ff4e896ba802b6a6dcb6f220dd41f058cb5796d469b3096b885d7459f
7
- data.tar.gz: daadfc6a6d520ac15847cd57c75407b87a4884055f6ad24f42ad96194aa530d0461303a6c305790aaeea8ea98f93cca4be81e7143bcc27617061711ae22a914a
6
+ metadata.gz: 76c9776bec807971122e42d5f3a8e7e40c5105d0d49ba35349f6c6ba1b9fb2310e13d5f33ab1fe98b9d40424a5ffd55b6300c774fb29a0268b39b269cd204ba9
7
+ data.tar.gz: 66a1ae81965bb1276b990c8dbd622fd7ee01f66590abdbb9c724c30dec0c4726573b92044d0cb97128c4262e579b3b0863489219ae63a6edc93db46bb1b327ee
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- bigdecimal_version = '1.3.5'
3
+ bigdecimal_version = '1.4.0.pre.20181121a'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "bigdecimal"
@@ -14,13 +14,15 @@ Gem::Specification.new do |s|
14
14
  s.license = "ruby"
15
15
 
16
16
  s.require_paths = %w[lib]
17
- s.extensions = %w[ext/bigdecimal/extconf.rb]
17
+ s.extensions = %w[ext/bigdecimal/extconf.rb ext/bigdecimal/util/extconf.rb]
18
18
  s.files = %w[
19
19
  bigdecimal.gemspec
20
20
  ext/bigdecimal/bigdecimal.c
21
21
  ext/bigdecimal/bigdecimal.h
22
22
  ext/bigdecimal/depend
23
23
  ext/bigdecimal/extconf.rb
24
+ ext/bigdecimal/util/extconf.rb
25
+ ext/bigdecimal/util/util.c
24
26
  lib/bigdecimal/jacobian.rb
25
27
  lib/bigdecimal/ludcmp.rb
26
28
  lib/bigdecimal/math.rb
@@ -31,6 +33,8 @@ Gem::Specification.new do |s|
31
33
  sample/pi.rb
32
34
  ]
33
35
 
36
+ s.required_ruby_version = Gem::Requirement.new(">= 2.3.0".freeze)
37
+
34
38
  s.add_development_dependency "rake", "~> 10.0"
35
39
  s.add_development_dependency "rake-compiler", ">= 0.9"
36
40
  s.add_development_dependency "rake-compiler-dock", ">= 0.6.1"
@@ -135,24 +135,6 @@ rb_rational_den(VALUE rat)
135
135
  */
136
136
  #define DoSomeOne(x,y,f) rb_num_coerce_bin(x,y,f)
137
137
 
138
- /*
139
- * Returns the BigDecimal version number.
140
- */
141
- static VALUE
142
- BigDecimal_version(VALUE self)
143
- {
144
- /*
145
- * 1.0.0: Ruby 1.8.0
146
- * 1.0.1: Ruby 1.8.1
147
- * 1.1.0: Ruby 1.9.3
148
- */
149
- #ifndef RUBY_BIGDECIMAL_VERSION
150
- # error RUBY_BIGDECIMAL_VERSION is not defined
151
- #endif
152
- rb_warning("BigDecimal.ver is deprecated; use BigDecimal::VERSION instead.");
153
- return rb_str_new2(RUBY_BIGDECIMAL_VERSION);
154
- }
155
-
156
138
  /*
157
139
  * VP routines used in BigDecimal part
158
140
  */
@@ -664,9 +646,10 @@ VP_EXPORT Real *
664
646
  VpNewRbClass(size_t mx, const char *str, VALUE klass)
665
647
  {
666
648
  VALUE obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, 0);
667
- Real *pv = VpAlloc(mx,str);
649
+ Real *pv = VpAlloc(mx, str, 1);
668
650
  RTYPEDDATA_DATA(obj) = pv;
669
651
  pv->obj = obj;
652
+ RB_OBJ_FREEZE(obj);
670
653
  return pv;
671
654
  }
672
655
 
@@ -2165,15 +2148,10 @@ BigDecimal_exponent(VALUE self)
2165
2148
  return INT2NUM(e);
2166
2149
  }
2167
2150
 
2168
- /* Returns debugging information about the value as a string of comma-separated
2169
- * values in angle brackets with a leading #:
2151
+ /* Returns a string representation of self.
2170
2152
  *
2171
2153
  * BigDecimal("1234.5678").inspect
2172
2154
  * #=> "0.12345678e4"
2173
- *
2174
- * The first part is the address, the second is the value as a string, and
2175
- * the final part ss(mm) is the current number of significant digits and the
2176
- * maximum number of significant digits, respectively.
2177
2155
  */
2178
2156
  static VALUE
2179
2157
  BigDecimal_inspect(VALUE self)
@@ -2335,7 +2313,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
2335
2313
  n = NIL_P(prec) ? (ssize_t)(x->Prec*VpBaseFig()) : NUM2SSIZET(prec);
2336
2314
 
2337
2315
  if (VpIsNaN(x)) {
2338
- y = VpCreateRbObject(n, "0#");
2316
+ y = VpCreateRbObject(n, "0");
2339
2317
  RB_GC_GUARD(y->obj);
2340
2318
  VpSetNaN(y);
2341
2319
  return ToValue(y);
@@ -2459,7 +2437,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
2459
2437
  }
2460
2438
  }
2461
2439
  else {
2462
- y = VpCreateRbObject(n, "0#");
2440
+ y = VpCreateRbObject(n, "0");
2463
2441
  if (BIGDECIMAL_NEGATIVE_P(x)) {
2464
2442
  if (is_integer(vexp)) {
2465
2443
  if (is_even(vexp)) {
@@ -2492,7 +2470,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
2492
2470
  }
2493
2471
  else if (RTEST(rb_funcall(abs_value, '<', 1, INT2FIX(1)))) {
2494
2472
  if (is_negative(vexp)) {
2495
- y = VpCreateRbObject(n, "0#");
2473
+ y = VpCreateRbObject(n, "0");
2496
2474
  if (is_even(vexp)) {
2497
2475
  VpSetInf(y, VpGetSign(x));
2498
2476
  }
@@ -2510,7 +2488,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
2510
2488
  }
2511
2489
  else {
2512
2490
  if (is_positive(vexp)) {
2513
- y = VpCreateRbObject(n, "0#");
2491
+ y = VpCreateRbObject(n, "0");
2514
2492
  if (is_even(vexp)) {
2515
2493
  VpSetInf(y, VpGetSign(x));
2516
2494
  }
@@ -2560,52 +2538,8 @@ BigDecimal_power_op(VALUE self, VALUE exp)
2560
2538
  return BigDecimal_power(1, &exp, self);
2561
2539
  }
2562
2540
 
2563
- static VALUE
2564
- BigDecimal_s_allocate(VALUE klass)
2565
- {
2566
- return VpNewRbClass(0, NULL, klass)->obj;
2567
- }
2568
-
2569
2541
  static Real *BigDecimal_new(int argc, VALUE *argv);
2570
2542
 
2571
- /* call-seq:
2572
- * new(initial, digits)
2573
- *
2574
- * Create a new BigDecimal object.
2575
- *
2576
- * initial:: The initial value, as an Integer, a Float, a Rational,
2577
- * a BigDecimal, or a String.
2578
- *
2579
- * If it is a String, spaces are ignored and unrecognized characters
2580
- * terminate the value.
2581
- *
2582
- * digits:: The number of significant digits, as an Integer. If omitted or 0,
2583
- * the number of significant digits is determined from the initial
2584
- * value.
2585
- *
2586
- * The actual number of significant digits used in computation is usually
2587
- * larger than the specified number.
2588
- *
2589
- * ==== Exceptions
2590
- *
2591
- * TypeError:: If the +initial+ type is neither Integer, Float,
2592
- * Rational, nor BigDecimal, this exception is raised.
2593
- *
2594
- * TypeError:: If the +digits+ is not an Integer, this exception is raised.
2595
- *
2596
- * ArgumentError:: If +initial+ is a Float, and the +digits+ is larger than
2597
- * Float::DIG + 1, this exception is raised.
2598
- *
2599
- * ArgumentError:: If the +initial+ is a Float or Rational, and the +digits+
2600
- * value is omitted, this exception is raised.
2601
- */
2602
- static VALUE
2603
- BigDecimal_s_new(int argc, VALUE *argv, VALUE self)
2604
- {
2605
- rb_warning("BigDecimal.new is deprecated; use Kernel.BigDecimal method instead.");
2606
- return rb_call_super(argc, argv);
2607
- }
2608
-
2609
2543
  static VALUE
2610
2544
  BigDecimal_initialize(int argc, VALUE *argv, VALUE self)
2611
2545
  {
@@ -2700,10 +2634,40 @@ BigDecimal_new(int argc, VALUE *argv)
2700
2634
  break;
2701
2635
  }
2702
2636
  StringValueCStr(iniValue);
2703
- return VpAlloc(mf, RSTRING_PTR(iniValue));
2637
+ return VpAlloc(mf, RSTRING_PTR(iniValue), 1);
2704
2638
  }
2705
2639
 
2706
- /* See also BigDecimal.new */
2640
+ /* call-seq:
2641
+ * BigDecimal(initial, digits)
2642
+ *
2643
+ * Create a new BigDecimal object.
2644
+ *
2645
+ * initial:: The initial value, as an Integer, a Float, a Rational,
2646
+ * a BigDecimal, or a String.
2647
+ *
2648
+ * If it is a String, spaces are ignored and unrecognized characters
2649
+ * terminate the value.
2650
+ *
2651
+ * digits:: The number of significant digits, as an Integer. If omitted or 0,
2652
+ * the number of significant digits is determined from the initial
2653
+ * value.
2654
+ *
2655
+ * The actual number of significant digits used in computation is usually
2656
+ * larger than the specified number.
2657
+ *
2658
+ * ==== Exceptions
2659
+ *
2660
+ * TypeError:: If the +initial+ type is neither Integer, Float,
2661
+ * Rational, nor BigDecimal, this exception is raised.
2662
+ *
2663
+ * TypeError:: If the +digits+ is not an Integer, this exception is raised.
2664
+ *
2665
+ * ArgumentError:: If +initial+ is a Float, and the +digits+ is larger than
2666
+ * Float::DIG + 1, this exception is raised.
2667
+ *
2668
+ * ArgumentError:: If the +initial+ is a Float or Rational, and the +digits+
2669
+ * value is omitted, this exception is raised.
2670
+ */
2707
2671
  static VALUE
2708
2672
  BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
2709
2673
  {
@@ -2715,6 +2679,7 @@ BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
2715
2679
  GUARD_OBJ(pv, BigDecimal_new(argc, argv));
2716
2680
  if (ToValue(pv)) pv = VpCopy(NULL, pv);
2717
2681
  RTYPEDDATA_DATA(obj) = pv;
2682
+ RB_OBJ_FREEZE(obj);
2718
2683
  return pv->obj = obj;
2719
2684
  }
2720
2685
 
@@ -3138,6 +3103,21 @@ get_vp_value:
3138
3103
  return y;
3139
3104
  }
3140
3105
 
3106
+ VALUE
3107
+ rmpd_util_str_to_d(VALUE str)
3108
+ {
3109
+ ENTER(1);
3110
+ char const *c_str;
3111
+ Real *pv;
3112
+ VALUE obj;
3113
+
3114
+ c_str = StringValueCStr(str);
3115
+ GUARD_OBJ(pv, VpAlloc(0, c_str, 0));
3116
+ obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, pv);
3117
+ RB_OBJ_FREEZE(obj);
3118
+ return obj;
3119
+ }
3120
+
3141
3121
  /* Document-class: BigDecimal
3142
3122
  * BigDecimal provides arbitrary-precision floating point decimal arithmetic.
3143
3123
  *
@@ -3277,18 +3257,17 @@ Init_bigdecimal(void)
3277
3257
 
3278
3258
  /* Class and method registration */
3279
3259
  rb_cBigDecimal = rb_define_class("BigDecimal", rb_cNumeric);
3280
- rb_define_alloc_func(rb_cBigDecimal, BigDecimal_s_allocate);
3281
3260
 
3282
3261
  /* Global function */
3283
3262
  rb_define_global_function("BigDecimal", BigDecimal_global_new, -1);
3284
3263
 
3285
3264
  /* Class methods */
3286
- rb_define_singleton_method(rb_cBigDecimal, "new", BigDecimal_s_new, -1);
3265
+ rb_undef_method(CLASS_OF(rb_cBigDecimal), "allocate");
3266
+ rb_undef_method(CLASS_OF(rb_cBigDecimal), "new");
3287
3267
  rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1);
3288
3268
  rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
3289
3269
  rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
3290
3270
  rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 1);
3291
- rb_define_singleton_method(rb_cBigDecimal, "ver", BigDecimal_version, 0);
3292
3271
 
3293
3272
  rb_define_singleton_method(rb_cBigDecimal, "save_exception_mode", BigDecimal_save_exception_mode, 0);
3294
3273
  rb_define_singleton_method(rb_cBigDecimal, "save_rounding_mode", BigDecimal_save_rounding_mode, 0);
@@ -3745,25 +3724,19 @@ One(void)
3745
3724
  VP_EXPORT double
3746
3725
  VpGetDoubleNaN(void) /* Returns the value of NaN */
3747
3726
  {
3748
- static double fNaN = 0.0;
3749
- if (fNaN == 0.0) fNaN = Zero()/Zero();
3750
- return fNaN;
3727
+ return nan("");
3751
3728
  }
3752
3729
 
3753
3730
  VP_EXPORT double
3754
3731
  VpGetDoublePosInf(void) /* Returns the value of +Infinity */
3755
3732
  {
3756
- static double fInf = 0.0;
3757
- if (fInf == 0.0) fInf = One()/Zero();
3758
- return fInf;
3733
+ return HUGE_VAL;
3759
3734
  }
3760
3735
 
3761
3736
  VP_EXPORT double
3762
3737
  VpGetDoubleNegInf(void) /* Returns the value of -Infinity */
3763
3738
  {
3764
- static double fInf = 0.0;
3765
- if (fInf == 0.0) fInf = -(One()/Zero());
3766
- return fInf;
3739
+ return -HUGE_VAL;
3767
3740
  }
3768
3741
 
3769
3742
  VP_EXPORT double
@@ -3964,8 +3937,8 @@ VpInit(BDIGIT BaseVal)
3964
3937
  VpGetDoubleNegZero();
3965
3938
 
3966
3939
  /* Allocates Vp constants. */
3967
- VpConstOne = VpAlloc(1UL, "1");
3968
- VpPt5 = VpAlloc(1UL, ".5");
3940
+ VpConstOne = VpAlloc(1UL, "1", 1);
3941
+ VpPt5 = VpAlloc(1UL, ".5", 1);
3969
3942
 
3970
3943
  #ifdef BIGDECIMAL_DEBUG
3971
3944
  gnAlloc = 0;
@@ -4029,6 +4002,52 @@ overflow:
4029
4002
  return VpException(VP_EXCEPTION_OVERFLOW, "Exponent overflow", 0);
4030
4003
  }
4031
4004
 
4005
+ Real *
4006
+ rmpd_parse_special_string(const char *str)
4007
+ {
4008
+ static const struct {
4009
+ const char *str;
4010
+ size_t len;
4011
+ int sign;
4012
+ } table[] = {
4013
+ { SZ_INF, sizeof(SZ_INF) - 1, VP_SIGN_POSITIVE_INFINITE },
4014
+ { SZ_PINF, sizeof(SZ_PINF) - 1, VP_SIGN_POSITIVE_INFINITE },
4015
+ { SZ_NINF, sizeof(SZ_NINF) - 1, VP_SIGN_NEGATIVE_INFINITE },
4016
+ { SZ_NaN, sizeof(SZ_NaN) - 1, VP_SIGN_NaN }
4017
+ };
4018
+ static const size_t table_length = sizeof(table) / sizeof(table[0]);
4019
+ size_t i;
4020
+
4021
+ for (i = 0; i < table_length; ++i) {
4022
+ const char *p;
4023
+ if (strncmp(str, table[i].str, table[i].len) != 0) {
4024
+ continue;
4025
+ }
4026
+
4027
+ p = str + table[i].len;
4028
+ while (*p && ISSPACE(*p)) ++p;
4029
+ if (*p == '\0') {
4030
+ Real *vp = VpAllocReal(1);
4031
+ vp->MaxPrec = 1;
4032
+ switch (table[i].sign) {
4033
+ default:
4034
+ UNREACHABLE; break;
4035
+ case VP_SIGN_POSITIVE_INFINITE:
4036
+ VpSetPosInf(vp);
4037
+ return vp;
4038
+ case VP_SIGN_NEGATIVE_INFINITE:
4039
+ VpSetNegInf(vp);
4040
+ return vp;
4041
+ case VP_SIGN_NaN:
4042
+ VpSetNaN(vp);
4043
+ return vp;
4044
+ }
4045
+ }
4046
+ }
4047
+
4048
+ return NULL;
4049
+ }
4050
+
4032
4051
  /*
4033
4052
  * Allocates variable.
4034
4053
  * [Input]
@@ -4043,10 +4062,10 @@ overflow:
4043
4062
  * NULL be returned if memory allocation is failed,or any error.
4044
4063
  */
4045
4064
  VP_EXPORT Real *
4046
- VpAlloc(size_t mx, const char *szVal)
4065
+ VpAlloc(size_t mx, const char *szVal, int strict_p)
4047
4066
  {
4048
4067
  const char *orig_szVal = szVal;
4049
- size_t i, ni, ipn, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc;
4068
+ size_t i, j, ni, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc;
4050
4069
  char v, *psz;
4051
4070
  int sign=1;
4052
4071
  Real *vp = NULL;
@@ -4057,7 +4076,10 @@ VpAlloc(size_t mx, const char *szVal)
4057
4076
  if (mx == 0) ++mx;
4058
4077
 
4059
4078
  if (szVal) {
4079
+ /* Skipping leading spaces */
4060
4080
  while (ISSPACE(*szVal)) szVal++;
4081
+
4082
+ /* Processing the leading one `#` */
4061
4083
  if (*szVal != '#') {
4062
4084
  if (mf) {
4063
4085
  mf = (mf + BASE_FIG - 1) / BASE_FIG + 2; /* Needs 1 more for div */
@@ -4071,6 +4093,7 @@ VpAlloc(size_t mx, const char *szVal)
4071
4093
  }
4072
4094
  }
4073
4095
  else {
4096
+ return_zero:
4074
4097
  /* necessary to be able to store */
4075
4098
  /* at least mx digits. */
4076
4099
  /* szVal==NULL ==> allocate zero value. */
@@ -4081,105 +4104,166 @@ VpAlloc(size_t mx, const char *szVal)
4081
4104
  return vp;
4082
4105
  }
4083
4106
 
4084
- /* Skip all '_' after digit: 2006-6-30 */
4085
- ni = 0;
4107
+ /* Check on Inf & NaN */
4108
+ if ((vp = rmpd_parse_special_string(szVal)) != NULL) {
4109
+ return vp;
4110
+ }
4111
+
4112
+ /* Scanning digits */
4113
+
4114
+ /* A buffer for keeping scanned digits */
4086
4115
  buf = rb_str_tmp_new(strlen(szVal) + 1);
4087
4116
  psz = RSTRING_PTR(buf);
4088
- i = 0;
4089
- ipn = 0;
4090
- while ((psz[i] = szVal[ipn]) != 0) {
4091
- if (ISSPACE(psz[i])) {
4092
- psz[i] = 0;
4117
+
4118
+ /* cursor: i for psz, and j for szVal */
4119
+ i = j = 0;
4120
+
4121
+ /* Scanning: sign part */
4122
+ v = psz[i] = szVal[j];
4123
+ if ((v == '-') || (v == '+')) {
4124
+ sign = -(v == '-');
4125
+ ++i;
4126
+ ++j;
4127
+ }
4128
+
4129
+ /* Scanning: integer part */
4130
+ ni = 0; /* number of digits in the integer part */
4131
+ while ((v = psz[i] = szVal[j]) != '\0') {
4132
+ if (!strict_p && ISSPACE(v)) {
4133
+ v = psz[i] = '\0';
4093
4134
  break;
4094
4135
  }
4095
- if (ISDIGIT(psz[i])) ++ni;
4096
- if (psz[i] == '_') {
4136
+ if (v == '_') {
4097
4137
  if (ni > 0) {
4098
- ipn++;
4099
- continue;
4138
+ v = szVal[j+1];
4139
+ if (v == '\0' || ISSPACE(v) || ISDIGIT(v)) {
4140
+ ++j;
4141
+ continue;
4142
+ }
4143
+ if (!strict_p) {
4144
+ v = psz[i] = '\0';
4145
+ break;
4146
+ }
4100
4147
  }
4101
- psz[i] = 0;
4148
+ goto invalid_value;
4149
+ }
4150
+ if (!ISDIGIT(v)) {
4102
4151
  break;
4103
4152
  }
4153
+ ++ni;
4104
4154
  ++i;
4105
- ++ipn;
4155
+ ++j;
4106
4156
  }
4107
- szVal = psz;
4108
4157
 
4109
- /* Check on Inf & NaN */
4110
- if (StrCmp(szVal, SZ_PINF) == 0 || StrCmp(szVal, SZ_INF) == 0 ) {
4111
- vp = VpAllocReal(1);
4112
- vp->MaxPrec = 1; /* set max precision */
4113
- VpSetPosInf(vp);
4114
- return vp;
4115
- }
4116
- if (StrCmp(szVal, SZ_NINF) == 0) {
4117
- vp = VpAllocReal(1);
4118
- vp->MaxPrec = 1; /* set max precision */
4119
- VpSetNegInf(vp);
4120
- return vp;
4121
- }
4122
- if (StrCmp(szVal, SZ_NaN) == 0) {
4123
- vp = VpAllocReal(1);
4124
- vp->MaxPrec = 1; /* set max precision */
4125
- VpSetNaN(vp);
4126
- return vp;
4127
- }
4128
-
4129
- /* check on number szVal[] */
4130
- ipn = i = 0;
4131
- if (szVal[i] == '-') { sign=-1; ++i; }
4132
- else if (szVal[i] == '+') ++i;
4133
- /* Skip digits */
4134
- ni = 0; /* digits in mantissa */
4135
- while ((v = szVal[i]) != 0) {
4136
- if (!ISDIGIT(v)) break;
4137
- ++i;
4138
- ++ni;
4139
- }
4140
- nf = 0;
4141
- ipf = 0;
4142
- ipe = 0;
4143
- ne = 0;
4158
+ /* Scanning: fractional part */
4159
+ nf = 0; /* number of digits in the fractional part */
4160
+ ne = 0; /* number of digits in the exponential part */
4161
+ ipf = 0; /* index of the beginning of the fractional part */
4162
+ ipe = 0; /* index of the beginning of the exponential part */
4144
4163
  dot_seen = 0;
4145
4164
  exp_seen = 0;
4146
- if (v) {
4147
- /* other than digit nor \0 */
4148
- if (szVal[i] == '.') { /* xxx. */
4165
+
4166
+ if (v != '\0') {
4167
+ /* Scanning fractional part */
4168
+ if ((psz[i] = szVal[j]) == '.') {
4149
4169
  dot_seen = 1;
4150
4170
  ++i;
4171
+ ++j;
4151
4172
  ipf = i;
4152
- while ((v = szVal[i]) != 0) { /* get fraction part. */
4173
+ while ((v = psz[i] = szVal[j]) != '\0') {
4174
+ if (!strict_p && ISSPACE(v)) {
4175
+ v = psz[i] = '\0';
4176
+ break;
4177
+ }
4178
+ if (v == '_') {
4179
+ if (nf > 0 && ISDIGIT(szVal[j+1])) {
4180
+ ++j;
4181
+ continue;
4182
+ }
4183
+ if (!strict_p) {
4184
+ v = psz[i] = '\0';
4185
+ if (nf == 0) {
4186
+ dot_seen = 0;
4187
+ }
4188
+ break;
4189
+ }
4190
+ goto invalid_value;
4191
+ }
4153
4192
  if (!ISDIGIT(v)) break;
4154
4193
  ++i;
4194
+ ++j;
4155
4195
  ++nf;
4156
4196
  }
4157
4197
  }
4158
- ipe = 0; /* Exponent */
4159
-
4160
- switch (szVal[i]) {
4161
- case '\0':
4162
- break;
4163
- case 'e': case 'E':
4164
- case 'd': case 'D':
4165
- exp_seen = 1;
4166
- ++i;
4167
- ipe = i;
4168
- v = szVal[i];
4169
- if ((v == '-') || (v == '+')) ++i;
4170
- while ((v=szVal[i]) != 0) {
4171
- if (!ISDIGIT(v)) break;
4198
+
4199
+ /* Scanning exponential part */
4200
+ if (v != '\0') {
4201
+ switch ((psz[i] = szVal[j])) {
4202
+ case '\0':
4203
+ break;
4204
+ case 'e': case 'E':
4205
+ case 'd': case 'D':
4206
+ exp_seen = 1;
4172
4207
  ++i;
4173
- ++ne;
4174
- }
4175
- break;
4176
- default:
4177
- break;
4208
+ ++j;
4209
+ ipe = i;
4210
+ v = psz[i] = szVal[j];
4211
+ if ((v == '-') || (v == '+')) {
4212
+ ++i;
4213
+ ++j;
4214
+ }
4215
+ while ((v = psz[i] = szVal[j]) != '\0') {
4216
+ if (!strict_p && ISSPACE(v)) {
4217
+ v = psz[i] = '\0';
4218
+ break;
4219
+ }
4220
+ if (v == '_') {
4221
+ if (ne > 0 && ISDIGIT(szVal[j+1])) {
4222
+ ++j;
4223
+ continue;
4224
+ }
4225
+ if (!strict_p) {
4226
+ v = psz[i] = '\0';
4227
+ if (ne == 0) {
4228
+ exp_seen = 0;
4229
+ }
4230
+ break;
4231
+ }
4232
+ goto invalid_value;
4233
+ }
4234
+ if (!ISDIGIT(v)) break;
4235
+ ++i;
4236
+ ++j;
4237
+ ++ne;
4238
+ }
4239
+ break;
4240
+ default:
4241
+ break;
4242
+ }
4243
+ }
4244
+
4245
+ if (v != '\0') {
4246
+ /* Scanning trailing spaces */
4247
+ while (ISSPACE(szVal[j])) ++j;
4248
+
4249
+ /* Invalid character */
4250
+ if (szVal[j]) {
4251
+ goto invalid_value;
4252
+ }
4178
4253
  }
4179
4254
  }
4255
+
4256
+ psz[i] = '\0';
4257
+
4180
4258
  if (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0)) {
4181
- VALUE str = rb_str_new2(orig_szVal);
4182
- rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str);
4259
+ VALUE str;
4260
+ invalid_value:
4261
+ if (!strict_p) {
4262
+ goto return_zero;
4263
+ }
4264
+
4265
+ str = rb_str_new2(orig_szVal);
4266
+ rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str);
4183
4267
  }
4184
4268
 
4185
4269
  nalloc = (ni + nf + BASE_FIG - 1) / BASE_FIG + 1; /* set effective allocation */
@@ -4191,7 +4275,7 @@ VpAlloc(size_t mx, const char *szVal)
4191
4275
  /* xmalloc() alway returns(or throw interruption) */
4192
4276
  vp->MaxPrec = mx; /* set max precision */
4193
4277
  VpSetZero(vp, sign);
4194
- VpCtoV(vp, &szVal[ipn], ni, &szVal[ipf], nf, &szVal[ipe], ne);
4278
+ VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne);
4195
4279
  rb_str_resize(buf, 0);
4196
4280
  return vp;
4197
4281
  }
@@ -4754,7 +4838,7 @@ VpMult(Real *c, Real *a, Real *b)
4754
4838
 
4755
4839
  if (MxIndC < MxIndAB) { /* The Max. prec. of c < Prec(a)+Prec(b) */
4756
4840
  w = c;
4757
- c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0");
4841
+ c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0", 1);
4758
4842
  MxIndC = MxIndAB;
4759
4843
  }
4760
4844
 
@@ -5922,8 +6006,8 @@ VpSqrt(Real *y, Real *x)
5922
6006
  if (x->MaxPrec > (size_t)n) n = (ssize_t)x->MaxPrec;
5923
6007
 
5924
6008
  /* allocate temporally variables */
5925
- f = VpAlloc(y->MaxPrec * (BASE_FIG + 2), "#1");
5926
- r = VpAlloc((n + n) * (BASE_FIG + 2), "#1");
6009
+ f = VpAlloc(y->MaxPrec * (BASE_FIG + 2), "#1", 1);
6010
+ r = VpAlloc((n + n) * (BASE_FIG + 2), "#1", 1);
5927
6011
 
5928
6012
  nr = 0;
5929
6013
  y_prec = y->MaxPrec;
@@ -6375,8 +6459,8 @@ VpPower(Real *y, Real *x, SIGNED_VALUE n)
6375
6459
 
6376
6460
  /* Allocate working variables */
6377
6461
 
6378
- w1 = VpAlloc((y->MaxPrec + 2) * BASE_FIG, "#0");
6379
- w2 = VpAlloc((w1->MaxPrec * 2 + 1) * BASE_FIG, "#0");
6462
+ w1 = VpAlloc((y->MaxPrec + 2) * BASE_FIG, "#0", 1);
6463
+ w2 = VpAlloc((w1->MaxPrec * 2 + 1) * BASE_FIG, "#0", 1);
6380
6464
  /* calculation start */
6381
6465
 
6382
6466
  VpAsgn(y, x, 1);
@@ -308,7 +308,7 @@ VP_EXPORT size_t VpInit(BDIGIT BaseVal);
308
308
  VP_EXPORT void *VpMemAlloc(size_t mb);
309
309
  VP_EXPORT void *VpMemRealloc(void *ptr, size_t mb);
310
310
  VP_EXPORT void VpFree(Real *pv);
311
- VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal);
311
+ VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal, int strict_p);
312
312
  VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw);
313
313
  VP_EXPORT size_t VpAddSub(Real *c,Real *a,Real *b,int operation);
314
314
  VP_EXPORT size_t VpMult(Real *c,Real *a,Real *b);
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: false
2
2
  require 'mkmf'
3
3
 
4
+ def windows_platform?
5
+ /cygwin|mingw|mswin/ === RUBY_PLATFORM
6
+ end
7
+
4
8
  gemspec_name = gemspec_path = nil
5
9
  unless ['', '../../'].any? {|dir|
6
10
  gemspec_name = "#{dir}bigdecimal.gemspec"
@@ -28,6 +32,17 @@ have_func("rb_rational_den", "ruby.h")
28
32
  have_func("rb_array_const_ptr", "ruby.h")
29
33
  have_func("rb_sym2str", "ruby.h")
30
34
 
35
+ checking_for(checking_message("Windows")) do
36
+ if windows_platform?
37
+ import_library_name = "libruby-bigdecimal.a"
38
+ $DLDFLAGS << " $(srcdir)/bigdecimal.def -Wl,--out-implib=#{import_library_name}"
39
+ $cleanfiles << import_library_name
40
+ true
41
+ else
42
+ false
43
+ end
44
+ end
45
+
31
46
  create_makefile('bigdecimal') {|mf|
32
47
  mf << "\nall:\n\nextconf.h: $(srcdir)/#{gemspec_name}\n"
33
48
  }
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: false
2
+ require 'mkmf'
3
+
4
+ def windows_platform?
5
+ /cygwin|mingw|mswin/ === RUBY_PLATFORM
6
+ end
7
+
8
+ checking_for(checking_message("Windows")) do
9
+ if windows_platform?
10
+ base_dir = File.expand_path('../../../..', __FILE__)
11
+ build_dir = File.join(base_dir, "tmp", RUBY_PLATFORM, "bigdecimal", RUBY_VERSION)
12
+ library_base_name = "ruby-bigdecimal"
13
+ case RUBY_PLATFORM
14
+ when /cygwin|mingw/
15
+ $LDFLAGS << " -L#{build_dir}"
16
+ $libs << " -l#{library_base_name}"
17
+ when /mswin/
18
+ $DLDFLAGS << " /libpath:#{build_dir}"
19
+ $libs << " lib#{library_base_name}.lib"
20
+ end
21
+ true
22
+ else
23
+ false
24
+ end
25
+ end
26
+
27
+ create_makefile('bigdecimal/util')
@@ -0,0 +1,9 @@
1
+ #include "ruby.h"
2
+
3
+ RUBY_EXTERN VALUE rmpd_util_str_to_d(VALUE str);
4
+
5
+ void
6
+ Init_util(void)
7
+ {
8
+ rb_define_method(rb_cString, "to_d", rmpd_util_str_to_d, 0);
9
+ }
@@ -21,6 +21,9 @@
21
21
  #
22
22
  # fx is f.values(x).
23
23
  #
24
+
25
+ require 'bigdecimal'
26
+
24
27
  module Jacobian
25
28
  module_function
26
29
 
@@ -5,6 +5,8 @@
5
5
  # and provides BigDecimal#to_d and BigDecimal#to_digits.
6
6
  #++
7
7
 
8
+ require 'bigdecimal'
9
+ require 'bigdecimal/util.so'
8
10
 
9
11
  class Integer < Numeric
10
12
  # call-seq:
@@ -42,8 +44,8 @@ class Float < Numeric
42
44
  #
43
45
  # See also BigDecimal::new.
44
46
  #
45
- def to_d(precision=nil)
46
- BigDecimal(self, precision || Float::DIG)
47
+ def to_d(precision=Float::DIG)
48
+ BigDecimal(self, precision)
47
49
  end
48
50
  end
49
51
 
@@ -64,13 +66,6 @@ class String
64
66
  #
65
67
  # See also BigDecimal::new.
66
68
  #
67
- def to_d
68
- begin
69
- BigDecimal(self)
70
- rescue ArgumentError
71
- BigDecimal(0)
72
- end
73
- end
74
69
  end
75
70
 
76
71
 
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.3.5
4
+ version: 1.4.0.pre.20181121a
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: 2018-06-15 00:00:00.000000000 Z
13
+ date: 2018-11-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -89,6 +89,7 @@ email:
89
89
  executables: []
90
90
  extensions:
91
91
  - ext/bigdecimal/extconf.rb
92
+ - ext/bigdecimal/util/extconf.rb
92
93
  extra_rdoc_files: []
93
94
  files:
94
95
  - bigdecimal.gemspec
@@ -96,6 +97,8 @@ files:
96
97
  - ext/bigdecimal/bigdecimal.h
97
98
  - ext/bigdecimal/depend
98
99
  - ext/bigdecimal/extconf.rb
100
+ - ext/bigdecimal/util/extconf.rb
101
+ - ext/bigdecimal/util/util.c
99
102
  - lib/bigdecimal/jacobian.rb
100
103
  - lib/bigdecimal/ludcmp.rb
101
104
  - lib/bigdecimal/math.rb
@@ -116,12 +119,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
119
  requirements:
117
120
  - - ">="
118
121
  - !ruby/object:Gem::Version
119
- version: '0'
122
+ version: 2.3.0
120
123
  required_rubygems_version: !ruby/object:Gem::Requirement
121
124
  requirements:
122
- - - ">="
125
+ - - ">"
123
126
  - !ruby/object:Gem::Version
124
- version: '0'
127
+ version: 1.3.1
125
128
  requirements: []
126
129
  rubyforge_project:
127
130
  rubygems_version: 2.7.6