Следующий код показывает, как вы можете сделать это, имея в виду простое расширение.
"Волшебство" заключается в основном в функции makeDecimal
, которая при правильных переданных значениях гарантирует, что в выводе никогда не будет больше четырех символов.
Сначала извлекаются целые и десятые доли для данного делителя, поэтому, например, 12,345,678
с делителем 1,000,000
даст значение whole
12
и значение tenths
3
.
Исходя из этого, он может решить, будет ли он выводить только всю часть или как целую, так и десятую часть, используя правила:
- Если десятая часть равна нулю, просто выведите целую часть и суффикс.
- Если целая часть больше девяти, просто выведите целую часть и суффикс.
- В противном случае выведите целую часть, десятую часть и суффикс.
Код для этого:
static private String makeDecimal(long val, long div, String sfx) {
val = val / (div / 10);
long whole = val / 10;
long tenths = val % 10;
if ((tenths == 0) || (whole >= 10))
return String.format("%d%s", whole, sfx);
return String.format("%d.%d%s", whole, tenths, sfx);
}
Тогда достаточно просто вызвать вспомогательную функцию с правильными значениями, включая некоторые константы, чтобы облегчить жизнь разработчику:
static final long THOU = 1000L;
static final long MILL = 1000000L;
static final long BILL = 1000000000L;
static final long TRIL = 1000000000000L;
static final long QUAD = 1000000000000000L;
static final long QUIN = 1000000000000000000L;
static private String Xlat(long val) {
if (val < THOU) return Long.toString(val);
if (val < MILL) return makeDecimal(val, THOU, "k");
if (val < BILL) return makeDecimal(val, MILL, "m");
if (val < TRIL) return makeDecimal(val, BILL, "b");
if (val < QUAD) return makeDecimal(val, TRIL, "t");
if (val < QUIN) return makeDecimal(val, QUAD, "q");
return makeDecimal(val, QUIN, "u");
}
Тот факт, что функция makeDecimal
выполняет грубую работу, означает, что расширение за пределы 999,999,999
- это просто вопрос добавления дополнительной строки к Xlat
, настолько легко, что я сделал это для вас.
Финальный return
в Xlat
не нуждается в условном выражении, так как наибольшее значение, которое вы можете хранить в 64-битной длинной со знаком, составляет всего около 9,2 квинтиллионов.
Но если по каким-то странным требованиям Oracle решит добавить 128-битный тип longer
или 1024-битный damn_long
, вы будете к этому готовы: -)
И, наконец, небольшой тестовый комплект, который вы можете использовать для проверки функциональности.
public static void main(String[] args) {
long vals[] = {
999L, 1000L, 5821L, 10500L, 101800L, 2000000L,
7800000L, 92150000L, 123200000L, 999999999L,
1000000000L, 1100000000L, 999999999999L,
1000000000000L, 999999999999999L,
1000000000000000L, 9223372036854775807L
};
for (long val: vals)
System.out.println ("" + val + " -> " + Xlat(val));
}
}
Из вывода видно, что он дает то, что вам нужно:
999 -> 999
1000 -> 1k
5821 -> 5.8k
10500 -> 10k
101800 -> 101k
2000000 -> 2m
7800000 -> 7.8m
92150000 -> 92m
123200000 -> 123m
999999999 -> 999m
1000000000 -> 1b
1100000000 -> 1.1b
999999999999 -> 999b
1000000000000 -> 1t
999999999999999 -> 999t
1000000000000000 -> 1q
9223372036854775807 -> 9.2u
И, кроме того, помните, что передача отрицательного числа в эту функцию приведет к слишком длинной строке для ваших требований, поскольку она следует по пути < THOU
). Я подумал, что все в порядке, поскольку в вопросе вы упоминаете только неотрицательные значения.