[PATCH] msvcrt: Fix scanf floating-point exponent handling.

=?utf-8?q?J=C4=81nis=20R=C5=ABcis?= parasti at gmail.com
Fri Feb 15 15:09:52 CST 2008


This patch modifies the scanf floating-point algorithm to pass the tests
I sent in my previous message.

---
 dlls/msvcrt/scanf.h |   40 +++++++++++++++++++++++++---------------
 1 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/dlls/msvcrt/scanf.h b/dlls/msvcrt/scanf.h
index 7fe3cc4..66df15e 100644
--- a/dlls/msvcrt/scanf.h
+++ b/dlls/msvcrt/scanf.h
@@ -241,6 +241,12 @@ _FUNCTION_ {
             case 'G': { /* read a float */
                     long double cur = 0;
 		    int negative = 0;
+
+		    int decimal_places = 0;
+		    unsigned int exponent = 0;
+		    int negexp = 0;
+		    long double be;
+
                     /* skip initial whitespace */
                     while ((nch!=_EOF_) && _ISSPACE_(nch))
                         nch = _GETC_(file);
@@ -268,20 +274,17 @@ _FUNCTION_ {
 		    }
 		    /* handle decimals */
                     if (width!=0 && nch == '.') {
-                        float dec = 1;
                         nch = _GETC_(file);
 			if (width>0) width--;
                         while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) {
-                            dec /= 10;
-                            cur += dec * (nch - '0');
+                            cur = cur * 10 + (nch - '0');
+                            decimal_places += 1;
                             nch = _GETC_(file);
 			    if (width>0) width--;
                         }
                     }
 		    /* handle exponent */
 		    if (width!=0 && (nch == 'e' || nch == 'E')) {
-			int exponent = 0, negexp = 0;
-			float expcnt;
                         nch = _GETC_(file);
 			if (width>0) width--;
 			/* possible sign on the exponent */
@@ -292,20 +295,27 @@ _FUNCTION_ {
 			}
 			/* exponent digits */
 			while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) {
-			    exponent *= 10;
-			    exponent += (nch - '0');
+			    exponent = exponent * 10 + (nch - '0');
                             nch = _GETC_(file);
 			    if (width>0) width--;
                         }
-			/* update 'cur' with this exponent. */
-			expcnt =  negexp ? .1 : 10;
-			while (exponent!=0) {
-			    if (exponent&1)
-				cur*=expcnt;
-			    exponent/=2;
-			    expcnt=expcnt*expcnt;
-			}
 		    }
+
+		    /* Combine exponent with decimal point. */
+		    for (; decimal_places > 0; decimal_places--)
+		    {
+			if (exponent == 0)
+			    negexp = 1;
+
+			exponent += negexp ? +1 : -1;
+		    }
+
+		    /* Perform exponentiation. */
+		    for (be = 1.0; exponent > 0; exponent--)
+			be *= 10.0;
+
+		    cur = negexp ? cur / be : cur * be;
+
                     st = 1;
                     if (!suppress) {
 			if (L_prefix) _SET_NUMBER_(long double);
-- 
1.5.3.8




More information about the wine-devel mailing list