Piotr Caban : msvcrt: Improved scanf precision.

Alexandre Julliard julliard at winehq.org
Mon Nov 5 13:32:25 CST 2012


Module: wine
Branch: master
Commit: 74ec93bab77d387018f170ae2e3576329ae207e1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=74ec93bab77d387018f170ae2e3576329ae207e1

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Nov  5 11:40:20 2012 +0100

msvcrt: Improved scanf precision.

---

 dlls/msvcrt/scanf.h |   23 +++++++++++++++++++++--
 1 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/dlls/msvcrt/scanf.h b/dlls/msvcrt/scanf.h
index 89fdac3..7f618f4 100644
--- a/dlls/msvcrt/scanf.h
+++ b/dlls/msvcrt/scanf.h
@@ -310,9 +310,11 @@ _FUNCTION_ {
             case 'f':
             case 'g':
             case 'G': { /* read a float */
-                    long double cur;
+                    long double cur = 1, expcnt = 10;
                     ULONGLONG d, hlp;
                     int exp = 0, negative = 0;
+                    unsigned fpcontrol;
+                    BOOL negexp;
 
                     /* skip initial whitespace */
                     while ((nch!=_EOF_) && _ISSPACE_(nch))
@@ -401,7 +403,24 @@ _FUNCTION_ {
                         else exp += e;
                     }
 
-                    cur = (exp>=0 ? d*pow(10, exp) : d/pow(10, -exp));
+                    fpcontrol = _control87(0, 0);
+                    _control87(MSVCRT__EM_DENORMAL|MSVCRT__EM_INVALID|MSVCRT__EM_ZERODIVIDE
+                            |MSVCRT__EM_OVERFLOW|MSVCRT__EM_UNDERFLOW|MSVCRT__EM_INEXACT, 0xffffffff);
+
+                    negexp = (exp < 0);
+                    if(negexp)
+                        exp = -exp;
+                    /* update 'cur' with this exponent. */
+                    while(exp) {
+                        if(exp & 1)
+                            cur *= expcnt;
+                        exp /= 2;
+                        expcnt = expcnt*expcnt;
+                    }
+                    cur = (negexp ? d/cur : d*cur);
+
+                    _control87(fpcontrol, 0xffffffff);
+
                     st = 1;
                     if (!suppress) {
                         if (L_prefix) _SET_NUMBER_(double);




More information about the wine-cvs mailing list