float a= (float) 1846.4;
NumberFormat df = DecimalFormat.getInstance();
df.setMinimumFractionDigits(2);
df.setMaximumFractionDigits(2);
float b = Float.parseFloat( df.format(a));
What would be the best way to set decimal places for a float (I just want to set 2 decimal places of a float value which can be 2013.43452 or 2392.2) ? Now I am getting exception like Exception in thread "main" java.lang.NumberFormatException: For input string: "1,846.40".
I think the direct problem causing the NFE is the thousand separators in the string, not the number of decimal places. You have both a ',' and a '.' in the string, and parseFloat doesn't like that.
Note, however, that you can't fix the number of decimal places in a float value - it is entirely a formatting issue. Specifically, trailing 0's have no significance in floating point values, thus will not be shown by default. You need to format the value according to your wishes at the point of output (when converting it into a displayable String e.g. by using DecimalFormat as you did above).
To get your formatting + parsing to work, just use df again:
float b = df.parse( df.format(a));
However, I still don't see any sense in that. You can't define the number of decimal places in a floating point number. 1846.40 is the same as 1846.4 or 1846.400, the trailing zeros are totally irrelevant.
Those digits come into play when you have output, e.g. writing the number to a string. But there are other facilities to do that, e.g. a string format pattern.
If you need to restrict the number of fraction digits internally use BigDecimal where you can set the scale and thus define the number of fraction digits it represents.
Sounds like you simply want to round to two decimal places.
Number format and mucking around with strings isn't where you want to go.
Try this:
float b = Math.round(a * 100)/100.0f;
What would be the best way to set decimal places for a float
There isn't one. Floats don't have decimal places. They have binary places.
If you want decimal places you have to use a decimal radix, either a BigDecimal or the result of DecimalFormat.format().
Related
My question is basically the following:
When I use a value with BigDecimal, how do I append zeros in front of a random number?
Say I want to have a number <10 following an entirely random pattern. Now i want to add zeros in front of the number, so the actual amount adds up to 10 numbers.
Here's an example:
BigDecimal num = new BigDecimal(2353);
Now I want to have that ouput:
0000002353
Is there a function that appends numbers to a BigDecimal type?
I couldn't find any.
I tried using a while loop that checks whether the number is less than ten. But I don't understand the Big Decimal well enough to actually compare integral values to the BigDecimal types.
Thanks for any help in advance!
If you use a BigInteger instead (or any integer type, such as int or long) you can format the value with
String.format("%010d", BigInteger.valueOf(2353))
The leading 0 in the format strings means pad with 0, the following 10 is the desired length...
BigDecimal is meant to be used for storing large floating point numbers. Since in a floating-point number there isn't any difference between 0000002353 and 2353, there is no reasonable way to append leading 0's to a BigDecimal just as there is no reasonable way to append leading 0's to a normal float. According to the behavior you're looking for, I would suggest using a String to store your number, and then convert to and from BigDecimal when you want to perform any operations.
To compare an integral type to a BigDecimal, first convert the variable to a BigDecimal and then call BigDecimal's compareTo method. More info is in this question.
Since you're interested in formatting the number, you might want to look at DecimalFormat class, which allows to format floating point and integer numbers according to the specified pattern.
BigDecimal num = new BigDecimal(2353);
DecimalFormat f1 = new DecimalFormat("0000000000");
DecimalFormat f2 = new DecimalFormat("0,000,000,000");
System.out.println(f1.format(num));
System.out.println(f2.format(num));
Output:
0000002353
0,000,002,353
If the maximum number of digits is 10 and only whole numbers are allowed you don't need anything more than to use long with standard formatting:
long myNumber = 123456;
System.out.printf("%010d%n", myNumber);
I want to format a double with a certain number of decimal places in Java. My code currently looks like this:
final NumberFormat format = NumberFormat.getInstance();
format.setMinimumFractionDigits(decimalPlaces);
format.setMaximumFractionDigits(decimalPlaces);
format.setGroupingUsed(false);
String s = format.format(value);
but when decimalPlaces is more than 340, this method just prints 340 digits and ignores the rest. Is there a way to work around this limitation?
Specifically in my case they're all 0s (and probably would be with any number after a certain point since the precision is not that high) but it seems wrong to me that the function just silently ignores what I want instead of throwing an exception or something.
Yes, I'm aware that a double can't actually hold that many decimal places, but it's also true that an int can't hold any decimal places at all yet I'm able to print it with some.
The documentation of setMinimumFractionDigits contains this statement:
The concrete subclass may enforce an upper limit to this value appropriate to the numeric type being formatted.
Most likely the subclass returned by NumberFormat.getInstance is DecimalFormat, which tells us in the JavaDocs
For formatting numbers other than BigInteger and BigDecimal objects, the lower of newValue and 340 is used. Negative input values are replaced with 0.
So to solve your problem, convert your number to a BigDecimal before formatting it.
In case of double the value is getting truncating. Use/declare value as BigDecimal
Try this sample code:
final NumberFormat format = NumberFormat.getInstance();
format.setMinimumFractionDigits(355);
format.setMaximumFractionDigits(400);
format.setGroupingUsed(false);
System.out.println(format.getMinimumFractionDigits());
BigDecimal bd=new BigDecimal(10L);
String s = format.format(bd);
System.out.println(s.length());
System.out.println(s);
I'm doing some large number divisions (long/long to double, and int/int to float).. But I bump, to a problem when the results include the "E". I know we can use NumberFormat to format when displaying, but that's not what I. Just want the result of the divisions to not involve the "E", i.e. just round it up to the closest float/double that fits in the space.
Anybody got an idea?
The internal representation of floating point number does not have a switch for E presence or not (check IEEE-754). So your float/double number is just number (not a number with E or without it).
The only place where you get E is when you print this value out. And while Java uses number formater for printing, so I don't see a point why you don't want to use it here.
System.out.println(new DecimalFormat("#.#####").format(doubleValue));
The general problem that double and float in binary format. It not always possible to convert decimal fraction to binary fraction. For example 0.2 decmal fraction have infinitely many digits in binary (double) format. So whe converted from bynary format to decimal string, it result something like "0.2000000001" what displayed with E. To solve this problem you can use BigDecimal class what contains number in decimal format, so no E problem - it can easy rounded to any decimal point by setScale method. Or you can sore double as is, an write it to output by String.format("My value are: %.3f", value) - i recommend this way.
If you just want round you value to decimal point you can use:
new BigDecimal(val).setScale(3, RoundingMode.HALF_EVEN).doubleValue()
But there no any garanty what this core return double with fine fraction numbers.
I'm trying to format a double to just 2 decimal places in Java.
I've read the following post:
How to round a number to n decimal places in Java
For some reason, every one of those methods fails to work on certain numbers I have..
For example:
DecimalFormat df = new DecimalFormat("#.##");
normalizedValue = Double.valueOf(df.format(normalizedValue));
If I print normalizedValue I get result similar to the following:
-78.64000000000001
18.97
59.469999999999985
-63.120000000000005
(Note: some are formatted correctly... some aren't)
So, these methods seem to round, but I need something that will remove all decimals after 2 decimal places... Any suggestions?
Thank you.
The string representation given by DecimalFormat.format(...) does indeed have only 2 digits in your example. But as soon as you reconvert it into a double those accuracy issues occur. A binary base format like double will always show such effects when you try to represent "exakt" decimal fractions. You may change to BigDecimal to get rid of such effects.
BigDecimal numerator = new BigDecimal(numerator);
BigDecimal denominator = new BigDecimal(denominator);
double result = numerator.divide(denominator).doubleValue();
Division on certain conditions results in a zero at the end (e.g. 0.0060).
Dividing equal numbers results in a zero at the end (e.g 1.0).
I would prefer to trim the trailing zero in both cases. How should I do this?
How about keeping the result as a BigDecimal and then you can set the scale on it to only represent the significant figures that you want.
An easy way to do this, for some numbers, is to use BigDecimal#stripTrailingZeros(). However, if the number is an integer with trailing zeros you'll get an engineering representation e.g. 600.0 will give you 6E+2. If this isn't what you want, you'll have to detect this condition and manually use BigDecimal#setScale() to set the scale appropriately.
If you need to keep to a restricted maximum number of decimal digits you'll need to use alternative formatting/rounding mechanisms before applying this technique.
It's also a good idea to only do this on values that you're going to display, not on the internal values of your model. Treat it as a view/presentation layer modification.
If you must convert to a double, then it's only the formatted representation you can alter. In this case, if you've got a variable number of decimal places that you want to format to, I'd just drop it into a string/character array, scan backwards for the first non-zero character and truncate it there. Not the most performant means, but simple and reliable.
You could even use a regex for this purpose.
you can do this by using DecimalFormat. something like:
DecimalFormat df = new DecimalFormat(".0");
double formatResult = df.format(result);
will create something of 1.0 if the result is 1.278494890. there are many possible patterns that could be used here
Ok, so you've got this code:
BigDecimal numerator = new BigDecimal(numerator);
BigDecimal denominator = new BigDecimal(denominator);
double result = numerator.divide(denominator).doubleValue();
and you want more control over your output. Since result is a double, which is a primitive, you won't have much control.
From my understanding, you don't want to do any rounding to n decimal places, you want original precision paired with desired formatting.
You have few options.
BigDecimal numerator = new BigDecimal(numerator);
BigDecimal denominator = new BigDecimal(denominator);
BigDecimal div = numerator.divide(denominator);
If you stay with BigDecimal, your output will be better. If you put 10 as the numerator and denominator in above code, System.out.println(div) will yield 1.
Generally, be careful of using above code because some combinations of numerator and denominator will throw
java.lang.ArithmeticException: "Non-terminating decimal expansion; no exact representable decimal result."
If you want to avoid such situations, and not worry about precision beyond double's internal representation, use double directly.
System.out.println(2312 / 2.543); //909.1624066063704
System.out.println(1.0 / 1.0); //1.0
System.out.println(1 / 1); //1
When using double numbers, you might get a 0 at the end, such as 0.0060 in your case. If you want to be sure what you're getting, you'll have to convert your result to a String using
String dec = String.valueOf(10.0/10.0); //1.0
and then using
String newDec = dec.endsWith("0") ? dec.substring(0, dec.length() - 1) : dec;
to eradicate that last 0. Of course, if your string ends with .0, you have a choice based on your preferences whether you want to leave that leading . or not.