2006-04-22 Yoshinori K. Okuji <okuji@enbug.org>
* kern/misc.c (grub_lltoa): Rewritten the decimal conversion part, as it was simply too buggy.
This commit is contained in:
parent
970d3b8ab0
commit
49986a9f99
2 changed files with 32 additions and 16 deletions
|
@ -1,3 +1,8 @@
|
|||
2006-04-22 Yoshinori K. Okuji <okuji@enbug.org>
|
||||
|
||||
* kern/misc.c (grub_lltoa): Rewritten the decimal conversion part,
|
||||
as it was simply too buggy.
|
||||
|
||||
2006-04-21 Yoshinori K. Okuji <okuji@enbug.org>
|
||||
|
||||
* kern/misc.c (grub_lltoa): New function.
|
||||
|
|
43
kern/misc.c
43
kern/misc.c
|
@ -526,22 +526,33 @@ grub_lltoa (char *str, int c, unsigned long long n)
|
|||
/* BASE == 10 */
|
||||
do
|
||||
{
|
||||
unsigned high, low;
|
||||
unsigned high_mod, low_mod;
|
||||
unsigned d;
|
||||
|
||||
high = (unsigned) (n >> 32);
|
||||
low = (unsigned) (n & 0xffffffff);
|
||||
high_mod = high % 10;
|
||||
low_mod = low % 10;
|
||||
/* 6 = (1 << 32) % 10 */
|
||||
d = (high_mod * 6 + low_mod) % 10;
|
||||
*p++ = d + '0';
|
||||
|
||||
/* (HIGH_MOD << 31) / 5 = (HIGH_MOD << 32) / 10 */
|
||||
n = (((unsigned long long) (high / 10) << 32)
|
||||
+ ((high_mod << 31) / 5)
|
||||
+ low_mod / 10);
|
||||
/* This algorithm is typically implemented by hardware. The idea
|
||||
is to get the highest bit in N, 64 times, by keeping
|
||||
upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
|
||||
represents the high 64 bits in 128-bits space. */
|
||||
unsigned bits = sizeof (unsigned long long) * 8;
|
||||
unsigned long long q = 0;
|
||||
unsigned m = 0;
|
||||
|
||||
while (bits--)
|
||||
{
|
||||
m <<= 1;
|
||||
|
||||
if ((long long ) n < 0)
|
||||
m |= 1;
|
||||
|
||||
q <<= 1;
|
||||
n <<= 1;
|
||||
|
||||
if (m >= 10)
|
||||
{
|
||||
q |= 1;
|
||||
m -= 10;
|
||||
}
|
||||
}
|
||||
|
||||
*p++ = m + '0';
|
||||
n = q;
|
||||
}
|
||||
while (n);
|
||||
|
||||
|
|
Loading…
Reference in a new issue