DecimalFormat is returning -0.00 - java

This bit of code
DecimalFormat formatter = new DecimalFormat("0.00");
return formatter.format(-0.001);
returns
"-0.00"
I would really prefer (and expect) "0.00"
I know I can fix this by writing a subclass of DecimalFormat, but is there a way to do this using the standard DecimalFormat?
EDIT: I only wan't to change the particular case where the result is "-0.00". All other negative values should remain unchanged, eg: -9.1 -> "-9.10"

You could test the string when it's returned.
I don't believe formatting will manipulate the value.
It can only format it. Perhaps you can round it first, and then format it?
DecimalFormat formatter = new DecimalFormat("0.00");
double x = -0.001;
double y = Math.round(x*100.0)/100.0;
return formatter.format(y);

Related

Convert double value to contain decimal seperator and only two digits after comma in groovy

I would like to convert a number such as the following:
2937998.7397271004
to look like this:
2.937.998,73
My attempt of achieving this looks as following, but the result still looks the same:
DecimalFormat decimalFormat = new DecimalFormat("###.###.###.###,00");
def val = decimalFormat.format(cell.getNumericCellValue().doubleValue())
return val
One way to do is to use a locale which supports your formatting pattern. For example Locale.GERMAN is in line with what you are expecting
DecimalFormat df = new DecimalFormat("###,###.00",
DecimalFormatSymbols.getInstance(Locale.GERMAN));
df.format(2937998.7397271004); // 2.937.998,74
You should definitely use Locale for this issue. And in your case formatting is german:
import java.text.NumberFormat
NumberFormat numberFormat = NumberFormat.getInstance(Locale.GERMAN);
println numberFormat.format(2937998.7397271004)
Although I am not familiar with groovy as far as I know it still utilizes the java libraries.
You cannot utilize multipled .'s on a standard DecimalFormat as can be seen in the documentation for the java class: Documentation.
So the following line of code needs to changed to:
DecimalFormat decimalFormat = new DecimalFormat("###,###,###,###.00");
Which will respond with 2.937.998,74 utilizing the provided value of 2937998.7397271004.
If you want to do it as 2.937.998,74 you can, again at least in java, do the following.
DecimalFormat decimalFormat = new DecimalFormat("###,###,###,###.00");
DecimalFormatSymbols custom = new DecimalFormatSymbols();
custom.setDecimalSeparator(',');
custom.setGroupingSeparator('.');
decimalFormat.setDecimalFormatSymbols(custom);
String val = decimalFormat.format(cell.getNumericCellValue().doubleValue());
Or use the locale as other aswers sugest.

How can I impose decimalFormat on the result of a method?

