]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2006-04-22 Yoshinori K. Okuji <okuji@enbug.org>
authorokuji <okuji@localhost>
Sat, 22 Apr 2006 09:20:44 +0000 (09:20 +0000)
committerokuji <okuji@localhost>
Sat, 22 Apr 2006 09:20:44 +0000 (09:20 +0000)
        * kern/misc.c (grub_lltoa): Rewritten the decimal conversion part,
        as it was simply too buggy.

ChangeLog
kern/misc.c

index 6bbd5f781edc7e73f0fab7b4464216567148e23a..7216717b39177fe925fd8047eccc9802bb2a1d8e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
index fa1760815688107b20b0c1edaab44be10d5b095a..fc61343c8cace9b3eb908f1b6f5731df97ceae9c 100644 (file)
@@ -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);