Format double value? - java

I have following line of code:
DecimalFormat df = new DecimalFormat("#.##");
System.out.println(df.format(23.00));
System.out.println(Double.parseDouble(df.format(23.00d)));
System.out.println(df.parse("23.00").doubleValue());
First line print 23 but in 2nd and 3rd line when i convert it to double it prints 23.0 . showing 23.0 doesnt makes any sense.
How can i get a double value 23.
I checked these best-way-to-format-a-double-value-to-2-decimal-places how-to-nicely-format-floating-numbers-to-string-without-unnecessary-decimal-0

In the second and third output lines, you're just using Double.toString effectively. A double value doesn't remember whatever format it happens to have been parsed in to start with - it's just a numeric value.
If you want to format a value in a particular way, use df.format as you have in your first output line. For example:
String text = ...; // Wherever you get the text from
double value = Double.parseDouble(text);
String formatted = df.format(value); // Using the df you set up before

A double value, when converted to a String, will NEVER be an integer. It will always contains decimals.
If you want to print to the console a double as 23, you can cast it to an Int:
System.out.println((int) yourDouble);

When you say double if your number is 23, it shown 23.0 because it is double.
If your meaning is to print an int value with 2-digits, you can use System.out.printf("%.2d", number);
I don't have any Java compiler on my system this time for test that, but I think it is true.

Related

Error: while trying to format decimal output in Java