I have this code:
public double theInterest(){
return (accountBalance*i) +accountBalance;
My question is, is there a way I can impose DecimalFormat to the result of the equation so that it will display up to 2 decimal places?
Any help is really appreciated.
Your question is as posted nonanswerable since the method returns a double, and DecimalFormat can only return a String. It makes no sense to try to return a formatted double. I don't recommend that you change the method, but consider creating a separate method, say getInterestString() that takes the result of theInterest(), and formats it with your DecimalFormatter and then returns this formatted String.
i.e.,
public String getInterestString() {
NumberFormat moneyFormat = NumberFormat.getCurrencyInstance();
return moneyFormat.format(theInterest();
}
Or more generally,
private NumberFormat moneyFormat = NumberFormat.getCurrencyInstance();
public String currencyFormat(double numberValue) {
moneyFormat.format(numberValue);
}
Edit: and as svc well states, you should strive to avoid using floating point numbers for monetary calculations as the inaccuracies matter. Better to use BigDecimal.
You should not use double at all for financial work. Typically, you use a BigDecimal where your numbers are valued by the lowest currency unit for your country:
BigDecimal tenDollars = new BigDecimal(1000L, 2);
// Alternatively, use the BigDecimal(BigInteger, int) constructor.
You can set the rounding mode by using MathContexts. Internally, you store the BigDecimal for your currency values; only when you display to the user do you convert to a string using a format.

java (beginner) converting scientific notation to decimal

if
double d = 1.999e-4
I want my output to be 0.0001999.
How can I do it?
NumberFormat formatter = new DecimalFormat("###.#####");
String f = formatter.format(d);
You can explore the sub classes of NumberFormat class to know more details.
I suppose there is a method in BigDecimal Class called toPlainString().
e.g. if the the BigDecimal is 1.23e-8 then the method returns 0.0000000124.
BigDecimal d = new BigDecimal("1.23E-8");
System.out.println(d.toPlainString());
Above code prints 0.0000000123, then you can process the string as per your requirement.
You can do it like this:
double d = 1.999e-4;
NumberFormat nf = NumberFormat.getInstance();
nf.setMinimumFractionDigits(7);
System.out.println(nf.format(d));
Check out the documentation of NumberFormat's methods to format your double as you see fit.
DecimalFormat is a special case of NumberFormat as its constructor states, I don't think that you need its functionality for your case. Check out their documentation if you are confused. Use the factory method getInstance() of NumberFormat for your convenience.
If all you want is to print like that.
System.out.printf("%1$.10f", d);
you can change 10f, 10=number of decimal places you want.
Take a look over
java.text.DecimalFormat
and
java.text.DecimalFormatSymbols

How to change the decimal separator of DecimalFormat from comma to dot/point?

I have this little crazy method that converts BigDecimal values into nice and readable Strings.
private String formatBigDecimal(BigDecimal bd){
DecimalFormat df = new DecimalFormat();
df.setMinimumFractionDigits(3);
df.setMaximumFractionDigits(3);
df.setMinimumIntegerDigits(1);
df.setMaximumIntegerDigits(3);
df.setGroupingSize(20);
return df.format(bd);
}
It however, also produces a so called grouping separator "," that makes all my values come out like this:
xxx,xxx
I do need the separator to be a dot or a point and not a comma.
Does anybody have a clue of how to accomplish this little feat?
I have read this and in particular this to death now but I cannot find a way to get this done.
Am I approaching this the wrong way? Is there a much more elegant way of doing this? Maybe even a solution that accounts for different local number representations, since the comma would be perfect by European standards.
You can change the separator either by setting a locale or using the DecimalFormatSymbols.
If you want the grouping separator to be a point, you can use an european locale:
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
DecimalFormat df = (DecimalFormat)nf;
Alternatively you can use the DecimalFormatSymbols class to change the symbols that appear in the formatted numbers produced by the format method. These symbols include the decimal separator, the grouping separator, the minus sign, and the percent sign, among others:
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(currentLocale);
otherSymbols.setDecimalSeparator(',');
otherSymbols.setGroupingSeparator('.');
DecimalFormat df = new DecimalFormat(formatString, otherSymbols);
currentLocale can be obtained from Locale.getDefault() i.e.:
Locale currentLocale = Locale.getDefault();
Europe is quite huge. I'm not sure if they use the same format all over. However this or this answer will be of help.
String text = "1,234567";
NumberFormat nf_in = NumberFormat.getNumberInstance(Locale.GERMANY);
double val = nf_in.parse(text).doubleValue();
NumberFormat nf_out = NumberFormat.getNumberInstance(Locale.UK);
nf_out.setMaximumFractionDigits(3);
String output = nf_out.format(val);
I.e. use the correct locale.
public String getGermanCurrencyFormat(double value) {
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
nf.setGroupingUsed(true);
return "€ " + nf.format(value);
}
This worked in my case:
DecimalFormat df2 = new DecimalFormat("#.##");
df2.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
BigDecimal does not seem to respect Locale settings.
Locale.getDefault(); //returns sl_SI
Slovenian locale should have a decimal comma. Guess I had strange misconceptions regarding numbers.
a = new BigDecimal("1,2") //throws exception
a = new BigDecimal("1.2") //is ok
a.toPlainString() // returns "1.2" always
I have edited a part of my message that made no sense since it proved to be due the human error (forgot to commit data and was looking at the wrong thing).
Same as BigDecimal can be said for any Java .toString() functions. I guess that is good in some ways. Serialization for example or debugging. There is an unique string representation.
Also as others mentioned using formatters works OK. Just use formatters, same for the JSF frontend, formatters do the job properly and are aware of the locale.
String money = output.replace(',', '.');
you could just use replace function before you return the string in the method
return df.format(bd).replace(",", ".")
This worked for me...
double num = 10025000;
new DecimalFormat("#,###.##");
DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(Locale.GERMAN);
System.out.println(df.format(num));

Problems using DecimalFormat

I am having problems using DecimalFormat when I am going to print out coefficients after a regression.
Here is the part of the code that is facing problems;
DecimalFormat twoDForm = new DecimalFormat("0.00");
private double s(double d){
return Double.valueOf(twoDForm.format(d));
}
and here is the error message in eclipse;
Exception in thread "main" java.lang.NumberFormatException: For input string: "0,16"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.lang.Double.valueOf(Unknown Source)
at model.ARF2.s(ARF2.java:126)
at model.ARF2.printBestModel(ARF2.java:114)
at testing.testclass3.bestForecastingModel(testclass3.java:69)
at testing.testclass3.main(testclass3.java:36)
Please let me know if anyone has any surgestions on how to fix the code. I want two decimals on my coefficients.
Thank you
Lars
use:
DecimalFormat twoDForm = new DecimalFormat("#.##");
DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setDecimalSeparator('.');
twoDForm.setDecimalFormatSymbols(dfs);
http://download.oracle.com/javase/1.4.2/docs/api/java/text/DecimalFormat.html
The following excerpt appears to be part of your problem:
To obtain a NumberFormat for a
specific locale, including the default
locale, call one of NumberFormat's
factory methods, such as
getInstance(). In general, do not call
the DecimalFormat constructors
directly, since the NumberFormat
factory methods may return subclasses
other than DecimalFormat. If you need
to customize the format object, do
something like this:
NumberFormat f = NumberFormat.getInstance(loc);
if (f instanceof DecimalFormat) {
((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
}
You may want to use the applyPattern method:
applyPattern
public void applyPattern(String
pattern) Apply the given pattern to
this Format object. A pattern is a
short-hand specification for the
various formatting properties. These
properties can also be changed
individually through the various
setter methods. There is no limit to
integer digits are set by this
routine, since that is the typical
end-user desire; use setMaximumInteger
if you want to set a real value. For
negative numbers, use a second
pattern, separated by a semicolon
Example "#,#00.0#" -> 1,234.56
This means a minimum of 2 integer
digits, 1 fraction digit, and a
maximum of 2 fraction digits.
Example: "#,#00.0#;(#,#00.0#)" for
negatives in parentheses.
In negative patterns, the minimum and
maximum counts are ignored; these are
presumed to be set in the positive
pattern.
Throws: NullPointerException - if
pattern is null
IllegalArgumentException - if the
given pattern is invalid.
You are encountering an i18n issue. DecimalFormat is using your default locale which specifies the decimal separator as ,. However, the Double.valueOf does not use the locale. It always expects that the decimal separator is ..
If you want to parse a string formatted with DecimalFormat then you need to use DecimalFormat.parse
I think what you intended to do is:
private static String s(double d) {
return twoDForm.format(d);
}
Are you trying to format the number? Or round it? If you're formatting it, shouldn't your "s" method (bad name IMO, btw, but it's private, so it's your call) return a java.lang.String instead of a double?
Check your Locale.
DecimalFormat twoDForm = new DecimalFormat("0.00");
private double s(double d){
String doubleString = displayNumberAmount(twoDForm.format(d));
return Double.valueOf(doubleString);
}
public static String displayNumberAmount(String amount) {
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH);
Number number = 0;
try {
number = numberFormat.parse(amount);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return String.format(Locale.US, "%1$,.2f", number);
}

Categories