Piotr Caban : msvcrt: Fix NAN handling in printf.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Mar 25 10:13:23 CDT 2015


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

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Mar 25 14:22:02 2015 +0100

msvcrt: Fix NAN handling in printf.

---

 dlls/msvcrt/printf.h | 43 +++++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/dlls/msvcrt/printf.h b/dlls/msvcrt/printf.h
index 80133d6..4757931 100644
--- a/dlls/msvcrt/printf.h
+++ b/dlls/msvcrt/printf.h
@@ -26,6 +26,10 @@
 #define FUNC_NAME(func) func ## _a
 #endif
 
+#ifndef signbit
+#define signbit(x) ((x) < 0)
+#endif
+
 typedef struct FUNC_NAME(pf_flags_t)
 {
     APICHAR Sign, LeftAlign, Alternate, PadZero;
@@ -539,19 +543,23 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
             int len = flags.Precision + 10;
             double val = pf_args(args_ctx, pos, VT_R8, valist).get_double;
             int r;
-            BOOL inf = FALSE, nan = FALSE;
+            BOOL inf = FALSE, nan = FALSE, ind = FALSE;
 
             if(isinf(val))
                 inf = TRUE;
-            else if(isnan(val))
-                nan = TRUE; /* FIXME: NaN value may be displayed as #IND or #QNAN */
+            else if(isnan(val)) {
+                if(!signbit(val))
+                    nan = TRUE;
+                else
+                    ind = TRUE;
+            }
 
-            if(inf || nan) {
-                if(nan || val<0)
+            if(inf || nan || ind) {
+                if(ind || val<0)
                     flags.Sign = '-';
 
                 if(flags.Format=='g' || flags.Format=='G')
-                    val = 1.1234; /* fraction will be overwritten with #INF or #IND string */
+                    val = (nan ? 1.12345 : 1.1234); /* fraction will be overwritten with #INF, #IND or #QNAN string */
                 else
                     val = 1;
 
@@ -592,18 +600,33 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
             if(decimal_point) {
                 *decimal_point = *locinfo->lconv->decimal_point;
 
-                if(inf || nan) {
+                if(inf || nan || ind) {
                     static const char inf_str[] = "#INF";
                     static const char ind_str[] = "#IND";
+                    static const char nan_str[] = "#QNAN";
+
+                    const char *str;
+                    int size;
+
+                    if(inf) {
+                        str = inf_str;
+                        size = sizeof(inf_str);
+                    }else if(ind) {
+                        str = ind_str;
+                        size = sizeof(ind_str);
+                    }else {
+                        str = nan_str;
+                        size = sizeof(nan_str);
+                    }
 
-                    for(i=1; i<(inf ? sizeof(inf_str) : sizeof(ind_str)); i++) {
+                    for(i=1; i<size; i++) {
                         if(decimal_point[i]<'0' || decimal_point[i]>'9')
                             break;
 
-                        decimal_point[i] = inf ? inf_str[i-1] : ind_str[i-1];
+                        decimal_point[i] = str[i-1];
                     }
 
-                    if(i!=sizeof(inf_str) && i!=1)
+                    if(i!=size && i!=1)
                         decimal_point[i-1]++;
                 }
             }




More information about the wine-cvs mailing list