Howto format number with DecimalFormat with optional scientific notation - java

I am using a pattern "#0.00##" to format numbers, it works as expected for most input. But sometimes sources number are smaller ie: 6.84378E-05, and gets converted into "0,0001".
Is it possible to format only such numbers (not fitting standard pattern) using scientific notation? leaving all "normal" numbers intact? with single pattern.
I have to use only a single DecimalFormat pattern, without any extra code.
EDIT: To better explain why I need single DecimalFormat : I am using an external library and can only define a pattern to configure output.

You can have distinct patterns only for positive and negative values.You should do something like:
public class DecimalScientificFormat extends DecimalFormat {
private static DecimalFormat df = new DecimalFormat("#0.00##");
private static DecimalFormat sf = new DecimalFormat("0.###E0");
#Override
public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) {
String decimalFormat = df.format(number);
return (0.0001 != number && df.format(0.0001).equals(decimalFormat)) ? sf.format(number, result, fieldPosition) : result.append(decimalFormat);
}
}

Related

DecimalFormat pattern for BigDecimal.

What pattern of DecimalFormat should I use so that when I format BigDecimals like
new BigDecimal("4235886589.00000");
new BigDecimal("4235886589.0000030000");
new BigDecimal("4235886589.0");
new BigDecimal("4235886589");
The output must have the following appearance:
4,235,886,589.00000; 4,235,886,589.0000030000; 4,235,886,589.0; 4,235,886,589;
So basically I'm trying to write a pattern which won't cut off zeros in the end and won't put them if they are not necessary. I tried to handle it with patterns:
DecimalFormat formatter = new DecimalFormat("#,###,##0.########");
DecimalFormat formatter = new DecimalFormat("#,###,##0.000000");
But the first formatter cuts off zeros, whereas the second one puts them where they are unnecessary.
I don't think you can do it in a straight way using the formatter. What you can do is wrap your Decimal in a class where you can store the appropriate format string computed at instantiation:
class MyBigDecimal {
String asString;
BigDecimal n;
public MyBigDecimal(String asString) {
this.asString = asString;
n = new BigDecimal(asString);
}
}

formating a number/string with decimal separator

I am trying to format a Number with DecimalFormat. But I want it to format a number, that is like
input: 1234. --> should be formatted to: 1,234.
But I get 1,234.0 or 1,234.00 depending on my rules for the decimal format
What do I have to do in order to get this done?
The methods that should help you are setMinimumFractionDigits and setMaximumFractionDigits.
format.setMinimumFractionDigits(0);
at a guess, is probably what your looking for.
To ensure that the decimal separator is always shown, use: DecimalFormat.setDecimalSeparatorAlwaysShown(true)
You could format the number regardless of whether it is a decimal or not by using
DecimalFormat f = new DecimalFormat("#,###");
f.format(whatever)...
If you don't want to display any decimal places, don't format a floating point value :) If you use BigInteger, int, or long, it should be fine:
import java.math.*;
import java.text.*;
public class Test {
private static final char p = 'p';
public static void main(String[] args) {
NumberFormat format = new DecimalFormat();
BigInteger value = BigInteger.valueOf(1234);
System.out.println(format.format(value));
System.out.println(format.format(1234));
System.out.println(format.format(1234L));
}
}
Try this:
DecimalFormat df = new DecimalFormat("#,###.", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
System.out.println(df.format(1234));

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);
}

How can I format a String number to have commas and round?