I am writing this program as an assignment for school. The program takes input in the form of 'sex' and 'age' from the user, and gives back the average age of all men and/or women.
The program has worked fine up until my mom beta tested it and we found a problem by happenstance. If by any chance the user were to input a number of individuals where the sum of their ages is not divisible by the number of individuals inputted, the output will give an answer with 15 decimal places.
For example if I input 3 men with the ages 98, 1 and 1, the program divides 100 by 3 and I get the output:
33.333333333333336.
So I took to SO to find a solution to this problem, and found this which I implemented in my program like below so that it would trim down the answer to a maximum of 3 decimal places:
/*
This method takes two values. The first value is divided by the second value to get the average. Then it trims the
answer to output a maximum of 3 decimal places in cases where decimals run amok.
*/
public static double average (double a, double b){
double d = a/b;
DecimalFormat df = new DecimalFormat("#.###");
return Double.parseDouble(df.format(d));
I wrote the code in the bottom of my program, in its own method, which I call in the main method at lines 76 and 77:
// Here we calculate the average age of all the people and put them into their respective variable.
double yAverage = average(yAge, men);
double xAverage = average(xAge, women);
However. I get this error message when I try to run the program, and I don't understand the error message. I tried googling the error, but found nothing.
Please keep in mind that I'm a beginner, and I need as simple an answer as anyone can give me.
Thank you in advance!
The problem is that DecimalFormat honors you Locale setting, formatting the number according to your language setting.
E.g. in US English the result is 33.333, but in Germany the result is 33,333.
However, Double.parseDouble(String s) is hardcoded to only parse US English formatting.
A few options to fix it:
Don't round the value. Recommended
Use a DecimalFormat wherever the value needs to be displayed, but keep the full precision of the value itself.
Force DecimalFormat to use US English formatting symbols.
DecimalFormat df = new DecimalFormat("#.###", DecimalFormatSymbols.getInstance(Locale.US));
Use the DecimalFormat to re-parse the value.
DecimalFormat df = new DecimalFormat("#.###");
try {
return df.parse(df.format(d)).doubleValue();
} catch (ParseException e) {
throw new AssertionError(e.toString(), e);
}
Don't convert to/from string to round to 3 decimal places.
Use Math.round(double a).
return Math.round(d * 1000d) / 1000d;
Use BigDecimal (and stick with it). Recommended
return BigDecimal.valueOf(d).setScale(3, RoundingMode.HALF_UP);
Use BigDecimal (temporarily).
return BigDecimal.valueOf(d).setScale(3, RoundingMode.HALF_UP).doubleValue();
Try this code
public static double average(double a, double b) {
double d = a / b;
DecimalFormat df = new DecimalFormat(
"#.###",
DecimalFormatSymbols.getInstance(Locale.ENGLISH)
);
return Double.parseDouble(df.format(d));
}
You're using a formatting with the point as decimal separator ("#.###"). Depending on the location where you run your program, the Java runtime uses a different localisation setting, e.g. in Germany, where a comma is used as decimal separator.
When you use new DecimalFormat("#.###") the default locale is used to interpret the string #.### which may work in some places, but won't in others. Luckily, there is another constructor for DecimalFormat where you can specify what symbols should be used. By using DecimalFormatSymbols.getInstance(Locale.ENGLISH) as second parameter you specify that you want the English formatting conventions ("." as decimal separator, "," for thousands).

What is the MessageFormat pattern to produce localized, full precision output for any double

Given the example code:
String format = "{0,number}"; // <- What do I put here?
double value = Math.PI * 1e-10;
System.out.println(value);
System.out.println(new MessageFormat(format, Locale.US).format(new Object[]{value}));
System.out.println(new MessageFormat(format, Locale.FRANCE).format(new Object[]{value}));
What do I use as the format string such that I get full precision output of any double value and that the output is localized? For example, the output of the current code is:
3.1415926535897934E-10
0
0
String.valueOf(double) correctly prints the full precision, but it isn't a message format and it is not localized. The message format decides the value is too small to bother with. For large numbers the results are even worse! MessageFormat prints 16 significant digits and then appends a bunch of zeros that do not accurately reflect the value stored in the double. E.g. with pi * 1e100 I get:
3.141592653589793E100
31,415,926,535,897,930,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
31 415 926 535 897 930 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
For your requirement and only for it, this is an easiest solution which fits to your code.
Using # symbol below, we show the digits only when they are not 0, otherwise they are being omit.
double value = Math.PI*1e-10;
String format = "{0,number,#.###############E0}"; // <- What do I put here?
System.out.println(value);
System.out.println(new MessageFormat(format, Locale.US).format(new Double[]{value}));
System.out.println(new MessageFormat(format, Locale.FRANCE).format(new Double[]{value}));
If you want to omit conversion of formatting numbers using scientific notifications, for example instead of 9.424777960769379E2( if in format #.###############E0) or 94.24777960769379E1 ( if in format ##.###############E0 ) to be 942.4777960769379, just use code below:
double value = Math.PI*1e-10;
String format = "{0,number,#.################}"; // <- What do I put here?
Take a look and if there is something you need additionally, feel free to ask!

How to set Text Format?

A normal scoreboard text is like this
so i want to make te text format like this
this is the code
score = (TextView)findViewById(R.id.ct);
score.setText(String.valueOf(gamescore));
if (gamescore > highscore){
high.setText(String.valueOf(gamescore));
}
Anyone can explain? Thank's
You should use the String.format() method along with the formatter syntax. String.format() can be used to left-pad a string with zeroes, just like you want.
This code will give you the results that you want: high.setText(String.format("%06d", gamescore));
Let's look at what's going on in detail. We are using this syntax: %[flags][width]conversion
Always begin the format string syntax with a %.
Following % is 0, the zero-padding flag. This tells the formatter that the result will be zero-padded.
After the zero-padding flag is the width, or the minimum number of digits we want; in this case, 6.
Lastly, specify the conversion type. The desired result is formatted as a decimal integer, so we use d.
Here is an example:
int gamescore = 100;
String result = String.format("%06d", gamescore);
System.out.println(result);
Output: 000100

How to convert string to double

double d=0.0;
for (String k : word.keySet()) {
System.out.println(k + "\t" + word.get(k));
d+=Double.valueOf(word.get(k));
d+=word.get(k);
word.get(k);
}
System.out.println("Value\t"+d);
The values are in hashmap. Incompatible type error occurs in 5th line.how to correct it?
The line d+=Double.valueOf(word.get(k)); will correctly add the Double value of word.get(k) to your double d, provided the String is parsable as Double.
The line after it, however, adds a String to a double, which will not compile.
The last line in your loop doesn't make any sense, you are invoking get without actually using the value.
You can use Double.parseDouble()
Eg:
String str="2.25";
double d=Double.parseDouble(str);
System.out.println(d);
You can convert String value to Double like this--
double latitu=Double.parseDouble("21.2186653");
If the error is in 5th line that's because you are trying to add whatever you have in the set word with double d. Java do not know what you have in the set word so you can type cast it if the word is a set of double. Otherwise you have to parse the double from what "word.get(k)" returns.
try d+=(double) word.get(k), if word is a set of double
or d+=double.valueOf(word.get(k)). if you have string in the set word.
In your 5th line of sample code, you are trying to add a string value with a double. that's why you are getting error
use
d += Double.parseDouble(word.get(k));
rather than
d+=word.get(k)

Parse double from JFormattedTextField

I've got a bug or something. I have a method that saves an article, like this:
class SaveArticleListener implements ActionListener {
//....
String s = textArticlePrice.getText().replace(',','.').replaceAll("\\s","");
double price = Double.parseDouble(s);
//....
}
Where textArticlePrice is a JFormattedTextField which configured like:
NumberFormat priceFormat = NumberFormat.getNumberInstance();
priceFormat.setMaximumFractionDigits(2);
priceFormat.setMinimumFractionDigits(2);
textArticlePrice = new JFormattedTextField(priceFormat);
textArticlePrice.setColumns(10);
And in the parseDouble method I'm getting every time:
java.lang.NumberFormatException: For input string: "123 456 789.00"
So replace works with a dot, but not with whitespace... Why?
You'd be better off using your NumberFormat to parse the String. Keep a reference to priceFormat, and then use
double price = priceFormat.parse(textArticlePrice.getText()).doubleValue();
The formatter that's being used to display the number is the same one then used to turn it back into a double so you know it's going to be parsing it in a compatible way.
Best of all is
double price = ((Number) textArticlePrice.getValue()).doubleValue();
which should work without any need for conversion if you've set your JFormattedTextField up properly. (The getValue() call returns an Object, so you need to cast it. It might return a Double or a Long, depending on what's in the text field, so the safe way to get a double out of it is to treat it as a Number, which is the supertype of both, and invoke its .doubleValue() method.)
Writing something that converts it into something that can be parsed by Double.parseDouble() is really not the right way to go because it's too fragile if the formatting of your text field changes later on.
Regarding your question" why doesn't it work with white spaces". White spaces are chars just like a,l,#,?,¡, but it only recognises ,12345, numbers together as a number, you cant make an int variable 'int number = 1 234; Its the same with parsing. Rather try,
s = s.replace(',','.');
s = s.replace(" ","");
Price = Double.parseDouble(s);
Assuming that '123 456 789.00' is one number.
please comment if this helped.
I did this now, it worked fine
String strNumber = "1 2 3 4 5 6.789";
double DblNumber = Double.parseDouble(strNumber);
System.out.Println(DblNumber);// this displays the number if your IDE has an output window

Categories