Module: wine Branch: master Commit: 9b9f7a007786b32a4c80f69ceb6753acdc8c2091 URL: https://gitlab.winehq.org/wine/wine/-/commit/9b9f7a007786b32a4c80f69ceb6753a...
Author: Zebediah Figura zfigura@codeweavers.com Date: Tue Nov 21 15:59:41 2023 -0600
msvcrt: Perform a base-10 logarithm using integer math.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55918
---
dlls/msvcrt/bnum.h | 2 +- dlls/msvcrt/printf.h | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/dlls/msvcrt/bnum.h b/dlls/msvcrt/bnum.h index a1d3133c3e6..3e42f61e3e1 100644 --- a/dlls/msvcrt/bnum.h +++ b/dlls/msvcrt/bnum.h @@ -22,7 +22,7 @@ #define EXP_BITS 11 #define MANT_BITS 53
-static const int p10s[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; +static const int p10s[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
#define LIMB_DIGITS 9 /* each DWORD stores up to 9 digits */ #define LIMB_MAX 1000000000 /* 10^9 */ diff --git a/dlls/msvcrt/printf.h b/dlls/msvcrt/printf.h index c34479c5688..be30d6ae719 100644 --- a/dlls/msvcrt/printf.h +++ b/dlls/msvcrt/printf.h @@ -135,6 +135,20 @@ static inline int mbstowcs_len(wchar_t *wcstr, const char *mbstr, } return wlen; } + +static inline unsigned int log2i(unsigned int x) +{ + ULONG result; + _BitScanReverse(&result, x); + return result; +} + +static inline unsigned int log10i(unsigned int x) +{ + unsigned int t = ((log2i(x) + 1) * 1233) / 4096; + return t - (x < p10s[t]); +} + #endif
static inline int FUNC_NAME(pf_output_wstr)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, @@ -635,7 +649,7 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu if(!b->data[bnum_idx(b, b->e-1)]) first_limb_len = 1; else - first_limb_len = floor(log10(b->data[bnum_idx(b, b->e - 1)])) + 1; + first_limb_len = log10i(b->data[bnum_idx(b, b->e - 1)]) + 1; radix_pos = first_limb_len + LIMB_DIGITS + e10;
round_pos = flags->Precision; @@ -700,7 +714,7 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu if(!b->data[bnum_idx(b, b->e-1)]) i = 1; else - i = floor(log10(b->data[bnum_idx(b, b->e-1)])) + 1; + i = log10i(b->data[bnum_idx(b, b->e-1)]) + 1; if(i != first_limb_len) { first_limb_len = i; radix_pos++;