简体   繁体   中英

Is it possible to Number Format a BigInteger in Java to 1k, 1m, etc?

I am wondering if it's possible to number format a BigInteger in Java by converting to 2 decimal places and adding a Suffix?

Eg 1000 = 1.00k, 1000000000000 = 1.00t

I am currently using the following code which is perfect for formatting longs...

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

Is there a way to do something like this, but for BigIntegers?

Thanks in advance!

Here is an example of a formatter:

String[] suffixes = { "€", "K", "M", "T"};

public final String format(BigInteger value) {

    // As a string
    String stringValue = value.toString();
    // Packets are groups of three numbers
    final List<String> packets = new ArrayList<>();

    // Create packets
    for (int i = stringValue.length(); 0 < i; i -= 3) {
        if (i <= 3) {
        packets.add(0, stringValue);
        break;
        }
        packets.add(0, stringValue.substring(i - 3));
        stringValue = stringValue.substring(0, i - 3);
    }

    // Create the number according to its length
    final StringBuilder sb = new StringBuilder();
    if (packets.size() > 1) {
        sb.append(packets.get(0));
        sb.append(".");
        sb.append(packets.get(1).substring(0, 2));
        sb.append(suffixes[packets.size()]);
    } else {
        System.out.println(packets.get(0) + "€");
        return packets.get(0) + "€";
    }
    System.out.println(sb.toString());
    return sb.toString();
}

It formats a BigInteger to a String like 547.58T or 0€. The only issue is that it doesn't support negative numbers so well.

Fortunately, there is a solution on the Maven Central.

<dependency>
  <groupId>com.github.bogdanovmn.humanreadablevalues</groupId>
  <artifactId>human-readable-values</artifactId>
  <version>1.0.1</version>
</dependency>

You can just get values for amount of bytes or seconds. Also you can create you own fraction class.

Docs https://github.com/bogdanovmn/java-human-readable-values

Seconds example

assertEquals(
    "2h 46m 40s",
    new SecondsValue(10000).fullString()
);

assertEquals(
    "2.8h",
    new SecondsValue(10000).shortString()
);

Bytes example

assertEquals(
    "9K 784b",
    new BytesValue(10000).fullString()
);

assertEquals(
    "9.8K",
    new BytesValue(10000).shortString()
);

Customization example

public class MyTypeValue extends FractionatedValue {
    public MyTypeValue(long value) {
        super(
            value,
            new FractionSpecification(
                FractionDefinition.builder()
                    .name("the minimal fraction unit")
                    .shortNotation("foo")
                    .minimalUnitsAmount(1)
                .build(),

                FractionDefinition.builder()
                    .name("another fraction unit")
                    .shortNotation("baz")
                    .minimalUnitsAmount(60)
                .build(),

                FractionDefinition.builder()
                    .name("the last fraction unit")
                    .shortNotation("foo baz")
                    .minimalUnitsAmount(3600)
                .build()
            )
        );
    }
}

...

assertEquals(
    "2foo 46baz 40foo baz",
    new MyTypeValue(10000).fullString()
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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