liverare Posted October 18, 2017 Share Posted October 18, 2017 (edited) Test case: logger.debug(formatRSUnit(559546000000l)); // 559.54B logger.debug(formatRSUnit(19546000000l)); // 19.54B logger.debug(formatRSUnit(1954600000l)); // 1.95B logger.debug(formatRSUnit(155400000l)); // 155.4M logger.debug(formatRSUnit(70000000l)); // 70.0M logger.debug(formatRSUnit(5400000l)); // 5.40M logger.debug(formatRSUnit(450000l)); // 450.0K logger.debug(formatRSUnit(12000l)); // 12.0K logger.debug(formatRSUnit(8000l)); // 8.0K logger.debug(formatRSUnit(600l)); // 600 logger.debug(formatRSUnit(50l)); // 50 logger.debug(formatRSUnit(2l)); // 2 Source code: private static final DecimalFormat UNIT_FORMAT = new DecimalFormat(".0#"); /** * @author Explv (https://osbot.org/forum/profile/192661-explv/) * @author LiveRare (https://osbot.org/forum/profile/23977-liverare/) * * @param value * - An amount * @return Formatted RS unit */ public static String formatRSUnit(final long value) { String suffix; double convertedValue; if (value >= 1_000_000_000) { convertedValue = ((double) value / 1_000_000_000); suffix = "B"; } else if (value >= 1_000_000) { convertedValue = ((double) value / 1_000_000); suffix = "M"; } else if (value >= 1000) { convertedValue = ((double) value / 1000); suffix = "K"; } else { return String.valueOf(value); } convertedValue = Math.floor(convertedValue * 100) / 100; return UNIT_FORMAT.format(convertedValue) + suffix; } I think I've over-complicated something here. If I have, please tell me how. Edited October 18, 2017 by liverare 3 Quote Link to comment Share on other sites More sharing options...
Apaec Posted October 18, 2017 Share Posted October 18, 2017 public String runescapeFormat(long l) { String[] suffix = new String[] { "K", "M", "B", "T" }; int size = (l != 0) ? (int) Math.log10(l) : 0; if (size >= 3) while (size % 3 != 0) size = size - 1; return (size >= 3) ? + (Math.round((l / Math.pow(10, size)) * 10) / 10d) + suffix[(size / 3) - 1] : + l + ""; } ...But yours is a lot more readable!! 3 Quote Link to comment Share on other sites More sharing options...
Prolax Posted October 18, 2017 Share Posted October 18, 2017 15 minutes ago, Apaec said: public String runescapeFormat(long l) { String[] suffix = new String[] { "K", "M", "B", "T" }; int size = (l != 0) ? (int) Math.log10(l) : 0; if (size >= 3) while (size % 3 != 0) size = size - 1; return (size >= 3) ? + (Math.round((l / Math.pow(10, size)) * 10) / 10d) + suffix[(size / 3) - 1] : + l + ""; } ...But yours is a lot more readable!! Nicely written method. Quote Link to comment Share on other sites More sharing options...
liverare Posted October 18, 2017 Author Share Posted October 18, 2017 (edited) 1 hour ago, Apaec said: public String runescapeFormat(long l) { String[] suffix = new String[] { "K", "M", "B", "T" }; int size = (l != 0) ? (int) Math.log10(l) : 0; if (size >= 3) while (size % 3 != 0) size = size - 1; return (size >= 3) ? + (Math.round((l / Math.pow(10, size)) * 10) / 10d) + suffix[(size / 3) - 1] : + l + ""; } ...But yours is a lot more readable!! Your's does exactly what I need it to do (and no doubt more efficient as you're not splitting strings). However, you're damn right mine's more readable. I'm stealing your code. >:) I'm going to reformat it so I can actually comprehend in full what's actually happening, then I'm replacing my method with yours. (will credit where due). :edit: I found just one flaw: you round up your number. So in a test case, if 17,965,432 was used, I'd get 17.96M whereas you would get 18.00M. But I've figured out how to solve that and have modified the original thread with your code that I've modified. Edited October 18, 2017 by liverare Quote Link to comment Share on other sites More sharing options...
Explv Posted October 18, 2017 Share Posted October 18, 2017 (edited) 1 hour ago, liverare said: Test case: logger.debug(formatRSUnit(559546000000l)); // 559.54B logger.debug(formatRSUnit(19546000000l)); // 19.54B logger.debug(formatRSUnit(1954600000l)); // 1.95B logger.debug(formatRSUnit(155400000l)); // 155.4M logger.debug(formatRSUnit(70000000l)); // 70.0M logger.debug(formatRSUnit(5400000l)); // 5.40M logger.debug(formatRSUnit(450000l)); // 450.0K logger.debug(formatRSUnit(12000l)); // 12.0K logger.debug(formatRSUnit(8000l)); // 8.0K logger.debug(formatRSUnit(600l)); // 600 logger.debug(formatRSUnit(50l)); // 50 logger.debug(formatRSUnit(2l)); // 2 Source code: public static String formatRSUnit(long amount) { String formatted = ""; int wholeNumber = 0; int decimalNumber = 0; String notation = null; String[] decimalNumbers; if (amount >= 1000000000l) { // 1B wholeNumber = (int) (amount / 1000000000l); decimalNumber = (int) (amount % 1000000000l); notation = "B"; } else if (amount >= 1000000l) { // 1M wholeNumber = (int) (amount / 1000000l); decimalNumber = (int) (amount % 1000000l); notation = "M"; } else if (amount >= 1000l) { // 1K wholeNumber = (int) (amount / 1000l); decimalNumber = (int) (amount % 1000l); notation = "K"; } else { formatted += amount; } if (notation != null) { decimalNumbers = String.valueOf(decimalNumber).split(""); formatted += wholeNumber; formatted += "."; if (decimalNumbers != null && decimalNumbers.length > 0) { for (int i = 0; i < decimalNumbers.length && i < 2; i++) { decimalNumber = Integer.parseInt(decimalNumbers[i]); if (decimalNumber == 0) { if (i == 0) { formatted += "0"; } break; } else { formatted += decimalNumber; } } } else { formatted += "00"; } formatted += notation; } return formatted; } I think I've over-complicated something here. If I have, please tell me how. 1 hour ago, Apaec said: public String runescapeFormat(long l) { String[] suffix = new String[] { "K", "M", "B", "T" }; int size = (l != 0) ? (int) Math.log10(l) : 0; if (size >= 3) while (size % 3 != 0) size = size - 1; return (size >= 3) ? + (Math.round((l / Math.pow(10, size)) * 10) / 10d) + suffix[(size / 3) - 1] : + l + ""; } ...But yours is a lot more readable!! Simplest way you wieners: This will also ensure whole numbers are not printed with .0 at the end: public static String formatValue(final long value) { String suffix = ""; double convertedValue; if (value >= 1_000_000_000) { convertedValue = ((double) value / 1_000_000_000); suffix = "b"; } else if (value >= 1_000_000) { convertedValue = ((double) value / 1_000_000); suffix = "m"; } else if (value >= 1000) { convertedValue = ((double) value / 1000); suffix = "k"; } else { convertedValue = value; } if (convertedValue % 1 == 0) { return String.format("%d%s", (long) convertedValue, suffix); } return String.format("%.2f%s", convertedValue, suffix); } Test cases: assert formatValue(559546000000L).equals("559.55b"); assert formatValue(19546000000L).equals("19.55b"); assert formatValue(1954600000L).equals("1.95b"); assert formatValue(155400000L).equals("155.40m"); assert formatValue(70000000L).equals("70m"); assert formatValue(5400000L).equals("5.40m"); assert formatValue(450000L).equals("450k"); assert formatValue(12000L).equals("12k"); assert formatValue(8000L).equals("8k"); assert formatValue(600L).equals("600"); assert formatValue(50L).equals("50"); assert formatValue(2L).equals("2"); Edited October 18, 2017 by Explv 2 Quote Link to comment Share on other sites More sharing options...
liverare Posted October 18, 2017 Author Share Posted October 18, 2017 (edited) 13 minutes ago, Explv said: Simplest way you wieners. This will also ensure whole numbers are not printed with .0 at the end: public static String formatValue(final long value) { String suffix = ""; double convertedValue; if (value >= 1_000_000_000) { convertedValue = ((double) value / 1_000_000_000); suffix = "b"; } else if (value >= 1_000_000) { convertedValue = ((double) value / 1_000_000); suffix = "m"; } else if (value >= 1000) { convertedValue = ((double) value / 1000); suffix = "k"; } else { convertedValue = value; } if (convertedValue % 1 == 0) { return String.format("%d%s", (long) convertedValue, suffix); } return String.format("%.2f%s", convertedValue, suffix); } Test cases: assert formatValue(559546000000L).equals("559.55b"); assert formatValue(19546000000L).equals("19.55b"); assert formatValue(1954600000L).equals("1.95b"); assert formatValue(155400000L).equals("155.40m"); assert formatValue(70000000L).equals("70m"); assert formatValue(5400000L).equals("5.40m"); assert formatValue(450000L).equals("450k"); assert formatValue(12000L).equals("12k"); assert formatValue(8000L).equals("8k"); assert formatValue(600L).equals("600"); assert formatValue(50L).equals("50"); assert formatValue(2L).equals("2"); I do like yours too, however, what I dislike is the forced rounding (which happens as a result of the format), how your forced to two decimal places even when that remaining digit is a "0" (such as 5.40M), and (as a personal preference), when denoting values, I like to have at least one decimal value even if that value's "0", because it signifies that the number's not a 100% accurate reflection of the actual number. Edited October 18, 2017 by liverare Quote Link to comment Share on other sites More sharing options...
Explv Posted October 18, 2017 Share Posted October 18, 2017 22 minutes ago, liverare said: I do like yours too, however, what I dislike is the forced rounding (which happens as a result of the format), how your forced to two decimal places even when that remaining digit is a "0" (such as 5.40M), and (as a personal preference), when denoting values, I like to have at least one decimal value even if that value's "0", because it signifies that the number's not a 100% accurate reflection of the actual number. Ok well, if you don't want to round then you can just do Math.floor(doubleValue * 100) / 100 to get the value to 2dp To achieve your super weird format you can use the Java class "DecimalFormat" with the format ".0#" # is an optional value (if it is 0 it won't be displayed), 0 is a digit public static String formatValue(final long value) { String suffix; double convertedValue; if (value >= 1_000_000_000) { convertedValue = ((double) value / 1_000_000_000); suffix = "b"; } else if (value >= 1_000_000) { convertedValue = ((double) value / 1_000_000); suffix = "m"; } else if (value >= 1000) { convertedValue = ((double) value / 1000); suffix = "k"; } else { return String.valueOf(value); } convertedValue = Math.floor(convertedValue * 100) / 100; return new DecimalFormat(".0#").format(convertedValue) + suffix; } Test cases: assert formatValue(559546000000L).equals("559.54b"); assert formatValue(19546000000L).equals("19.54b"); assert formatValue(1954600000L).equals("1.95b"); assert formatValue(155400000L).equals("155.4m"); assert formatValue(70000000L).equals("70.0m"); assert formatValue(5400000L).equals("5.4m"); assert formatValue(450000L).equals("450.0k"); assert formatValue(12000L).equals("12.0k"); assert formatValue(8000L).equals("8.0k"); assert formatValue(600L).equals("600"); assert formatValue(50L).equals("50"); assert formatValue(2L).equals("2"); 2 Quote Link to comment Share on other sites More sharing options...
liverare Posted October 18, 2017 Author Share Posted October 18, 2017 4 hours ago, Explv said: Ok well, if you don't want to round then you can just do Math.floor(doubleValue * 100) / 100 to get the value to 2dp To achieve your super weird format you can use the Java class "DecimalFormat" with the format ".0#" # is an optional value (if it is 0 it won't be displayed), 0 is a digit public static String formatValue(final long value) { String suffix; double convertedValue; if (value >= 1_000_000_000) { convertedValue = ((double) value / 1_000_000_000); suffix = "b"; } else if (value >= 1_000_000) { convertedValue = ((double) value / 1_000_000); suffix = "m"; } else if (value >= 1000) { convertedValue = ((double) value / 1000); suffix = "k"; } else { return String.valueOf(value); } convertedValue = Math.floor(convertedValue * 100) / 100; return new DecimalFormat(".0#").format(convertedValue) + suffix; } Test cases: assert formatValue(559546000000L).equals("559.54b"); assert formatValue(19546000000L).equals("19.54b"); assert formatValue(1954600000L).equals("1.95b"); assert formatValue(155400000L).equals("155.4m"); assert formatValue(70000000L).equals("70.0m"); assert formatValue(5400000L).equals("5.4m"); assert formatValue(450000L).equals("450.0k"); assert formatValue(12000L).equals("12.0k"); assert formatValue(8000L).equals("8.0k"); assert formatValue(600L).equals("600"); assert formatValue(50L).equals("50"); assert formatValue(2L).equals("2"); I like it! I've updated the main post with it. However, I've tweeked it a slight bit for my use. Quote Link to comment Share on other sites More sharing options...