15

I'd like to format following numbers into the numbers next to them with Android:

1000 to 1k 5821 to 5.8k 2000000 to 2m 7800000 to 7.8m

Mëd KB
  • 173
  • 1
  • 1
  • 4
  • 6
    Possible duplicate of [How to go about formatting 1200 to 1.2k in java](http://stackoverflow.com/questions/4753251/how-to-go-about-formatting-1200-to-1-2k-in-java) – Hiren Jungi Jan 25 '17 at 19:01
  • Try out this library https://github.com/tygalive/Number-Shortener [Disclaimer am the owner] – Richard Muvirimi Apr 06 '21 at 09:17

9 Answers9

20

Function

public String prettyCount(Number number) {
    char[] suffix = {' ', 'k', 'M', 'B', 'T', 'P', 'E'};
    long numValue = number.longValue();
    int value = (int) Math.floor(Math.log10(numValue));
    int base = value / 3;
    if (value >= 3 && base < suffix.length) {
        return new DecimalFormat("#0.0").format(numValue / Math.pow(10, base * 3)) + suffix[base];
    } else {
        return new DecimalFormat("#,##0").format(numValue);
    }
}

Use

prettyCount(789); Output: 789
prettyCount(5821); Output: 5.8k
prettyCount(101808); Output: 101.8k
prettyCount(7898562); Output: 7.9M
Ketan Ramani
  • 3,976
  • 30
  • 39
14

Try this method :

For Java

public static String formatNumber(long count) {
    if (count < 1000) return "" + count;
    int exp = (int) (Math.log(count) / Math.log(1000));
    return String.format("%.1f %c", count / Math.pow(1000, exp),"kMGTPE".charAt(exp-1));
}

For Kotlin(Android)

fun getFormatedNumber(count: Long): String {
if (count < 1000) return "" + count
val exp = (ln(count.toDouble()) / ln(1000.0)).toInt()
return String.format("%.1f %c", count / 1000.0.pow(exp.toDouble()), "kMGTPE"[exp - 1])
}
Ashav Kothari
  • 274
  • 3
  • 6
11

This should do the trick

String numberString = "";
if (Math.abs(number / 1000000) > 1) {
   numberString = (number / 1000000).toString() + "m";

} else if (Math.abs(number / 1000) > 1) {
   numberString = (number / 1000).toString() + "k";

} else {
   numberString = number.toString();

}
Garvit Jain
  • 1,482
  • 2
  • 18
  • 25
StackOverflower
  • 4,945
  • 12
  • 54
  • 88
  • 5
    Your logic will not show 1000 to 1k, because greater than equal to sign should be there. Also your logic will not show 5821 to 5.8k, it will show 5k instead of 5.8k. – Rahul Gupta Mar 17 '19 at 10:21
10

Try this trick:

 private String numberCalculation(long number) {
    if (number < 1000) 
        return "" + number;
    int exp = (int) (Math.log(number) / Math.log(1000));
    return String.format("%.1f %c", number / Math.pow(1000, exp), "kMGTPE".charAt(exp-1));
}
Tushar Lathiya
  • 807
  • 8
  • 22
2

As of Android 7.0 (API 24), it is possible to use CompactDecimalFormat.

For example :

    private String convertNumber(int number, Locale locale) {
        CompactDecimalFormat compactDecimalFormat =
                CompactDecimalFormat.getInstance(locale, CompactDecimalFormat.CompactStyle.SHORT);
        return compactDecimalFormat.format(number);
    }

This class is also part of ICU v49 (https://unicode-org.github.io/icu-docs/apidoc/dev/icu4j/com/ibm/icu/text/CompactDecimalFormat.html).


Furthermore, as of Android 11 (API 30), it is possible to use NumberFormatter.

This class is also part of ICU v60.

Guillaume Husta
  • 3,541
  • 26
  • 39
1

This a Kotlin "extension on Double" that worked for me.
This also doesn't round the number:

fun Double.currencyCountWithSuffix(): String {
val suffixChars = "KMGTPE"
val formatter = DecimalFormat("###.#")
formatter.roundingMode = RoundingMode.DOWN

return if (this < 1000.0) formatter.format(this)
else {
    val exp = (ln(this) / ln(1000.0)).toInt()
    formatter.format(this / 1000.0.pow(exp.toDouble())) + suffixChars[exp - 1]
  }
}
DarShan
  • 2,558
  • 2
  • 14
  • 38
Fathallah
  • 71
  • 1
  • 3
1

// Kotlin Version

fun countviews(count:Long): String{
    val array = arrayOf(' ', 'k', 'M', 'B', 'T', 'P', 'E')
    val value = Math.floor(Math.log10(count.toDouble())).toInt()
    val  base = value / 3
        if (value >= 3 && base < array.size) {
            return DecimalFormat("#0.0").format(count/ Math.pow(10.0, (base * 3).toDouble())) + array[base]
        } else {
            return DecimalFormat("#,##0").format(count)
        }
    }
Kunal Mathur
  • 11
  • 1
  • 2
0
public static String prettyCount(Double number) {
    DecimalFormat df = new DecimalFormat("#.#");
    String numberString = "";

    if (Math.abs(number / 1000000) >= 1) {
        numberString = df.format(number / 1000000.0) + "m";

    } else if (Math.abs(number / 1000.0) >= 1) {
        numberString = df.format(number / 1000.0) + "k";

    } else {
        numberString = number.toString();

    }
    return numberString;
}
RominaV
  • 3,245
  • 1
  • 28
  • 57
PintuBeast
  • 36
  • 3
0

This is a modified version of Sujith Manjavana answer.

here i have used DecimalFormat to control the integers after the decimal point.

long kil = 1000;
long meg = kil * 1000;
long gig = meg * 1000;
long ter = gig * 1000;

double bytes = 56789; // your integer. if you are using a String then -->  double bytes = Double.parseDouble(56789);
DecimalFormat form = new DecimalFormat("0.0"); // you can also use 0.00 or 0.000 


if ((bytes >= 0) && (bytes < kil)) {
String oneDecimal = form.format(bytes);
Toast.makeText(MainActivity.this, oneDecimal, Toast.LENGTH_LONG).show();

} else if ((bytes >= kil) && (bytes < meg)) {
    String oneDecimal = form.format(bytes / kil);
    Toast.makeText(MainActivity.this, oneDecimal+" K", Toast.LENGTH_LONG).show();
    
     } else if ((bytes >= meg) && (bytes < gig)) {
         String oneDecimal = form.format(bytes / meg);
         Toast.makeText(MainActivity.this, oneDecimal+" M", Toast.LENGTH_LONG).show();
         
         } else if ((bytes >= gig) && (bytes < ter)) {
             String oneDecimal = form.format(bytes / gig);
             Toast.makeText(MainActivity.this, oneDecimal+" B", Toast.LENGTH_LONG).show();
            
            } else if (bytes >= ter) {
                String oneDecimal = form.format(bytes / ter);
                Toast.makeText(MainActivity.this, oneDecimal+" T", Toast.LENGTH_LONG).show();
            } else {
                String oneDecimal = form.format(bytes);
                Toast.makeText(MainActivity.this, oneDecimal, Toast.LENGTH_LONG).show();
            }
HAZEEM JOONUS
  • 137
  • 1
  • 5