1

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?

3
  • 2
    It's impossible. You may define a float or double as double f = 100514.213512345f, but that doesn't mean, that the computer will store it at precisely that precision, so some digits might have already been lost. You can't specify the values as "just like I said". You can treat them as Strings and insert the "," before or you have to implement your own floating point number class. Commented Mar 7, 2018 at 4:38
  • float has only ~7 digits of precision so the closest to 168874.00210014f in float is 168874 Commented Mar 7, 2018 at 5:21
  • You should clarify the question. Your code shows convertFloat being passed a value that is already float. It is certainly possible to format the value of this float as you describe. If, however, you have a number in another format—such as a string containing a decimal numeral—then converting it to a float to pass to convertFloat will lose information, and it is no longer possible to know the original number. You should state exactly what form of number you want to start with. Commented Mar 7, 2018 at 14:44

5 Answers 5

1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Even if I cut the number of decimal places to 5 in the example that you site, I still have a problem because the method is still rounding to 2 decimal places which I do not want. There should be no need to round anything or change any digits with what I am trying to do. I just want the exact same digits, with commas inserted.
@Vinay, 6 is the most precision that is guaranteed for entering a number and getting that same number back out. But as you can see here: en.wikipedia.org/wiki/Single-precision_floating-point_format... the full precision is about 7.225 decimal digits.
Hmm! then i think using float is dangerous in case of OP. As float will by default play with values after decimal.
6 digits of integral precision. The precision on a fraction depends on the fraction.
0

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.

3 Comments

This is not what I want because it rounds to the number of decimal places specified. I do not want any rounding
So you want by default whatever digits are after decimals are shown? No extra no less
Yes. I want the exact same digits as the original float, same decimal places and everything, just with commas inserted
0

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("\\.$","")

2 Comments

This will fail as the output would be distorted. e.g. for 461012.34f output is coming 461,012.34375
Thats the reason for using BigDecimal!
0

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

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.