summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/bigdecimal/bigdecimal.c525
-rw-r--r--ext/bigdecimal/bigdecimal.def3
-rw-r--r--ext/bigdecimal/bigdecimal.gemspec11
-rw-r--r--ext/bigdecimal/bigdecimal.h2
-rw-r--r--ext/bigdecimal/depend2
-rw-r--r--ext/bigdecimal/extconf.rb4
-rw-r--r--ext/bigdecimal/lib/bigdecimal/jacobian.rb3
-rw-r--r--ext/bigdecimal/lib/bigdecimal/util.rb30
-rw-r--r--ext/bigdecimal/sample/linear.rb21
-rw-r--r--ext/bigdecimal/sample/nlsolve.rb10
-rw-r--r--ext/bigdecimal/util/extconf.rb24
-rw-r--r--ext/bigdecimal/util/util.c9
12 files changed, 238 insertions, 406 deletions
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index a3f73015c9..d1aa56c121 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -136,6 +136,24 @@ rb_rational_den(VALUE rat)
#define DoSomeOne(x,y,f) rb_num_coerce_bin(x,y,f)
/*
+ * Returns the BigDecimal version number.
+ */
+static VALUE
+BigDecimal_version(VALUE self)
+{
+ /*
+ * 1.0.0: Ruby 1.8.0
+ * 1.0.1: Ruby 1.8.1
+ * 1.1.0: Ruby 1.9.3
+ */
+#ifndef RUBY_BIGDECIMAL_VERSION
+# error RUBY_BIGDECIMAL_VERSION is not defined
+#endif
+ rb_warning("BigDecimal.ver is deprecated; use BigDecimal::VERSION instead.");
+ return rb_str_new2(RUBY_BIGDECIMAL_VERSION);
+}
+
+/*
* VP routines used in BigDecimal part
*/
static unsigned short VpGetException(void);
@@ -646,10 +664,9 @@ VP_EXPORT Real *
VpNewRbClass(size_t mx, const char *str, VALUE klass)
{
VALUE obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, 0);
- Real *pv = VpAlloc(mx, str, 1, 1);
+ Real *pv = VpAlloc(mx,str);
RTYPEDDATA_DATA(obj) = pv;
pv->obj = obj;
- RB_OBJ_FREEZE(obj);
return pv;
}
@@ -2148,10 +2165,15 @@ BigDecimal_exponent(VALUE self)
return INT2NUM(e);
}
-/* Returns a string representation of self.
+/* Returns debugging information about the value as a string of comma-separated
+ * values in angle brackets with a leading #:
*
* BigDecimal("1234.5678").inspect
* #=> "0.12345678e4"
+ *
+ * The first part is the address, the second is the value as a string, and
+ * the final part ss(mm) is the current number of significant digits and the
+ * maximum number of significant digits, respectively.
*/
static VALUE
BigDecimal_inspect(VALUE self)
@@ -2313,7 +2335,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
n = NIL_P(prec) ? (ssize_t)(x->Prec*VpBaseFig()) : NUM2SSIZET(prec);
if (VpIsNaN(x)) {
- y = VpCreateRbObject(n, "0");
+ y = VpCreateRbObject(n, "0#");
RB_GC_GUARD(y->obj);
VpSetNaN(y);
return ToValue(y);
@@ -2437,7 +2459,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
}
}
else {
- y = VpCreateRbObject(n, "0");
+ y = VpCreateRbObject(n, "0#");
if (BIGDECIMAL_NEGATIVE_P(x)) {
if (is_integer(vexp)) {
if (is_even(vexp)) {
@@ -2470,7 +2492,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
}
else if (RTEST(rb_funcall(abs_value, '<', 1, INT2FIX(1)))) {
if (is_negative(vexp)) {
- y = VpCreateRbObject(n, "0");
+ y = VpCreateRbObject(n, "0#");
if (is_even(vexp)) {
VpSetInf(y, VpGetSign(x));
}
@@ -2488,7 +2510,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
}
else {
if (is_positive(vexp)) {
- y = VpCreateRbObject(n, "0");
+ y = VpCreateRbObject(n, "0#");
if (is_even(vexp)) {
VpSetInf(y, VpGetSign(x));
}
@@ -2538,6 +2560,72 @@ BigDecimal_power_op(VALUE self, VALUE exp)
return BigDecimal_power(1, &exp, self);
}
+static VALUE
+BigDecimal_s_allocate(VALUE klass)
+{
+ return VpNewRbClass(0, NULL, klass)->obj;
+}
+
+static Real *BigDecimal_new(int argc, VALUE *argv);
+
+/* call-seq:
+ * new(initial, digits)
+ *
+ * Create a new BigDecimal object.
+ *
+ * initial:: The initial value, as an Integer, a Float, a Rational,
+ * a BigDecimal, or a String.
+ *
+ * If it is a String, spaces are ignored and unrecognized characters
+ * terminate the value.
+ *
+ * digits:: The number of significant digits, as an Integer. If omitted or 0,
+ * the number of significant digits is determined from the initial
+ * value.
+ *
+ * The actual number of significant digits used in computation is usually
+ * larger than the specified number.
+ *
+ * ==== Exceptions
+ *
+ * TypeError:: If the +initial+ type is neither Integer, Float,
+ * Rational, nor BigDecimal, this exception is raised.
+ *
+ * TypeError:: If the +digits+ is not an Integer, this exception is raised.
+ *
+ * ArgumentError:: If +initial+ is a Float, and the +digits+ is larger than
+ * Float::DIG + 1, this exception is raised.
+ *
+ * ArgumentError:: If the +initial+ is a Float or Rational, and the +digits+
+ * value is omitted, this exception is raised.
+ */
+static VALUE
+BigDecimal_s_new(int argc, VALUE *argv, VALUE self)
+{
+ rb_warning("BigDecimal.new is deprecated; use Kernel.BigDecimal method instead.");
+ return rb_call_super(argc, argv);
+}
+
+static VALUE
+BigDecimal_initialize(int argc, VALUE *argv, VALUE self)
+{
+ ENTER(1);
+ Real *pv = rb_check_typeddata(self, &BigDecimal_data_type);
+ Real *x;
+
+ GUARD_OBJ(x, BigDecimal_new(argc, argv));
+ if (ToValue(x)) {
+ pv = VpCopy(pv, x);
+ }
+ else {
+ VpFree(pv);
+ pv = x;
+ }
+ DATA_PTR(self) = pv;
+ pv->obj = self;
+ return self;
+}
+
/* :nodoc:
*
* private method for dup and clone the provided BigDecimal +other+
@@ -2560,60 +2648,19 @@ BigDecimal_clone(VALUE self)
return self;
}
-static int
-opts_exception_p(VALUE opts)
-{
- static ID kwds[1];
- VALUE exception;
- if (!kwds[0]) {
- kwds[0] = rb_intern_const("exception");
- }
- rb_get_kwargs(opts, kwds, 0, 1, &exception);
- return exception != Qfalse;
-}
-
static Real *
BigDecimal_new(int argc, VALUE *argv)
{
size_t mf;
- VALUE opts = Qnil;
VALUE nFig;
VALUE iniValue;
double d;
- int exc;
-
- argc = rb_scan_args(argc, argv, "11:", &iniValue, &nFig, &opts);
- exc = opts_exception_p(opts);
- if (argc == 1) {
+ if (rb_scan_args(argc, argv, "11", &iniValue, &nFig) == 1) {
mf = 0;
}
else {
- /* expand GetPrecisionInt for exception suppression */
- ssize_t n = NUM2INT(nFig);
- if (n < 0) {
- if (!exc) {
- return NULL;
- }
- rb_raise(rb_eArgError, "negative precision");
- }
- mf = (size_t)n;
- }
-
- if (SPECIAL_CONST_P(iniValue)) {
- switch (iniValue) {
- case Qnil:
- if (!exc) return NULL;
- rb_raise(rb_eTypeError, "can't convert nil into BigDecimal");
- case Qtrue:
- if (!exc) return NULL;
- rb_raise(rb_eTypeError, "can't convert true into BigDecimal");
- case Qfalse:
- if (!exc) return NULL;
- rb_raise(rb_eTypeError, "can't convert false into BigDecimal");
- default:
- break;
- }
+ mf = GetPrecisionInt(nFig);
}
switch (TYPE(iniValue)) {
@@ -2636,17 +2683,11 @@ BigDecimal_new(int argc, VALUE *argv)
return pv;
}
if (mf > DBL_DIG+1) {
- if (!exc) {
- return NULL;
- }
rb_raise(rb_eArgError, "precision too large.");
}
/* fall through */
case T_RATIONAL:
if (NIL_P(nFig)) {
- if (!exc) {
- return NULL;
- }
rb_raise(rb_eArgError,
"can't omit precision for a %"PRIsVALUE".",
RB_OBJ_CLASSNAME(iniValue));
@@ -2658,60 +2699,22 @@ BigDecimal_new(int argc, VALUE *argv)
default:
break;
}
- /* TODO: support to_d */
- if (!exc) {
- iniValue = rb_check_convert_type(iniValue, T_STRING, "String", "to_str");
- if (NIL_P(iniValue)) return NULL;
- }
StringValueCStr(iniValue);
- return VpAlloc(mf, RSTRING_PTR(iniValue), 1, exc);
+ return VpAlloc(mf, RSTRING_PTR(iniValue));
}
-/* call-seq:
- * BigDecimal(initial, digits)
- *
- * Create a new BigDecimal object.
- *
- * initial:: The initial value, as an Integer, a Float, a Rational,
- * a BigDecimal, or a String.
- *
- * If it is a String, spaces are ignored and unrecognized characters
- * terminate the value.
- *
- * digits:: The number of significant digits, as an Integer. If omitted or 0,
- * the number of significant digits is determined from the initial
- * value.
- *
- * The actual number of significant digits used in computation is usually
- * larger than the specified number.
- *
- * ==== Exceptions
- *
- * TypeError:: If the +initial+ type is neither Integer, Float,
- * Rational, nor BigDecimal, this exception is raised.
- *
- * TypeError:: If the +digits+ is not an Integer, this exception is raised.
- *
- * ArgumentError:: If +initial+ is a Float, and the +digits+ is larger than
- * Float::DIG + 1, this exception is raised.
- *
- * ArgumentError:: If the +initial+ is a Float or Rational, and the +digits+
- * value is omitted, this exception is raised.
- */
+/* See also BigDecimal.new */
static VALUE
-f_BigDecimal(int argc, VALUE *argv, VALUE self)
+BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
{
ENTER(1);
Real *pv;
VALUE obj;
obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0);
- pv = BigDecimal_new(argc, argv);
- if (pv == NULL) return Qnil;
- SAVE(pv);
+ GUARD_OBJ(pv, BigDecimal_new(argc, argv));
if (ToValue(pv)) pv = VpCopy(NULL, pv);
RTYPEDDATA_DATA(obj) = pv;
- RB_OBJ_FREEZE(obj);
return pv->obj = obj;
}
@@ -3135,21 +3138,6 @@ get_vp_value:
return y;
}
-VALUE
-rmpd_util_str_to_d(VALUE str)
-{
- ENTER(1);
- char const *c_str;
- Real *pv;
- VALUE obj;
-
- c_str = StringValueCStr(str);
- GUARD_OBJ(pv, VpAlloc(0, c_str, 0, 1));
- obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, pv);
- RB_OBJ_FREEZE(obj);
- return obj;
-}
-
/* Document-class: BigDecimal
* BigDecimal provides arbitrary-precision floating point decimal arithmetic.
*
@@ -3289,17 +3277,18 @@ Init_bigdecimal(void)
/* Class and method registration */
rb_cBigDecimal = rb_define_class("BigDecimal", rb_cNumeric);
+ rb_define_alloc_func(rb_cBigDecimal, BigDecimal_s_allocate);
/* Global function */
- rb_define_global_function("BigDecimal", f_BigDecimal, -1);
+ rb_define_global_function("BigDecimal", BigDecimal_global_new, -1);
/* Class methods */
- rb_undef_method(CLASS_OF(rb_cBigDecimal), "allocate");
- rb_undef_method(CLASS_OF(rb_cBigDecimal), "new");
+ rb_define_singleton_method(rb_cBigDecimal, "new", BigDecimal_s_new, -1);
rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1);
rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 1);
+ rb_define_singleton_method(rb_cBigDecimal, "ver", BigDecimal_version, 0);
rb_define_singleton_method(rb_cBigDecimal, "save_exception_mode", BigDecimal_save_exception_mode, 0);
rb_define_singleton_method(rb_cBigDecimal, "save_rounding_mode", BigDecimal_save_rounding_mode, 0);
@@ -3419,13 +3408,14 @@ Init_bigdecimal(void)
arg = rb_str_new2("+Infinity");
/* Positive infinity value. */
- rb_define_const(rb_cBigDecimal, "INFINITY", f_BigDecimal(1, &arg, rb_cBigDecimal));
+ rb_define_const(rb_cBigDecimal, "INFINITY", BigDecimal_global_new(1, &arg, rb_cBigDecimal));
arg = rb_str_new2("NaN");
/* 'Not a Number' value. */
- rb_define_const(rb_cBigDecimal, "NAN", f_BigDecimal(1, &arg, rb_cBigDecimal));
+ rb_define_const(rb_cBigDecimal, "NAN", BigDecimal_global_new(1, &arg, rb_cBigDecimal));
/* instance methods */
+ rb_define_method(rb_cBigDecimal, "initialize", BigDecimal_initialize, -1);
rb_define_method(rb_cBigDecimal, "initialize_copy", BigDecimal_initialize_copy, 1);
rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
@@ -3724,7 +3714,13 @@ VpSetRoundMode(unsigned short n)
* (to let the compiler know they may be changed in outside
* (... but not actually..)).
*/
+volatile const double gZero_ABCED9B1_CE73__00400511F31D = 0.0;
volatile const double gOne_ABCED9B4_CE73__00400511F31D = 1.0;
+static double
+Zero(void)
+{
+ return gZero_ABCED9B1_CE73__00400511F31D;
+}
static double
One(void)
@@ -3749,19 +3745,25 @@ One(void)
VP_EXPORT double
VpGetDoubleNaN(void) /* Returns the value of NaN */
{
- return nan("");
+ static double fNaN = 0.0;
+ if (fNaN == 0.0) fNaN = Zero()/Zero();
+ return fNaN;
}
VP_EXPORT double
VpGetDoublePosInf(void) /* Returns the value of +Infinity */
{
- return HUGE_VAL;
+ static double fInf = 0.0;
+ if (fInf == 0.0) fInf = One()/Zero();
+ return fInf;
}
VP_EXPORT double
VpGetDoubleNegInf(void) /* Returns the value of -Infinity */
{
- return -HUGE_VAL;
+ static double fInf = 0.0;
+ if (fInf == 0.0) fInf = -(One()/Zero());
+ return fInf;
}
VP_EXPORT double
@@ -3962,8 +3964,8 @@ VpInit(BDIGIT BaseVal)
VpGetDoubleNegZero();
/* Allocates Vp constants. */
- VpConstOne = VpAlloc(1UL, "1", 1, 1);
- VpPt5 = VpAlloc(1UL, ".5", 1, 1);
+ VpConstOne = VpAlloc(1UL, "1");
+ VpPt5 = VpAlloc(1UL, ".5");
#ifdef BIGDECIMAL_DEBUG
gnAlloc = 0;
@@ -4027,52 +4029,6 @@ overflow:
return VpException(VP_EXCEPTION_OVERFLOW, "Exponent overflow", 0);
}
-Real *
-rmpd_parse_special_string(const char *str)
-{
- static const struct {
- const char *str;
- size_t len;
- int sign;
- } table[] = {
- { SZ_INF, sizeof(SZ_INF) - 1, VP_SIGN_POSITIVE_INFINITE },
- { SZ_PINF, sizeof(SZ_PINF) - 1, VP_SIGN_POSITIVE_INFINITE },
- { SZ_NINF, sizeof(SZ_NINF) - 1, VP_SIGN_NEGATIVE_INFINITE },
- { SZ_NaN, sizeof(SZ_NaN) - 1, VP_SIGN_NaN }
- };
- static const size_t table_length = sizeof(table) / sizeof(table[0]);
- size_t i;
-
- for (i = 0; i < table_length; ++i) {
- const char *p;
- if (strncmp(str, table[i].str, table[i].len) != 0) {
- continue;
- }
-
- p = str + table[i].len;
- while (*p && ISSPACE(*p)) ++p;
- if (*p == '\0') {
- Real *vp = VpAllocReal(1);
- vp->MaxPrec = 1;
- switch (table[i].sign) {
- default:
- UNREACHABLE; break;
- case VP_SIGN_POSITIVE_INFINITE:
- VpSetPosInf(vp);
- return vp;
- case VP_SIGN_NEGATIVE_INFINITE:
- VpSetNegInf(vp);
- return vp;
- case VP_SIGN_NaN:
- VpSetNaN(vp);
- return vp;
- }
- }
- }
-
- return NULL;
-}
-
/*
* Allocates variable.
* [Input]
@@ -4087,10 +4043,10 @@ rmpd_parse_special_string(const char *str)
* NULL be returned if memory allocation is failed,or any error.
*/
VP_EXPORT Real *
-VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
+VpAlloc(size_t mx, const char *szVal)
{
const char *orig_szVal = szVal;
- size_t i, j, ni, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc;
+ size_t i, ni, ipn, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc;
char v, *psz;
int sign=1;
Real *vp = NULL;
@@ -4101,10 +4057,7 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
if (mx == 0) ++mx;
if (szVal) {
- /* Skipping leading spaces */
while (ISSPACE(*szVal)) szVal++;
-
- /* Processing the leading one `#` */
if (*szVal != '#') {
if (mf) {
mf = (mf + BASE_FIG - 1) / BASE_FIG + 2; /* Needs 1 more for div */
@@ -4118,7 +4071,6 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
}
}
else {
- return_zero:
/* necessary to be able to store */
/* at least mx digits. */
/* szVal==NULL ==> allocate zero value. */
@@ -4129,168 +4081,105 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
return vp;
}
- /* Check on Inf & NaN */
- if ((vp = rmpd_parse_special_string(szVal)) != NULL) {
- return vp;
- }
-
- /* Scanning digits */
-
- /* A buffer for keeping scanned digits */
+ /* Skip all '_' after digit: 2006-6-30 */
+ ni = 0;
buf = rb_str_tmp_new(strlen(szVal) + 1);
psz = RSTRING_PTR(buf);
-
- /* cursor: i for psz, and j for szVal */
- i = j = 0;
-
- /* Scanning: sign part */
- v = psz[i] = szVal[j];
- if ((v == '-') || (v == '+')) {
- sign = -(v == '-');
- ++i;
- ++j;
- }
-
- /* Scanning: integer part */
- ni = 0; /* number of digits in the integer part */
- while ((v = psz[i] = szVal[j]) != '\0') {
- if (!strict_p && ISSPACE(v)) {
- v = psz[i] = '\0';
+ i = 0;
+ ipn = 0;
+ while ((psz[i] = szVal[ipn]) != 0) {
+ if (ISSPACE(psz[i])) {
+ psz[i] = 0;
break;
}
- if (v == '_') {
+ if (ISDIGIT(psz[i])) ++ni;
+ if (psz[i] == '_') {
if (ni > 0) {
- v = szVal[j+1];
- if (v == '\0' || ISSPACE(v) || ISDIGIT(v)) {
- ++j;
- continue;
- }
- if (!strict_p) {
- v = psz[i] = '\0';
- break;
- }
+ ipn++;
+ continue;
}
- goto invalid_value;
- }
- if (!ISDIGIT(v)) {
+ psz[i] = 0;
break;
}
- ++ni;
++i;
- ++j;
+ ++ipn;
+ }
+ szVal = psz;
+
+ /* Check on Inf & NaN */
+ if (StrCmp(szVal, SZ_PINF) == 0 || StrCmp(szVal, SZ_INF) == 0 ) {
+ vp = VpAllocReal(1);
+ vp->MaxPrec = 1; /* set max precision */
+ VpSetPosInf(vp);
+ return vp;
+ }
+ if (StrCmp(szVal, SZ_NINF) == 0) {
+ vp = VpAllocReal(1);
+ vp->MaxPrec = 1; /* set max precision */
+ VpSetNegInf(vp);
+ return vp;
+ }
+ if (StrCmp(szVal, SZ_NaN) == 0) {
+ vp = VpAllocReal(1);
+ vp->MaxPrec = 1; /* set max precision */
+ VpSetNaN(vp);
+ return vp;
}
- /* Scanning: fractional part */
- nf = 0; /* number of digits in the fractional part */
- ne = 0; /* number of digits in the exponential part */
- ipf = 0; /* index of the beginning of the fractional part */
- ipe = 0; /* index of the beginning of the exponential part */
+ /* check on number szVal[] */
+ ipn = i = 0;
+ if (szVal[i] == '-') { sign=-1; ++i; }
+ else if (szVal[i] == '+') ++i;
+ /* Skip digits */
+ ni = 0; /* digits in mantissa */
+ while ((v = szVal[i]) != 0) {
+ if (!ISDIGIT(v)) break;
+ ++i;
+ ++ni;
+ }
+ nf = 0;
+ ipf = 0;
+ ipe = 0;
+ ne = 0;
dot_seen = 0;
exp_seen = 0;
-
- if (v != '\0') {
- /* Scanning fractional part */
- if ((psz[i] = szVal[j]) == '.') {
+ if (v) {
+ /* other than digit nor \0 */
+ if (szVal[i] == '.') { /* xxx. */
dot_seen = 1;
++i;
- ++j;
ipf = i;
- while ((v = psz[i] = szVal[j]) != '\0') {
- if (!strict_p && ISSPACE(v)) {
- v = psz[i] = '\0';
- break;
- }
- if (v == '_') {
- if (nf > 0 && ISDIGIT(szVal[j+1])) {
- ++j;
- continue;
- }
- if (!strict_p) {
- v = psz[i] = '\0';
- if (nf == 0) {
- dot_seen = 0;
- }
- break;
- }
- goto invalid_value;
- }
+ while ((v = szVal[i]) != 0) { /* get fraction part. */
if (!ISDIGIT(v)) break;
++i;
- ++j;
++nf;
}
}
-
- /* Scanning exponential part */
- if (v != '\0') {
- switch ((psz[i] = szVal[j])) {
- case '\0':
- break;
- case 'e': case 'E':
- case 'd': case 'D':
- exp_seen = 1;
+ ipe = 0; /* Exponent */
+
+ switch (szVal[i]) {
+ case '\0':
+ break;
+ case 'e': case 'E':
+ case 'd': case 'D':
+ exp_seen = 1;
+ ++i;
+ ipe = i;
+ v = szVal[i];
+ if ((v == '-') || (v == '+')) ++i;
+ while ((v=szVal[i]) != 0) {
+ if (!ISDIGIT(v)) break;
++i;
- ++j;
- ipe = i;
- v = psz[i] = szVal[j];
- if ((v == '-') || (v == '+')) {
- ++i;
- ++j;
- }
- while ((v = psz[i] = szVal[j]) != '\0') {
- if (!strict_p && ISSPACE(v)) {
- v = psz[i] = '\0';
- break;
- }
- if (v == '_') {
- if (ne > 0 && ISDIGIT(szVal[j+1])) {
- ++j;
- continue;
- }
- if (!strict_p) {
- v = psz[i] = '\0';
- if (ne == 0) {
- exp_seen = 0;
- }
- break;
- }
- goto invalid_value;
- }
- if (!ISDIGIT(v)) break;
- ++i;
- ++j;
- ++ne;
- }
- break;
- default:
- break;
- }
- }
-
- if (v != '\0') {
- /* Scanning trailing spaces */
- while (ISSPACE(szVal[j])) ++j;
-
- /* Invalid character */
- if (szVal[j]) {
- goto invalid_value;
- }
+ ++ne;
+ }
+ break;
+ default:
+ break;
}
}
-
- psz[i] = '\0';
-
if (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0)) {
- VALUE str;
- invalid_value:
- if (!strict_p) {
- goto return_zero;
- }
- if (!exc) {
- return NULL;
- }
- str = rb_str_new2(orig_szVal);
- rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str);
+ VALUE str = rb_str_new2(orig_szVal);
+ rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str);
}
nalloc = (ni + nf + BASE_FIG - 1) / BASE_FIG + 1; /* set effective allocation */
@@ -4302,7 +4191,7 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
/* xmalloc() alway returns(or throw interruption) */
vp->MaxPrec = mx; /* set max precision */
VpSetZero(vp, sign);
- VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne);
+ VpCtoV(vp, &szVal[ipn], ni, &szVal[ipf], nf, &szVal[ipe], ne);
rb_str_resize(buf, 0);
return vp;
}
@@ -4865,7 +4754,7 @@ VpMult(Real *c, Real *a, Real *b)
if (MxIndC < MxIndAB) { /* The Max. prec. of c < Prec(a)+Prec(b) */
w = c;
- c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0", 1, 1);
+ c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0");
MxIndC = MxIndAB;
}
@@ -6033,8 +5922,8 @@ VpSqrt(Real *y, Real *x)
if (x->MaxPrec > (size_t)n) n = (ssize_t)x->MaxPrec;
/* allocate temporally variables */
- f = VpAlloc(y->MaxPrec * (BASE_FIG + 2), "#1", 1, 1);
- r = VpAlloc((n + n) * (BASE_FIG + 2), "#1", 1, 1);
+ f = VpAlloc(y->MaxPrec * (BASE_FIG + 2), "#1");
+ r = VpAlloc((n + n) * (BASE_FIG + 2), "#1");
nr = 0;
y_prec = y->MaxPrec;
@@ -6486,8 +6375,8 @@ VpPower(Real *y, Real *x, SIGNED_VALUE n)
/* Allocate working variables */
- w1 = VpAlloc((y->MaxPrec + 2) * BASE_FIG, "#0", 1, 1);
- w2 = VpAlloc((w1->MaxPrec * 2 + 1) * BASE_FIG, "#0", 1, 1);
+ w1 = VpAlloc((y->MaxPrec + 2) * BASE_FIG, "#0");
+ w2 = VpAlloc((w1->MaxPrec * 2 + 1) * BASE_FIG, "#0");
/* calculation start */
VpAsgn(y, x, 1);
diff --git a/ext/bigdecimal/bigdecimal.def b/ext/bigdecimal/bigdecimal.def
deleted file mode 100644
index 615bf72e20..0000000000
--- a/ext/bigdecimal/bigdecimal.def
+++ /dev/null
@@ -1,3 +0,0 @@
-EXPORTS
-rmpd_util_str_to_d
-Init_bigdecimal
diff --git a/ext/bigdecimal/bigdecimal.gemspec b/ext/bigdecimal/bigdecimal.gemspec
index c65c1da0a2..c8c90870ea 100644
--- a/ext/bigdecimal/bigdecimal.gemspec
+++ b/ext/bigdecimal/bigdecimal.gemspec
@@ -1,6 +1,6 @@
# coding: utf-8
-bigdecimal_version = '1.4.0.pre.20181204a'
+bigdecimal_version = '1.3.4'
Gem::Specification.new do |s|
s.name = "bigdecimal"
@@ -14,16 +14,13 @@ Gem::Specification.new do |s|
s.license = "ruby"
s.require_paths = %w[lib]
- s.extensions = %w[ext/bigdecimal/extconf.rb ext/bigdecimal/util/extconf.rb]
+ s.extensions = %w[ext/bigdecimal/extconf.rb]
s.files = %w[
bigdecimal.gemspec
ext/bigdecimal/bigdecimal.c
- ext/bigdecimal/bigdecimal.def
ext/bigdecimal/bigdecimal.h
ext/bigdecimal/depend
ext/bigdecimal/extconf.rb
- ext/bigdecimal/util/extconf.rb
- ext/bigdecimal/util/util.c
lib/bigdecimal/jacobian.rb
lib/bigdecimal/ludcmp.rb
lib/bigdecimal/math.rb
@@ -34,11 +31,9 @@ Gem::Specification.new do |s|
sample/pi.rb
]
- s.required_ruby_version = Gem::Requirement.new(">= 2.3.0".freeze)
-
s.add_development_dependency "rake", "~> 10.0"
s.add_development_dependency "rake-compiler", ">= 0.9"
s.add_development_dependency "rake-compiler-dock", ">= 0.6.1"
- s.add_development_dependency "minitest", "< 5.0.0"
+ s.add_development_dependency "minitest", "~> 4.7.5"
s.add_development_dependency "pry"
end
diff --git a/ext/bigdecimal/bigdecimal.h b/ext/bigdecimal/bigdecimal.h
index e3eae06e67..3297f18867 100644
--- a/ext/bigdecimal/bigdecimal.h
+++ b/ext/bigdecimal/bigdecimal.h
@@ -308,7 +308,7 @@ VP_EXPORT size_t VpInit(BDIGIT BaseVal);
VP_EXPORT void *VpMemAlloc(size_t mb);
VP_EXPORT void *VpMemRealloc(void *ptr, size_t mb);
VP_EXPORT void VpFree(Real *pv);
-VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal, int strict_p, int exc);
+VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal);
VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw);
VP_EXPORT size_t VpAddSub(Real *c,Real *a,Real *b,int operation);
VP_EXPORT size_t VpMult(Real *c,Real *a,Real *b);
diff --git a/ext/bigdecimal/depend b/ext/bigdecimal/depend
index 78833701ef..6783192b30 100644
--- a/ext/bigdecimal/depend
+++ b/ext/bigdecimal/depend
@@ -1,5 +1,3 @@
-extconf.h: $(srcdir)/$(GEMSPEC)
-
# AUTOGENERATED DEPENDENCIES START
bigdecimal.o: $(RUBY_EXTCONF_H)
bigdecimal.o: $(arch_hdrdir)/ruby/config.h
diff --git a/ext/bigdecimal/extconf.rb b/ext/bigdecimal/extconf.rb
index 2ae5e1b720..e565da891a 100644
--- a/ext/bigdecimal/extconf.rb
+++ b/ext/bigdecimal/extconf.rb
@@ -17,6 +17,8 @@ bigdecimal_version =
$defs << %Q[-DRUBY_BIGDECIMAL_VERSION=\\"#{bigdecimal_version}\\"]
+alias __have_macro__ have_macro
+
have_func("labs", "stdlib.h")
have_func("llabs", "stdlib.h")
have_func("finite", "math.h")
@@ -29,5 +31,5 @@ have_func("rb_array_const_ptr", "ruby.h")
have_func("rb_sym2str", "ruby.h")
create_makefile('bigdecimal') {|mf|
- mf << "GEMSPEC = #{gemspec_name}\n"
+ mf << "\nall:\n\nextconf.h: $(srcdir)/#{gemspec_name}\n"
}
diff --git a/ext/bigdecimal/lib/bigdecimal/jacobian.rb b/ext/bigdecimal/lib/bigdecimal/jacobian.rb
index 84c50248b7..9cad06c09b 100644
--- a/ext/bigdecimal/lib/bigdecimal/jacobian.rb
+++ b/ext/bigdecimal/lib/bigdecimal/jacobian.rb
@@ -21,9 +21,6 @@
#
# fx is f.values(x).
#
-
-require 'bigdecimal'
-
module Jacobian
module_function
diff --git a/ext/bigdecimal/lib/bigdecimal/util.rb b/ext/bigdecimal/lib/bigdecimal/util.rb
index 88f490cb45..911fa6fe3a 100644
--- a/ext/bigdecimal/lib/bigdecimal/util.rb
+++ b/ext/bigdecimal/lib/bigdecimal/util.rb
@@ -5,8 +5,6 @@
# and provides BigDecimal#to_d and BigDecimal#to_digits.
#++
-require 'bigdecimal'
-require 'bigdecimal/util.so'
class Integer < Numeric
# call-seq:
@@ -44,8 +42,8 @@ class Float < Numeric
#
# See also BigDecimal::new.
#
- def to_d(precision=Float::DIG)
- BigDecimal(self, precision)
+ def to_d(precision=nil)
+ BigDecimal(self, precision || Float::DIG)
end
end
@@ -66,6 +64,13 @@ class String
#
# See also BigDecimal::new.
#
+ def to_d
+ begin
+ BigDecimal(self)
+ rescue ArgumentError
+ BigDecimal(0)
+ end
+ end
end
@@ -127,20 +132,3 @@ class Rational < Numeric
BigDecimal(self, precision)
end
end
-
-
-class NilClass
- # call-seq:
- # nil.to_d -> bigdecimal
- #
- # Returns nil represented as a BigDecimal.
- #
- # require 'bigdecimal'
- # require 'bigdecimal/util'
- #
- # nil.to_d # => 0.0
- #
- def to_d
- BigDecimal(0)
- end
-end
diff --git a/ext/bigdecimal/sample/linear.rb b/ext/bigdecimal/sample/linear.rb
index 516c2473be..3b23269f8a 100644
--- a/ext/bigdecimal/sample/linear.rb
+++ b/ext/bigdecimal/sample/linear.rb
@@ -28,8 +28,8 @@ def rd_order(na)
end
na = ARGV.size
-zero = BigDecimal("0.0")
-one = BigDecimal("1.0")
+zero = BigDecimal.new("0.0")
+one = BigDecimal.new("1.0")
while (n=rd_order(na))>0
a = []
@@ -37,28 +37,27 @@ while (n=rd_order(na))>0
b = []
if na <= 0
# Read data from console.
- printf("\nEnter coefficient matrix element A[i,j]\n")
+ printf("\nEnter coefficient matrix element A[i,j]\n");
for i in 0...n do
for j in 0...n do
printf("A[%d,%d]? ",i,j); s = ARGF.gets
- a << BigDecimal(s)
- as << BigDecimal(s)
+ a << BigDecimal.new(s);
+ as << BigDecimal.new(s);
end
- printf("Contatant vector element b[%d] ? ",i)
- b << BigDecimal(ARGF.gets)
+ printf("Contatant vector element b[%d] ? ",i); b << BigDecimal.new(ARGF.gets);
end
else
# Read data from specified file.
- printf("Coefficient matrix and constant vector.\n")
+ printf("Coefficient matrix and constant vector.\n");
for i in 0...n do
s = ARGF.gets
printf("%d) %s",i,s)
s = s.split
for j in 0...n do
- a << BigDecimal(s[j])
- as << BigDecimal(s[j])
+ a << BigDecimal.new(s[j]);
+ as << BigDecimal.new(s[j]);
end
- b << BigDecimal(s[n])
+ b << BigDecimal.new(s[n]);
end
end
x = lusolve(a,b,ludecomp(a,n,zero,one),zero)
diff --git a/ext/bigdecimal/sample/nlsolve.rb b/ext/bigdecimal/sample/nlsolve.rb
index c2227dac73..b1dd08e0a3 100644
--- a/ext/bigdecimal/sample/nlsolve.rb
+++ b/ext/bigdecimal/sample/nlsolve.rb
@@ -12,11 +12,11 @@ include Newton
class Function # :nodoc: all
def initialize()
- @zero = BigDecimal("0.0")
- @one = BigDecimal("1.0")
- @two = BigDecimal("2.0")
- @ten = BigDecimal("10.0")
- @eps = BigDecimal("1.0e-16")
+ @zero = BigDecimal.new("0.0")
+ @one = BigDecimal.new("1.0")
+ @two = BigDecimal.new("2.0")
+ @ten = BigDecimal.new("10.0")
+ @eps = BigDecimal.new("1.0e-16")
end
def zero;@zero;end
def one ;@one ;end
diff --git a/ext/bigdecimal/util/extconf.rb b/ext/bigdecimal/util/extconf.rb
deleted file mode 100644
index 8750db1c52..0000000000
--- a/ext/bigdecimal/util/extconf.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: false
-require 'mkmf'
-
-checking_for(checking_message("Windows")) do
- case RUBY_PLATFORM
- when /cygwin|mingw/
- if defined?($extlist)
- build_dir = "$(TARGET_SO_DIR)../"
- else
- base_dir = File.expand_path('../../../..', __FILE__)
- build_dir = File.join(base_dir, "tmp", RUBY_PLATFORM, "bigdecimal", RUBY_VERSION, "")
- end
- $libs << " #{build_dir}bigdecimal.so"
- true
- when /mswin/
- $DLDFLAGS << " -libpath:.."
- $libs << " bigdecimal-$(arch).lib"
- true
- else
- false
- end
-end
-
-create_makefile('bigdecimal/util')
diff --git a/ext/bigdecimal/util/util.c b/ext/bigdecimal/util/util.c
deleted file mode 100644
index 8d38d87852..0000000000
--- a/ext/bigdecimal/util/util.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "ruby.h"
-
-RUBY_EXTERN VALUE rmpd_util_str_to_d(VALUE str);
-
-void
-Init_util(void)
-{
- rb_define_method(rb_cString, "to_d", rmpd_util_str_to_d, 0);
-}