From 2ad4b883f9add0f593100c5cc381b342497923f1 Mon Sep 17 00:00:00 2001 From: zhaoyanbai Date: Sat, 15 Aug 2026 09:48:05 +0800 Subject: [PATCH] =?utf8?q?=E4=BF=AE=E5=A4=8D=E6=A0=BC=E5=BC=8F=E5=8C=96?= =?utf8?q?=E6=97=B6=E5=B0=8664=E4=BD=8D=E6=95=B4=E5=9E=8B=E6=95=B0?= =?utf8?q?=E5=AD=97=E8=BD=AC=E6=8D=A2=E4=B8=BA=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?utf8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- lib/vsprintf.c | 50 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 2150486..fd667b2 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -157,13 +157,53 @@ char* itoa(char* s, int n) { return s; } +static void _udiv64(uint64_t dividend, uint64_t divisor, uint64_t* quotient, uint64_t* remainder) { + uint64_t _quotient = 0; + uint64_t _remainder = 0; + + // 整体算法类似10进的除法,只不过换成二进制的数来算 + // 10进制需要猜能乘几,而二进制不用猜,只有0和1,所以直接比较大小即可 + for (int i = 63; i >= 0; i--) { + // 以下两行可以看成类似10进制除法的被除数从高往低试除数时,被除数被逐渐试的高位数 + _remainder <<= 1; + _remainder |= (dividend >> i) & 1; + + // 如果这部分高位数能比被除数大,则商的对应位为1,否则为0 + if (_remainder >= divisor) { + _remainder -= divisor; + _quotient |= (1ULL << i); + } else { + // 商为0的比特位其实什么都不用做 + } + } + + if (quotient) { + *quotient = _quotient; + } + + if (remainder) { + *remainder = _remainder; + } +} + char* i64tou(char* s, uint64_t n) { - itou(s, n >> 32); - int i = 0; - if ((n >> 32) > 0) { - i = strlen(s); + char* p = s; + char* h = s; + + do { + uint64_t remainder = 0; + _udiv64(n, 10, &n, &remainder); + *p++ = remainder + '0'; + } while (n > 0); + + *p = 0; + p--; + + while (h < p) { + swap_char(h, p); + h++; + p--; } - itou(s + i, n & 0xFFFFFFFF); return s; } -- 2.55.0