Piotr Caban : msvcrt: Move big numbers implementation to new file.

Alexandre Julliard julliard at winehq.org
Mon Jul 13 16:08:49 CDT 2020


Module: wine
Branch: master
Commit: ec148864d6a6d47b319fe8bc79ae30d25d01c8ba
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=ec148864d6a6d47b319fe8bc79ae30d25d01c8ba

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Sat Jul 11 18:41:13 2020 +0200

msvcrt: Move big numbers implementation to new file.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/bnum.h   | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++
 dlls/msvcrt/string.c | 116 +------------------------------------------
 2 files changed, 138 insertions(+), 114 deletions(-)

diff --git a/dlls/msvcrt/bnum.h b/dlls/msvcrt/bnum.h
new file mode 100644
index 0000000000..b66ebf04ec
--- /dev/null
+++ b/dlls/msvcrt/bnum.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2020 Piotr Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_BNUM_H
+#define __WINE_BNUM_H
+
+#define EXP_BITS 11
+#define MANT_BITS 53
+
+static const int p10s[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
+
+#define LIMB_DIGITS 9           /* each DWORD stores up to 9 digits */
+#define LIMB_MAX 1000000000     /* 10^9 */
+#define BNUM_IDX(i) ((i) & 127)
+/* bnum represents real number with fixed decimal point (after 2 limbs) */
+struct bnum {
+    DWORD data[128]; /* circular buffer, base 10 number */
+    int b; /* least significant digit position */
+    int e; /* most significant digit position + 1 */
+};
+
+/* Returns integral part of bnum */
+static inline ULONGLONG bnum_to_mant(struct bnum *b)
+{
+    ULONGLONG ret = (ULONGLONG)b->data[BNUM_IDX(b->e-1)] * LIMB_MAX;
+    if(b->b != b->e-1) ret += b->data[BNUM_IDX(b->e-2)];
+    return ret;
+}
+
+/* Returns TRUE if new most significant limb was added */
+static inline BOOL bnum_lshift(struct bnum *b, int shift)
+{
+    DWORD rest = 0;
+    ULONGLONG tmp;
+    int i;
+
+    /* The limbs number can change by up to 1 so shift <= 29 */
+    assert(shift <= 29);
+
+    for(i=b->b; i<b->e; i++) {
+        tmp = ((ULONGLONG)b->data[BNUM_IDX(i)] << shift) + rest;
+        rest = tmp / LIMB_MAX;
+        b->data[BNUM_IDX(i)] = tmp % LIMB_MAX;
+
+        if(i == b->b && !b->data[BNUM_IDX(i)])
+            b->b++;
+    }
+
+    if(rest) {
+        b->data[BNUM_IDX(b->e)] = rest;
+        b->e++;
+
+        if(BNUM_IDX(b->b) == BNUM_IDX(b->e)) {
+            if(b->data[BNUM_IDX(b->b)]) b->data[BNUM_IDX(b->b+1)] |= 1;
+            b->b++;
+        }
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/* Returns TRUE if most significant limb was removed */
+static inline BOOL bnum_rshift(struct bnum *b, int shift)
+{
+    DWORD tmp, rest = 0;
+    BOOL ret = FALSE;
+    int i;
+
+    /* Compute LIMB_MAX << shift without accuracy loss */
+    assert(shift <= 9);
+
+    for(i=b->e-1; i>=b->b; i--) {
+        tmp = b->data[BNUM_IDX(i)] & ((1<<shift)-1);
+        b->data[BNUM_IDX(i)] = (b->data[BNUM_IDX(i)] >> shift) + rest;
+        rest = (LIMB_MAX >> shift) * tmp;
+        if(i==b->e-1 && !b->data[BNUM_IDX(i)]) {
+            b->e--;
+            ret = TRUE;
+        }
+    }
+
+    if(rest) {
+        if(BNUM_IDX(b->b-1) == BNUM_IDX(b->e)) {
+            if(rest) b->data[BNUM_IDX(b->b)] |= 1;
+        } else {
+            b->b--;
+            b->data[BNUM_IDX(b->b)] = rest;
+        }
+    }
+    return ret;
+}
+
+static inline void bnum_mult(struct bnum *b, int mult)
+{
+    DWORD rest = 0;
+    ULONGLONG tmp;
+    int i;
+
+    assert(mult <= LIMB_MAX);
+
+    for(i=b->b; i<b->e; i++) {
+        tmp = ((ULONGLONG)b->data[BNUM_IDX(i)] * mult) + rest;
+        rest = tmp / LIMB_MAX;
+        b->data[BNUM_IDX(i)] = tmp % LIMB_MAX;
+
+        if(i == b->b && !b->data[BNUM_IDX(i)])
+            b->b++;
+    }
+
+    if(rest) {
+        b->data[BNUM_IDX(b->e)] = rest;
+        b->e++;
+
+        if(BNUM_IDX(b->b) == BNUM_IDX(b->e)) {
+            if(b->data[BNUM_IDX(b->b)]) b->data[BNUM_IDX(b->b+1)] |= 1;
+            b->b++;
+        }
+    }
+}
+
+#endif /* __WINE_BNUM_H */
diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c
index 1e3e0d15bf..62ec54607e 100644
--- a/dlls/msvcrt/string.c
+++ b/dlls/msvcrt/string.c
@@ -32,6 +32,7 @@
 #include <limits.h>
 #include <errno.h>
 #include "msvcrt.h"
+#include "bnum.h"
 #include "winnls.h"
 #include "wine/debug.h"
 
@@ -353,8 +354,6 @@ enum round {
 
 static double make_double(int sign, int exp, ULONGLONG m, enum round round, int *err)
 {
-#define EXP_BITS 11
-#define MANT_BITS 53
     ULONGLONG bits = 0;
 
     TRACE("%c %s *2^%d (round %d)\n", sign == -1 ? '-' : '+', wine_dbgstr_longlong(m), exp, round);
@@ -572,120 +571,9 @@ static double strtod16(MSVCRT_wchar_t get(void *ctx), void unget(void *ctx),
 }
 #endif
 
-#define LIMB_DIGITS 9           /* each DWORD stores up to 9 digits */
-#define LIMB_MAX 1000000000     /* 10^9 */
-#define BNUM_IDX(i) ((i) & 127)
-/* bnum represents real number with fixed decimal point (after 2 limbs) */
-struct bnum {
-    DWORD data[128]; /* circular buffer, base 10 number */
-    int b; /* least significant digit position */
-    int e; /* most significant digit position + 1 */
-};
-
-/* Returns integral part of bnum */
-static inline ULONGLONG bnum_to_mant(struct bnum *b)
-{
-    ULONGLONG ret = (ULONGLONG)b->data[BNUM_IDX(b->e-1)] * LIMB_MAX;
-    if(b->b != b->e-1) ret += b->data[BNUM_IDX(b->e-2)];
-    return ret;
-}
-
-/* Returns TRUE if new most significant limb was added */
-static inline BOOL bnum_lshift(struct bnum *b, int shift)
-{
-    DWORD rest = 0;
-    ULONGLONG tmp;
-    int i;
-
-    /* The limbs number can change by up to 1 so shift <= 29 */
-    assert(shift <= 29);
-
-    for(i=b->b; i<b->e; i++) {
-        tmp = ((ULONGLONG)b->data[BNUM_IDX(i)] << shift) + rest;
-        rest = tmp / LIMB_MAX;
-        b->data[BNUM_IDX(i)] = tmp % LIMB_MAX;
-
-        if(i == b->b && !b->data[BNUM_IDX(i)])
-            b->b++;
-    }
-
-    if(rest) {
-        b->data[BNUM_IDX(b->e)] = rest;
-        b->e++;
-
-        if(BNUM_IDX(b->b) == BNUM_IDX(b->e)) {
-            if(b->data[BNUM_IDX(b->b)]) b->data[BNUM_IDX(b->b+1)] |= 1;
-            b->b++;
-        }
-        return TRUE;
-    }
-    return FALSE;
-}
-
-/* Returns TRUE if most significant limb was removed */
-static inline BOOL bnum_rshift(struct bnum *b, int shift)
-{
-    DWORD tmp, rest = 0;
-    BOOL ret = FALSE;
-    int i;
-
-    /* Compute LIMB_MAX << shift without accuracy loss */
-    assert(shift <= 9);
-
-    for(i=b->e-1; i>=b->b; i--) {
-        tmp = b->data[BNUM_IDX(i)] & ((1<<shift)-1);
-        b->data[BNUM_IDX(i)] = (b->data[BNUM_IDX(i)] >> shift) + rest;
-        rest = (LIMB_MAX >> shift) * tmp;
-        if(i==b->e-1 && !b->data[BNUM_IDX(i)]) {
-            b->e--;
-            ret = TRUE;
-        }
-    }
-
-    if(rest) {
-        if(BNUM_IDX(b->b-1) == BNUM_IDX(b->e)) {
-            if(rest) b->data[BNUM_IDX(b->b)] |= 1;
-        } else {
-            b->b--;
-            b->data[BNUM_IDX(b->b)] = rest;
-        }
-    }
-    return ret;
-}
-
-static inline void bnum_mult(struct bnum *b, int mult)
-{
-    DWORD rest = 0;
-    ULONGLONG tmp;
-    int i;
-
-    assert(mult <= LIMB_MAX);
-
-    for(i=b->b; i<b->e; i++) {
-        tmp = ((ULONGLONG)b->data[BNUM_IDX(i)] * mult) + rest;
-        rest = tmp / LIMB_MAX;
-        b->data[BNUM_IDX(i)] = tmp % LIMB_MAX;
-
-        if(i == b->b && !b->data[BNUM_IDX(i)])
-            b->b++;
-    }
-
-    if(rest) {
-        b->data[BNUM_IDX(b->e)] = rest;
-        b->e++;
-
-        if(BNUM_IDX(b->b) == BNUM_IDX(b->e)) {
-            if(b->data[BNUM_IDX(b->b)]) b->data[BNUM_IDX(b->b+1)] |= 1;
-            b->b++;
-        }
-    }
-}
-
 double parse_double(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *ctx),
         void *ctx, MSVCRT_pthreadlocinfo locinfo, int *err)
 {
-    static const int p10s[] = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
-
 #if _MSVCR_VER >= 140
     MSVCRT_wchar_t _infinity[] = { 'i', 'n', 'f', 'i', 'n', 'i', 't', 'y', 0 };
     MSVCRT_wchar_t _nan[] = { 'n', 'a', 'n', 0 };
@@ -869,7 +757,7 @@ double parse_double(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *ctx),
         return make_double(sign, 0, b.data[BNUM_IDX(b.e-1)], ROUND_ZERO, err);
     off = (dp - limb_digits) % LIMB_DIGITS;
     if(off < 0) off += LIMB_DIGITS;
-    if(off) bnum_mult(&b, p10s[off-1]);
+    if(off) bnum_mult(&b, p10s[off]);
 
     if(!err) err = MSVCRT__errno();
     if(dp-1 > MSVCRT_DBL_MAX_10_EXP)




More information about the wine-cvs mailing list