Ryan
Ryan

Reputation: 39

Convert Float To String With Commas No Rounding Or Decimal Changes

I am trying to convert a float to a String and insert commas into the resulting String. I don't want to add/remove any zeroes, change the precision of the float, or do any kind of rounding. I want the String result to have the exact same digits as the original float, just with commas added. A locale agnostic solution would be preferred.

What I need:

public String convertFloat(float number) {
    // return converted String with commas and no rounding or extra digits
}

Some input/output examples:

Given float: 1500

Result: "1,500"

Given float: 0.00210014

Result: "0.00210014"

Given float: 168874.00210014

Result: "168,874.00210014"

Given float: 168874.01

Result: "168,874.01"

Things I have tried:

String.valueOf(168874.00210014f) // Does not work for me because the result does not contain commas

String.format("%,f", 10.2f) // Does not work for me because it inserts a bunch of zeroes on the end

// The below does not work for me because the precision gets thrown off and the result ends up being: 14.1999998093 When it should be just: 14.2
NumberFormat f = NumberFormat.getInstance();
f.setMaximumFractionDigits(10);
System.out.println(f.format(14.2f));
// Result: 14.1999998093

// The below does not work for me because a bunch of random extra digits get thrown onto the end
DecimalFormat f = new DecimalFormat("#,###.##########");
System.out.println(f.format(100514.2f));
// Result: 100,514.203125

// The below does not work for me because it rounds to 2 decimal places
DecimalFormat f = new DecimalFormat("#,###.00");
System.out.println(f.format(100514.21351f));
// Result: 100,514.203125

// Does not work for me because it rounds to 2 decimal places.
String s = String.format("%,.2f", 10.2629f)

What I am trying to do seems so simple. How can I get the exact same digits just with commas added in the resulting string?

Upvotes: 1

Views: 2596

Answers (5)

Michael Jeszenka
Michael Jeszenka

Reputation: 109

Acknowledging what others have already posted regarding the limited about of digits allowed in a float, here's a version that should work when you are within the limit and won't cut out consecutive 0s if they properly belong to the float. We're basically just splitting the input into 2 substrings and adding the comma formatting to the first half.

    String input = String.valueOf(number);
    int decimalIndex = input.indexOf(".");
    String firstHalf = input.substring(0, decimalIndex);
    String secondHalf = input.substring(decimalIndex, input.length());
    String commas = String.format("%,d", Integer.parseInt(firstHalf));
    return commas + secondHalf;

If you want to retain more precision then please use doubles instead of floats.

Upvotes: 0

Ryan
Ryan

Reputation: 39

OP here, None of these answers really worked for me. Turns out that in my case converting to double was not possible. So I decided to sacrifice the commas and just go with String.valueOf() approach

Upvotes: 0

Yogesh
Yogesh

Reputation: 4784

This is kind of hack but you can replace preceding zeros

String.format("%,f", 10.2f).replaceAll("0*$","")

As for precision with big numbers you should use BigDecimal Additionally you can remove last dot if its round number

String.format("%,f", new BigDecimal(100010f)).replaceAll("0*$","").replaceAll("\\.$","")

Upvotes: 0

Vinay Prajapati
Vinay Prajapati

Reputation: 7504

By default its 6 digits.

There are few pointers that I found:-

  1. Float is distorting the value after decimal while double is not. Hence, would recommend using double.

  2. It's impossible to show as many as digits after decimal as there are in original number. Hence below is a workaround:

    String string = String.format("%,.6654f", Math.abs(n)).replaceAll("0*$", "")
    

n is a double number not a float.

I have used 6654 as random max decimal digits that you could have in your number increase it if you need to.

Upvotes: 0

kshetline
kshetline

Reputation: 13682

It's important to realize that a float has about 7 digits of decimal precision -- about, because decimal numbers can't be represented precisely.

Your example value of 100514.213512345f won't ever come back out the same way you put it in because the original value would necessarily have been truncated at a value somewhere in the neighborhood of 100514.2

I know you don't want any rounding, but it's the nature of floating point math on computers. Even if you use double precision, you just make the rounding smaller -- the issue of rounding doesn't go away.

Upvotes: 1

Related Questions