[#7708] Bug in libsnmp-ruby1.8 — Hadmut Danisch <hadmut@...>

Hi,

8 messages 2006/04/11
[#7709] Re: Bug in libsnmp-ruby1.8 — Eric Hodel <drbrain@...7.net> 2006/04/11

On Apr 11, 2006, at 6:23 AM, Hadmut Danisch wrote:

[#7770] Re: possible defect in array.c — "Brown, Warren" <warrenbrown@...>

> rb_range_beg_len (in range.c) does set beg and len.

13 messages 2006/04/26
[#7771] Re: possible defect in array.c — "Pat Eyler" <rubypate@...> 2006/04/26

On 4/26/06, Brown, Warren <warrenbrown@aquire.com> wrote:

Re: [ ruby-Bugs-4284 ] Float near Float::MIN

From: Yukihiro Matsumoto <matz@...>
Date: 2006-04-28 01:59:29 UTC
List: ruby-core #7797
Hi,

In message "Re: [ ruby-Bugs-4284 ] Float near Float::MIN"
    on Fri, 28 Apr 2006 04:14:47 +0900, noreply@rubyforge.org writes:

|3. comment:
|since 2.2250738585072e-308 is a legitimate Floating point number, and meant to be the smallest above zero, I would expect 1e-307, which is more than that to be working correctly.  But I get:
|- a weird warning which should not occur
|- a wrong output which is off about by a factor of 10**16
|- a output which should not be a legitimate Float, because it is between 0 and Float::MIN

The built-in strtod() function cut off exponent digits too early.
This is a patch to fix this.

							matz.

--- util.c	17 Feb 2006 02:21:35 -0000	1.50
+++ util.c	28 Apr 2006 01:56:38 -0000
@@ -17,2 +17,3 @@
 #include <errno.h>
+#include <math.h>
 
@@ -666,18 +667,4 @@ ruby_getcwd(void)
 
-#define TRUE 1
-#define FALSE 0
-
 static  int     MDMINEXPT       = -323;
-static  int     MDMAXEXPT       =  309;
-static double powersOf10[] = {	/* Table giving binary powers of 10.  Entry */
-    10.0,			/* is 10^2^i.  Used to convert decimal */
-    100.0,			/* exponents into floating-point numbers. */
-    1.0e4,
-    1.0e8,
-    1.0e16,
-    1.0e32,
-    1.0e64,
-    1.0e128,
-    1.0e256
-};
+static  int     MDMAXEXPT       = 309;
 
@@ -722,4 +709,4 @@ ruby_strtod(
 {
-    int sign, expSign = FALSE;
-    double fraction, dblExp, *d;
+    int sign, expSign = Qfalse;
+    double fraction = 0.0, dblExp;
     register const char *p;
@@ -737,4 +724,4 @@ ruby_strtod(
     int mantSize = 0;		/* Number of digits in mantissa. */
-    int hasPoint = FALSE;	/* Decimal point exists. */
-    int hasDigit = FALSE;	/* I or F exists. */
+    int hasPoint = Qfalse;	/* Decimal point exists. */
+    int hasDigit = Qfalse;	/* I or F exists. */
     const char *pMant;		/* Temporarily holds location of mantissa
@@ -754,3 +741,3 @@ ruby_strtod(
     if (*p == '-') {
-	sign = TRUE;
+	sign = Qtrue;
 	p += 1;
@@ -761,3 +748,3 @@ ruby_strtod(
 	}
-	sign = FALSE;
+	sign = Qfalse;
     }
@@ -774,3 +761,3 @@ ruby_strtod(
 	    }
-	    hasPoint = TRUE;
+	    hasPoint = Qtrue;
 	}
@@ -787,3 +774,3 @@ ruby_strtod(
 	    }
-	    hasDigit = TRUE;
+	    hasDigit = Qtrue;
 	}
@@ -811,3 +798,3 @@ ruby_strtod(
     else {
-	int frac1, frac2;
+	double frac1, frac2;
 	frac1 = 0;
@@ -841,3 +828,3 @@ ruby_strtod(
 	    if (*p == '-') {
-		expSign = TRUE;
+		expSign = Qtrue;
 		p += 1;
@@ -848,3 +835,3 @@ ruby_strtod(
 		}
-		expSign = FALSE;
+		expSign = Qfalse;
 	    }
@@ -875,34 +862,35 @@ ruby_strtod(
     
-	if (exp >= MDMAXEXPT - 18) {
-	    exp = MDMAXEXPT;
+	if (exp >= MDMAXEXPT) {
 	    errno = ERANGE;
+	    return HUGE_VAL * (sign ? -1.0 : 1.0);
 	}
-	else if (exp < MDMINEXPT + 18) {
-	    exp = MDMINEXPT;
+	else if (exp < MDMINEXPT) {
 	    errno = ERANGE;
+	    return 0.0 * (sign ? -1.0 : 1.0);
 	}
-	fracExp = exp;
-	exp += 9;
-	if (exp < 0) {
-	    expSign = TRUE;
-	    exp = -exp;
-	}
-	else {
-	    expSign = FALSE;
-	}
-	dblExp = 1.0;
-	for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
-	    if (exp & 01) {
-		dblExp *= *d;
+	if (frac1 > 0) {
+	    fracExp = exp;
+	    exp += 9;
+	    if (exp < 0) {
+		expSign = Qtrue;
+		exp = -exp;
 	    }
+	    else {
+		expSign = Qfalse;
+	    }
+	    dblExp = 10.0;
+	    while (exp) {
+		if (exp & 1) {
+		    if (expSign)
+			frac1 /= dblExp;
+		    else
+			frac1 *= dblExp;
+		}
+		exp >>= 1;
+		dblExp *= dblExp;
+	    }
+	    fraction = frac1;
 	}
-	if (expSign) {
-	    fraction = frac1 / dblExp;
-	}
-	else {
-	    fraction = frac1 * dblExp;
-	}
-	exp = fracExp;
 	if (exp < 0) {
-	    expSign = TRUE;
+	    expSign = Qtrue;
 	    exp = -exp;
@@ -910,16 +898,17 @@ ruby_strtod(
 	else {
-	    expSign = FALSE;
+	    expSign = Qfalse;
 	}
-	dblExp = 1.0;
-	for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
-	    if (exp & 01) {
-		dblExp *= *d;
+	dblExp = 10.0;
+	while (exp) 
+	{
+	    if (exp & 1) {
+		if (expSign)
+		    frac2 /= dblExp;
+		else
+		    frac2 *= dblExp;
 	    }
+	    exp >>= 1;
+	    dblExp *= dblExp;
 	}
-	if (expSign) {
-	    fraction += frac2 / dblExp;
-	}
-	else {
-	    fraction += frac2 * dblExp;
-	}
+	fraction += frac2;
     }

In This Thread

Prev Next