简体   繁体   English

Java:使用K,M,B将双精度格式设置为字符串

[英]Java: Format double to String with K, M, B

999 to 999 1000 to 1k 999至999 1000至1k

1500000 to 1.5m 1500000至1.5m

and so on, I would like to not lose any precision at all 依此类推,我想一点也不失去任何精度

Also, need to convert them back to their original value 另外,需要将它们转换回原始值

1.5m to 1500000 etc 1.5m至1500000等

The highest it would go is 11 digits max 最高可以达到11位数字

Thanks 谢谢

How about this: 这个怎么样:

import static java.lang.Double.parseDouble;
import static java.util.regex.Pattern.compile;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

...

private static final Pattern REGEX = compile("(\\d+(?:\\.\\d+)?)([KMG]?)");
private static final String[] KMG = new String[] {"", "K", "M", "G"};

static String formatDbl(double d) {
  int i = 0;
  while (d >= 1000) { i++; d /= 1000; }
  return d + KMG[i];
}

static double parseDbl(String s) {
  final Matcher m = REGEX.matcher(s);
  if (!m.matches()) throw new RuntimeException("Invalid number format " + s);
  int i = 0;
  long scale = 1;
  while (!m.group(2).equals(KMG[i])) { i++; scale *= 1000; }
  return parseDouble(m.group(1)) * scale;
}

If they weren't final you could extend java.lang.Integer etc. to override the toString() method. 如果它们不是最终的,则可以扩展java.lang.Integer等以覆盖toString()方法。 Is it worth creating a java.lang.Number subclass? 是否值得创建java.lang.Number子类? Probably not. 可能不是。 You could create your own classes: MyInteger, MyFloat etc using composition (they'll have an attribute to hold the numeric value) and override the toString() method to return the formats you want. 您可以使用合成来创建自己的类:MyInteger,MyFloat等(它们将具有保存数值的属性),并重写toString()方法以返回所需的格式。

For the other way around, you could create factory methods in your MyXXX classes that creates objects containing the numeric value of the string (such as "1m"). 对于另一种方法,可以在MyXXX类中创建工厂方法,该方法创建包含字符串数字值(例如“ 1m”)的对象。

The good thing is that kind of work lends itself well for unit testing. 好在,这种工作很适合单元测试。

You could probably obtain what you want by using directly a NumberFormat subclass but depending on how you're going to use it, the above design could be better. 您可以直接使用NumberFormat子类来获得所需的内容,但是根据您的使用方式,上述设计可能会更好。

static String[] prefixes = {"k","M","G"};

// Formats a double to a String with SI units
public static String format(double d) {
    String result = String.valueOf(d);
    // Get the prefix to use
    int prefixIndex = (int) (Math.log10(d) / Math.log10(10)) / 3;
    // We only have a limited number of prefixes
    if (prefixIndex > prefixes.length)
        prefixIndex = prefixes.length;
    // Divide the input to the appropriate prefix and add the prefix character on the end
    if (prefixIndex > 0)
        result = String.valueOf(d / Math.pow(10,prefixIndex*3)) + prefixes[prefixIndex-1];
    // Return result
    return result;
}
// Parses a String formatted with SI units to a double
public static double parse(String s) {
    // Retrieve the double part of the String (will throw an exception if not a double)
    double result = Double.parseDouble(s.substring(0,s.length()-1));
    // Retrieve the prefix index used
    int prefixIndex = Arrays.asList(prefixes).indexOf(s.substring(s.length()-1)) + 1;
    // Multiply the input to the appropriate prefix used
    if (prefixIndex > 0)
        result = result * Math.pow(10,prefixIndex*3);
    return result;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM