Module: wine Branch: master Commit: 74ec93bab77d387018f170ae2e3576329ae207e1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=74ec93bab77d387018f170ae2e...
Author: Piotr Caban piotr@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);