Jump to content

RS Unit Format


Recommended Posts

Posted (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 by liverare
  • Like 3
Posted
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!!

  • Like 3
Posted
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.

Posted (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. <3 (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 by liverare
Posted (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 by Explv
  • Like 2
Posted (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 by liverare
Posted
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");

 

  • Like 2
Posted
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. :)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...