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



Reply via email to