bigdecimal 1.3.5 → 1.4.0.pre.20181121a

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