What is the best way to format the following number that is given to me as a String?
String number = "1000500000.574" //assume my value will always be a String
I want this to be a String with the value: 1,000,500,000.57
How can I format it as such?
You might want to look at the DecimalFormat class; it supports different locales (eg: in some countries that would get formatted as 1.000.500.000,57 instead).
You also need to convert that string into a number, this can be done with:
double amount = Double.parseDouble(number);
Code sample:
String number = "1000500000.574";
double amount = Double.parseDouble(number);
DecimalFormat formatter = new DecimalFormat("#,###.00");
System.out.println(formatter.format(amount));
This can also be accomplished using String.format(), which may be easier and/or more flexible if you are formatting multiple numbers in one string.
String number = "1000500000.574";
Double numParsed = Double.parseDouble(number);
System.out.println(String.format("The input number is: %,.2f", numParsed));
// Or
String numString = String.format("%,.2f", numParsed);
For the format string "%,.2f" - "," means separate digit groups with commas, and ".2" means round to two places after the decimal.
For reference on other formatting options, see https://docs.oracle.com/javase/tutorial/java/data/numberformat.html
Given this is the number one Google result for format number commas java, here's an answer that works for people who are working with whole numbers and don't care about decimals.
String.format("%,d", 2000000)
outputs:
2,000,000
Once you've converted your String to a number, you can use
// format the number for the default locale
NumberFormat.getInstance().format(num)
or
// format the number for a particular locale
NumberFormat.getInstance(locale).format(num)
I've created my own formatting utility. Which is extremely fast at processing the formatting along with giving you many features :)
It supports:
Comma Formatting E.g. 1234567 becomes 1,234,567.
Prefixing with "Thousand(K),Million(M),Billion(B),Trillion(T)".
Precision of 0 through 15.
Precision re-sizing (Means if you want 6 digit precision, but only have 3 available digits it forces it to 3).
Prefix lowering (Means if the prefix you choose is too large it lowers it to a more suitable prefix).
The code can be found here. You call it like this:
public static void main(String[])
{
int settings = ValueFormat.COMMAS | ValueFormat.PRECISION(2) | ValueFormat.MILLIONS;
String formatted = ValueFormat.format(1234567, settings);
}
I should also point out this doesn't handle decimal support, but is very useful for integer values. The above example would show "1.23M" as the output. I could probably add decimal support maybe, but didn't see too much use for it since then I might as well merge this into a BigInteger type of class that handles compressed char[] arrays for math computations.
you can also use the below solution
public static String getRoundOffValue(double value){
DecimalFormat df = new DecimalFormat("##,##,##,##,##,##,##0.00");
return df.format(value);
}
public void convert(int s)
{
System.out.println(NumberFormat.getNumberInstance(Locale.US).format(s));
}
public static void main(String args[])
{
LocalEx n=new LocalEx();
n.convert(10000);
}
You can do the entire conversion in one line, using the following code:
String number = "1000500000.574";
String convertedString = new DecimalFormat("#,###.##").format(Double.parseDouble(number));
The last two # signs in the DecimalFormat constructor can also be 0s. Either way works.
Here is the simplest way to get there:
String number = "10987655.876";
double result = Double.parseDouble(number);
System.out.println(String.format("%,.2f",result));
output:
10,987,655.88
The first answer works very well, but for ZERO / 0 it will format as .00
Hence the format #,##0.00 is working well for me.
Always test different numbers such as 0 / 100 / 2334.30 and negative numbers before deploying to production system.
According to chartGPT
Using DecimalFormat:
DecimalFormat df = new DecimalFormat("#,###.00");
String formattedNumber = df.format(yourNumber);
Using NumberFormat:
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setGroupingUsed(true);
String formattedNumber = nf.format(yourNumber);
Using String.format():
String formattedNumber = String.format("%,.2f", yourNumber);
Note: In all the above examples, "yourNumber" is the double value that you want to format with a comma. The ".2f" in the format string indicates that the decimal places should be rounded to 2 decimal places. You can adjust this value as needed.

How to convert a string 3.0103E-7 to 0.00000030103 in Java?

How to convert a string 0E-11 to 0.00000000000 in Java? I want to display the number in non scientific notations. I've tried looking at the number formatter in Java, however I need to specific the exact number of decimals I want but I will not always know. I simply want the number of decimal places as specificed by my original number.
Apparently the correct answer is to user BigDecimal and retrieve the precision and scale numbers. Then use those numbers in the Formatter. Something similar like this:
BigDecimal bg = new BigDecimal(rs.getString(i));
Formatter fmt = new Formatter();
fmt.format("%." + bg.scale() + "f", bg);
buf.append( fmt);
Using BigDecimal:
public static String removeScientificNotation(String value)
{
return new BigDecimal(value).toPlainString();
}
public static void main(String[] arguments) throws Exception
{
System.out.println(removeScientificNotation("3.0103E-7"));
}
Prints:
0.00000030103
I would use BigDecimal.Pass your string into it as a parameter and then use String.format to represent your newly created BigDecimal without scientific notation.
Float or Double classes can be used too.
double d = Double.parseDouble("7.399999999999985E-5");
NumberFormat formatter = new DecimalFormat("###.#####");
String f = formatter.format(d);
System.out.println(f); // output --> 0.00007
I haven't tried it, but java.text.NumberFormat might do what you want.

Categories