-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Revised version, I have mistakenly understood the old code, which only
keeps one digit after the dot.

Cheers,
- -- 
Xin LI <[email protected]>    http://www.delphij.net/
FreeBSD - The Power to Serve!          Live free or die
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (FreeBSD)

iQEcBAEBCAAGBQJNh/D6AAoJEATO+BI/yjfBbDoH/25nmc7rQ914Rgfp2iVTBTCo
0J6D29V1tRfqFnzg62zYH23tsoQfcYI/gesx5TyegdCOpR1nOAEUl7T/UA4CmUuh
CN54KNQ631WUT/V5Rndf5ikIcAnu7L5IP14RNGUWH5CJhi70OmrbWt3d2XKvLMvO
Uhtq+Uhl/NyoGaq2tE9/WyGyeb70Ribzd4zE6hMVSSY9rPKASpCj3oSpAn7ioSms
X9MvcUCM/eOQxLMYtq1PN6Dz5GPqewiBfmoOWNGssbYnhqotYpIKNUAkDeKUuFop
P940nVkhhiSmsZPGD4W67fgKwXhxzj7Ukw7ru+XOp0z3afK6xxkkUQAvAfGop4g=
=mx5z
-----END PGP SIGNATURE-----
Index: humanize_number.c
===================================================================
--- humanize_number.c   (revision 219842)
+++ humanize_number.c   (working copy)
@@ -47,8 +47,9 @@
     const char *suffix, int scale, int flags)
 {
        const char *prefixes, *sep;
-       int     b, i, r, maxscale, s1, s2, sign;
+       int     i, r, maxscale, s1, s2, sign;
        int64_t divisor, max;
+       int64_t quotient = bytes, reminder = 0;
        size_t  baselen;
 
        assert(buf != NULL);
@@ -88,11 +89,10 @@
                buf[0] = '\0';
        if (bytes < 0) {
                sign = -1;
-               bytes *= -100;
+               quotient = -quotient;
                baselen = 3;            /* sign, digit, prefix */
        } else {
                sign = 1;
-               bytes *= 100;
                baselen = 2;            /* digit, prefix */
        }
        if (flags & HN_NOSPACE)
@@ -109,7 +109,7 @@
 
        if (scale & (HN_AUTOSCALE | HN_GETSCALE)) {
                /* See if there is additional columns can be used. */
-               for (max = 100, i = len - baselen; i-- > 0;)
+               for (max = 1, i = len - baselen; i-- > 0;)
                        max *= 10;
 
                /*
@@ -117,29 +117,33 @@
                 * If there will be an overflow by the rounding below,
                 * divide once more.
                 */
-               for (i = 0; bytes >= max - 50 && i < maxscale; i++)
-                       bytes /= divisor;
+               for (i = 0; quotient > max && i < maxscale; i++) {
+                       reminder = quotient % divisor;
+                       quotient /= divisor;
+               }
 
                if (scale & HN_GETSCALE)
                        return (i);
-       } else
-               for (i = 0; i < scale && i < maxscale; i++)
-                       bytes /= divisor;
+       } else {
+               for (i = 0; i < scale && i < maxscale; i++) {
+                       reminder = quotient % divisor;
+                       quotient /= divisor;
+               }
+       }
 
        /* If a value <= 9.9 after rounding and ... */
-       if (bytes < 995 && i > 0 && flags & HN_DECIMAL) {
+       if (quotient == 9 && reminder < 950 && i > 0 && flags & HN_DECIMAL) {
                /* baselen + \0 + .N */
                if (len < baselen + 1 + 2)
                        return (-1);
-               b = ((int)bytes + 5) / 10;
-               s1 = b / 10;
-               s2 = b % 10;
+               s1 = (int)quotient + (((int)reminder + 50) / 100);
+               s2 = (((int)reminder + 50) / 10) % 10;
                r = snprintf(buf, len, "%d%s%d%s%s%s",
                    sign * s1, localeconv()->decimal_point, s2,
                    sep, SCALE2PREFIX(i), suffix);
        } else
                r = snprintf(buf, len, "%" PRId64 "%s%s%s",
-                   sign * ((bytes + 50) / 100),
+                   sign * (quotient + (reminder + 50) / 100),
                    sep, SCALE2PREFIX(i), suffix);
 
        return (r);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "[email protected]"

Reply via email to