Browse Source

Try to ENABLE floating point, lack %g support.

HuangRui 9 years ago
parent
commit
530e964d95
7 changed files with 325 additions and 6 deletions
  1. 1 1
      app/include/user_config.h
  2. 115 0
      app/libc/c_math.c
  3. 4 0
      app/libc/c_math.h
  4. 201 2
      app/libc/c_stdlib.c
  5. 2 2
      app/libc/c_stdlib.h
  6. 1 0
      app/lua/lvm.c
  7. 1 1
      ld/eagle.app.v6.ld

+ 1 - 1
app/include/user_config.h

@@ -67,7 +67,7 @@
 #define LUA_USE_MODULES_MQTT
 #endif /* LUA_USE_MODULES */
 
-#define LUA_NUMBER_INTEGRAL
+// #define LUA_NUMBER_INTEGRAL
 
 #define LUA_OPTRAM
 #ifdef LUA_OPTRAM

+ 115 - 0
app/libc/c_math.c

@@ -1,6 +1,121 @@
 #include "c_math.h"
 #include "c_types.h"
 
+double floor(double x){
+	return (double) (x < 0.f ? (((int) x) - 1) : ((int) x)); 
+}
+
+double pow(double x, double y){
+#define MAXEXP 2031		/* (MAX_EXP * 16) - 1			*/
+#define MINEXP -2047		/* (MIN_EXP * 16) - 1			*/
+#define HUGE MAXFLOAT
+double a1[] = {
+	1.0,
+	0.95760328069857365,
+	0.91700404320467123,
+	0.87812608018664974,
+	0.84089641525371454,
+	0.80524516597462716,
+	0.77110541270397041,
+	0.73841307296974966,
+	0.70710678118654752,
+	0.67712777346844637,
+	0.64841977732550483,
+	0.62092890603674203,
+	0.59460355750136054,
+	0.56939431737834583,
+	0.54525386633262883,
+	0.52213689121370692,
+	0.50000000000000000
+};
+double a2[] = {
+	 0.24114209503420288E-17,
+	 0.92291566937243079E-18,
+	-0.15241915231122319E-17,
+	-0.35421849765286817E-17,
+	-0.31286215245415074E-17,
+	-0.44654376565694490E-17,
+	 0.29306999570789681E-17,
+	 0.11260851040933474E-17
+};
+double p1 = 0.833333333333332114e-1;
+double p2 = 0.125000000005037992e-1;
+double p3 = 0.223214212859242590e-2;
+double p4 = 0.434457756721631196e-3;
+double q1 = 0.693147180559945296e0;
+double q2 = 0.240226506959095371e0;
+double q3 = 0.555041086640855953e-1;
+double q4 = 0.961812905951724170e-2;
+double q5 = 0.133335413135857847e-2;
+double q6 = 0.154002904409897646e-3;
+double q7 = 0.149288526805956082e-4;
+double k = 0.442695040888963407;
+	
+    double frexp(), g, ldexp(), r, u1, u2, v, w, w1, w2, y1, y2, z;
+    int iw1, m, p;
+
+    if (y == 0.0)
+	return(1.0);
+    if (x <= 0.0) {
+	if (x == 0.0) {
+	    if (y > 0.0)
+		return(x);
+	    //cmemsg(FP_POWO, &y);
+	    //return(HUGE);
+	}
+	else {
+	    //cmemsg(FP_POWN, &x);
+	    x = -x;
+	}
+    }
+    g = frexp(x, &m);
+    p = 0;
+    if (g <= a1[8])
+	p = 8;
+    if (g <= a1[p + 4])
+	p += 4;
+    if (g <= a1[p + 2])
+	p += 2;
+    p++;
+    z = ((g - a1[p]) - a2[p / 2]) / (g + a1[p]);
+    z += z;
+    v = z * z;
+    r = (((p4 * v + p3) * v + p2) * v + p1) * v * z;
+    r += k * r;
+    u2 = (r + z * k) + z;
+    u1 = 0.0625 * (double)(16 * m - p);
+    y1 = 0.0625 * (double)((int)(16.0 * y));
+    y2 = y - y1;
+    w = u2 * y + u1 * y2;
+    w1 = 0.0625 * (double)((int)(16.0 * w));
+    w2 = w - w1;
+    w = w1 + u1 * y1;
+    w1 = 0.0625 * (double)((int)(16.0 * w));
+    w2 += (w - w1);
+    w = 0.0625 * (double)((int)(16.0 * w2));
+    iw1 = 16.0 * (w1 + w);
+    w2 -= w;
+    while (w2 > 0.0) {
+	iw1++;
+	w2 -= 0.0625;
+    }
+    if (iw1 > MAXEXP) {
+	//cmemsg(FP_POWO, &y);
+	return(HUGE);
+    }
+    if (iw1 < MINEXP) {
+	//cmemsg(FP_POWU, &y);
+	return(0.0);
+    }
+    m = iw1 / 16;
+    if (iw1 >= 0)
+	m++;	
+    p = 16 * m - iw1;
+    z = ((((((q7*w2 + q6)*w2 + q5)*w2 + q4)*w2 + q3)*w2 + q2)*w2 + q1)*w2;
+    z = a1[p] + a1[p] * z;
+    return(ldexp(z, m));
+}
+
 #if 0
 #ifndef __math_68881
 double atan(double x){

+ 4 - 0
app/libc/c_math.h

@@ -1,6 +1,10 @@
 #ifndef  _C_MATH_H_
 #define  _C_MATH_H_
 #include <math.h>
+
+double floor(double);
+double pow(double, double);
+
 #if 0
 #ifndef HUGE_VAL
   #define HUGE_VAL (1.0e99)

+ 201 - 2
app/libc/c_stdlib.c

@@ -50,8 +50,207 @@ const char *c_getenv(const char *__string){
 
 // int	c_atoi(const char *__nptr){
 // }
-// double	c_strtod(const char *__n, char **__end_PTR){
-// }
+#include <_ansi.h>
+//#include <reent.h>
+#include <string.h>
+//#include "mprec.h"
+
+double c_strtod(const char *string, char **endPtr) 
+{
+	int maxExponent = 511;	/* Largest possible base 10 exponent.  Any
+				 * exponent larger than this will already
+				 * produce underflow or overflow, so there's
+				 * no need to worry about additional digits.
+				 */
+    double powersOf10[] = {	/* Table giving binary powers of 10.  Entry */
+    10.,			/* is 10^2^i.  Used to convert decimal */
+    100.,			/* exponents into floating-point numbers. */
+    1.0e4,
+    1.0e8,
+    1.0e16,
+    1.0e32,
+    1.0e64,
+    1.0e128,
+    1.0e256
+    };
+    int sign, expSign = FALSE;
+    double fraction, dblExp, *d;
+    register const char *p;
+    register int c;
+    int exp = 0;		/* Exponent read from "EX" field. */
+    int fracExp = 0;		/* Exponent that derives from the fractional
+				 * part.  Under normal circumstatnces, it is
+				 * the negative of the number of digits in F.
+				 * However, if I is very long, the last digits
+				 * of I get dropped (otherwise a long I with a
+				 * large negative exponent could cause an
+				 * unnecessary overflow on I alone).  In this
+				 * case, fracExp is incremented one for each
+				 * dropped digit. */
+    int mantSize;		/* Number of digits in mantissa. */
+    int decPt;			/* Number of mantissa digits BEFORE decimal
+				 * point. */
+    const char *pExp;		/* Temporarily holds location of exponent
+				 * in string. */
+
+    /*
+     * Strip off leading blanks and check for a sign.
+     */
+
+    p = string;
+    while (isspace((unsigned char)(*p))) {
+	p += 1;
+    }
+    if (*p == '-') {
+	sign = TRUE;
+	p += 1;
+    } else {
+	if (*p == '+') {
+	    p += 1;
+	}
+	sign = FALSE;
+    }
+
+    /*
+     * Count the number of digits in the mantissa (including the decimal
+     * point), and also locate the decimal point.
+     */
+
+    decPt = -1;
+    for (mantSize = 0; ; mantSize += 1)
+    {
+	c = *p;
+	if (!isdigit(c)) {
+	    if ((c != '.') || (decPt >= 0)) {
+		break;
+	    }
+	    decPt = mantSize;
+	}
+	p += 1;
+    }
+
+    /*
+     * Now suck up the digits in the mantissa.  Use two integers to
+     * collect 9 digits each (this is faster than using floating-point).
+     * If the mantissa has more than 18 digits, ignore the extras, since
+     * they can't affect the value anyway.
+     */
+    
+    pExp  = p;
+    p -= mantSize;
+    if (decPt < 0) {
+	decPt = mantSize;
+    } else {
+	mantSize -= 1;			/* One of the digits was the point. */
+    }
+    if (mantSize > 18) {
+	fracExp = decPt - 18;
+	mantSize = 18;
+    } else {
+	fracExp = decPt - mantSize;
+    }
+    if (mantSize == 0) {
+	fraction = 0.0;
+	p = string;
+	goto done;
+    } else {
+	int frac1, frac2;
+	frac1 = 0;
+	for ( ; mantSize > 9; mantSize -= 1)
+	{
+	    c = *p;
+	    p += 1;
+	    if (c == '.') {
+		c = *p;
+		p += 1;
+	    }
+	    frac1 = 10*frac1 + (c - '0');
+	}
+	frac2 = 0;
+	for (; mantSize > 0; mantSize -= 1)
+	{
+	    c = *p;
+	    p += 1;
+	    if (c == '.') {
+		c = *p;
+		p += 1;
+	    }
+	    frac2 = 10*frac2 + (c - '0');
+	}
+	fraction = (1.0e9 * frac1) + frac2;
+    }
+
+    /*
+     * Skim off the exponent.
+     */
+
+    p = pExp;
+    if ((*p == 'E') || (*p == 'e')) {
+	p += 1;
+	if (*p == '-') {
+	    expSign = TRUE;
+	    p += 1;
+	} else {
+	    if (*p == '+') {
+		p += 1;
+	    }
+	    expSign = FALSE;
+	}
+	if (!isdigit((unsigned char)(*p))) {
+	    p = pExp;
+	    goto done;
+	}
+	while (isdigit((unsigned char)(*p))) {
+	    exp = exp * 10 + (*p - '0');
+	    p += 1;
+	}
+    }
+    if (expSign) {
+	exp = fracExp - exp;
+    } else {
+	exp = fracExp + exp;
+    }
+
+    /*
+     * Generate a floating-point number that represents the exponent.
+     * Do this by processing the exponent one bit at a time to combine
+     * many powers of 2 of 10. Then combine the exponent with the
+     * fraction.
+     */
+    
+    if (exp < 0) {
+	expSign = TRUE;
+	exp = -exp;
+    } else {
+	expSign = FALSE;
+    }
+    if (exp > maxExponent) {
+	exp = maxExponent;
+	// errno = ERANGE;
+    }
+    dblExp = 1.0;
+    for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
+	if (exp & 01) {
+	    dblExp *= *d;
+	}
+    }
+    if (expSign) {
+	fraction /= dblExp;
+    } else {
+	fraction *= dblExp;
+    }
+
+done:
+    if (endPtr != NULL) {
+	*endPtr = (char *) p;
+    }
+
+    if (sign) {
+	return -fraction;
+    }
+    return fraction;
+}
+
 // long	c_strtol(const char *__n, char **__end_PTR, int __base){
 // }
 // unsigned long c_strtoul(const char *__n, char **__end_PTR, int __base){

+ 2 - 2
app/libc/c_stdlib.h

@@ -36,7 +36,7 @@
 
 #define c_abs	abs
 #define c_atoi	atoi
-// #define c_strtod	strtod
+//#define c_strtod	strtod
 #define c_strtol	strtol
 #define c_strtoul	strtoul
 
@@ -55,7 +55,7 @@ void c_free(void *);
 // void c_srand(unsigned int __seed);
 
 // int	c_atoi(const char *__nptr);
-// double	c_strtod(const char *__n, char **__end_PTR);
+double	c_strtod(const char *__n, char **__end_PTR);
 // // long	c_strtol(const char *__n, char **__end_PTR, int __base);
 // unsigned long c_strtoul(const char *__n, char **__end_PTR, int __base);
 // // long long c_strtoll(const char *__n, char **__end_PTR, int __base);

+ 1 - 0
app/lua/lvm.c

@@ -8,6 +8,7 @@
 #include "c_stdio.h"
 #include "c_stdlib.h"
 #include "c_string.h"
+#include "c_math.h"
 
 #define lvm_c
 #define LUA_CORE

+ 1 - 1
ld/eagle.app.v6.ld

@@ -5,7 +5,7 @@ MEMORY
   dport0_0_seg :                      	org = 0x3FF00000, len = 0x10
   dram0_0_seg :                       	org = 0x3FFE8000, len = 0x14000
   iram1_0_seg :                       	org = 0x40100000, len = 0x8000
-  irom0_0_seg :                       	org = 0x40210000, len = 0x50000
+  irom0_0_seg :                       	org = 0x40210000, len = 0x51000
 }
 
 PHDRS