[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