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