Place a temporary bandaid on the ls/du/df human-readable issue.  This method is
not going to scale up as well as I would like, and Matt Kraai and I have
discussed a better long term solution.  But for now this will at least make all
the human-readable apps give correct answers.

Please test the human readable/non-human readable options on your systems!!!
 -Erik
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 86691fd..49470e9 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -648,15 +648,18 @@
 					printf("%4d, %3d ", (int)MAJOR(dn->dstat.st_rdev), (int)MINOR(dn->dstat.st_rdev));
 				} else {
 #ifdef BB_FEATURE_HUMAN_READABLE
-					fprintf(stdout, "%9s ", make_human_readable_str(dn->dstat.st_size>>10,
-								(ls_disp_hr==TRUE)? 0: 1));
-#else
+					if (ls_disp_hr==TRUE) {
+						fprintf(stdout, "%9s ", make_human_readable_str(
+									dn->dstat.st_size>>10, 0));
+					} else 
+#endif	
+					{
 #if _FILE_OFFSET_BITS == 64
-					printf("%9lld ", dn->dstat.st_size);
+						printf("%9lld ", dn->dstat.st_size);
 #else
-					printf("%9ld ", dn->dstat.st_size);
+						printf("%9ld ", dn->dstat.st_size);
 #endif
-#endif
+					}
 				}
 				column += 10;
 				break;
diff --git a/libbb/human_readable.c b/libbb/human_readable.c
index 36783fa..ff21751 100644
--- a/libbb/human_readable.c
+++ b/libbb/human_readable.c
@@ -28,26 +28,35 @@
 #include <stdio.h>
 #include "libbb.h"
 
-static char buffer[10];
-static const char *suffixes[] = { "", "k", "M", "G", "T" };
 
-const char *make_human_readable_str(unsigned long val, unsigned long not_hr)
+
+const char *make_human_readable_str(unsigned long val, unsigned long hr)
 {
-	int suffix, base;
+	int i=0;
+	static char str[10] = "\0";
+	static const char strings[] = { 'k', 'M', 'G', 'T', 0 };
+	unsigned long divisor = 1;
 
-	if (not_hr)
-		sprintf(buffer, "%lu", val);
-	else
-		for (suffix = 0, base = 1; suffix < 5; suffix++, base <<= 10) {
-			if (val < (base << 10)) {
-				if (suffix && val < 10 * base)
-					sprintf(buffer, "%lu.%lu%s", val / base,
-							(val % base) * 10 / base, suffixes[suffix]);
-				else
-					sprintf(buffer, "%lu%s", val / base, suffixes[suffix]);
-				break;
-			}
-		}
-
-	return buffer;
+	if(val == 0)
+		return("0");
+	if(hr)
+		snprintf(str, 9, "%ld", val/hr);
+	else {
+		while(val >= divisor && i <= 4) {
+			divisor=divisor<<10, i++;
+		} 
+		divisor=divisor>>10, i--;
+		snprintf(str, 9, "%.1Lf%c", (long double)(val)/divisor, strings[i]);
+	}
+	return(str);
 }
+
+
+/* END CODE */
+/*
+Local Variables:
+c-file-style: "linux"
+c-basic-offset: 4
+tab-width: 4
+End:
+*/
diff --git a/ls.c b/ls.c
index 86691fd..49470e9 100644
--- a/ls.c
+++ b/ls.c
@@ -648,15 +648,18 @@
 					printf("%4d, %3d ", (int)MAJOR(dn->dstat.st_rdev), (int)MINOR(dn->dstat.st_rdev));
 				} else {
 #ifdef BB_FEATURE_HUMAN_READABLE
-					fprintf(stdout, "%9s ", make_human_readable_str(dn->dstat.st_size>>10,
-								(ls_disp_hr==TRUE)? 0: 1));
-#else
+					if (ls_disp_hr==TRUE) {
+						fprintf(stdout, "%9s ", make_human_readable_str(
+									dn->dstat.st_size>>10, 0));
+					} else 
+#endif	
+					{
 #if _FILE_OFFSET_BITS == 64
-					printf("%9lld ", dn->dstat.st_size);
+						printf("%9lld ", dn->dstat.st_size);
 #else
-					printf("%9ld ", dn->dstat.st_size);
+						printf("%9ld ", dn->dstat.st_size);
 #endif
-#endif
+					}
 				}
 				column += 10;
 				break;