DecimalFormat and doubles - java

DecimalFormat parses Double.toString() representation (which could be in scientific and financial format).
Why Sun has chosen this approach, instead of direct converting double to String?
PS:
To be more concrete. Why DecimalFormat internally uses Double.toString() in order to format Double, instead of formatting internal representation of Double itself?

DecimalFormat gives you more control over the format by allowing you to give it a formatting pattern.

may be he ask like "Double.toString(withSomeParameters)" will do the job instead of using DecimalFormat.
i think the reason, could be i18n. in some places you can type 1,800.39 .. while somewhere else you can type 1.800,39

I'm not shure what you mean by "direct converting", but toString() is always a debug information only! You should not use it to display values in a frontend. Use DecimalFormat for parsing and formatting!

Perhaps Sun is following DRY principles.

For financial applications, use BigDecimal instead, that give you control over rounding modes and precision.

Related

Java changing format of a double in an ArrayList<Double>

I have an ArrayList that i am inputting numbers into like
23466012.83
23466413.39
23466411.94
etc.
but when i reprint them from the array after i sort them they are reprinted like this
2.346601283E7
2.346641339E7
2.346641194E7
Why does java do this and how can this be fixed? (I want the format to be the same as when it was input)
Thanks!
Please review how Java handles primitive types and their related objects. By adding a "double" (lowercase) primitive type into a List, they are converted into "Double" objects, because List in Java can only hold objects, not primitives.
Therefore when you later output the Double object, it actually uses the simple toString() method of class Double to format the line. And this is implemented in a way to print the full range of Double in a readable format, this is why it chooses the so-called Scientific Notation with exponents display.
By using a more useful formatter, e.g. the Formatter class as mentioned in the comment or the MessageFormat class, you can better control how the output looks like.
Why does java do this
Java merely prints out your Double values using the default number format.
and how can this be fixed?
By explicitly specifying the desired number format.
I want the format to be the same as when it was input
First of all, you'll need to understand that you can't get "the same format as when it was input" because that information is irretrievably lost. It cannot be determined by inspecting a Double value how many significant digits were used to parse it.
If all you need is printing with two decimal places, one way to achieve it is with this statement:
System.out.format("%.2f%n", 23466012.83);
If, by any chance, you are not bound to using Double as the container of your numeric values, you may also consider BigDecimal, which can exactly represent an arbitrary value in decimal notation. It takes a lot more memory and is a lot slower in computation, but for many use cases neither of those may matter much. A larger issue is that the division of BigDecimal is an involved process because, by default, the API will insist on producing an exact result, which will fail for things as simple as 1/3.
System.out.format("%f%n", value);
Where value is the double primitive variable you want to print to sysout the screen.
Remove the %n if you want to continue printing on the same line.
There are existing answers that indicate how to format the output if you want the numbers output with two decimal places, regardless of how they were input.
If you really mean "I want the format to be the same as when it was input" there is only one practical option - store the input string. You can parse it as a double or BigDecimal for validation and when you need it as input to arithmetic, but always output it using the original.

How can I stop Java from shortening large double?

Let's suppose we have the following code:
System.out.println(String.valueOf(100000000000.0));
Now the output to that is 1.0E11. But that is not what I want. (Looks bad on a highscore)
I want it to output exactly 100000000000.0. Is there a way to do that?
Format it appropriately. For example:
System.out.printf("%.1f", 1654621658874684.0);
Be aware that double is not infinitely precise. It has a precision of about 15 to 17 decimal digits. If you need floating-point numbers with arbitrary precision, use BigDecimal instead of double.
Or you could use String.format():
System.out.println(String.format("%.0f", 1654621658874684.0d));
System.out.printf("Score: %.0f\n", 1e5); will print 100000.
Refer to this ...
Quest
You can use DecimalFormat to format your value for displaying
For those kind of big numbers, I think you should use BigDecimal.

convert BigDecimal to Scientific Notation Java

How do i print this in scientific notation:
BigDecimal r= (a.subtract(exact, MathContext.DECIMAL128)).divide(exact, MathContext.DECIMAL128).stripTrailingZeros();
DecimalFormat format = new DecimalFormat("0.###E0");
System.out.println(new BigDecimal(format.format(r));
where:
a = 1.111111111111111160454356650006957352161407470703125
exact = 0.11
returns:
r = 0.900010000000000004
any ideas? I've also tried calling EngineeringString() on the BigDecimal but this also didn't seem to work for me
You overdid the thing. What you only need is:
System.out.println(format.format(r));
The DecimalFormat object does indeed create a string, creating a BigDecimal instance again would just parse the number from string again - and the toString() method is called on the BigDecimal instance, produing the output you described...
Some clarification
BigDecimal, and other numeric formats (and dates too!) are stored in binary formats in the memory, abstracted from how us, humans think of them. BigDecimal for example stores the decimal digits, and where the decimal point is. Floating point numbers are even more sophisticated. Date stores the seconds from The Epoch. You need to format them to be readable. Formatting means to create a String (or semantically similar) object, that represents the value of the given object in the desired format. This doesn't involve changing the original object in any way.
The default formatting, toString() provides one generic format. To get your output the way you'd like does not mean to change the value to be formatted right with toString(), but to transform the unchanged value into the right String. Nice example is Double.toString() (using sun.mic.FloatingDecimal): it does exponential notation when the number is large or small enough, but in between, it prints in plain decimal format...

BigDecimal rendering the decimal point according to locale?

related to another issue I found out that:
if I want to display BigDecimal.ZERO in JSF with 2 fraction digits, then I have to hardcode the rounding in my backing bean. Because numberConverter does not work on the constant.
BigDecimal.ZERO.SetScale(2, RoundingMode.HALF_UP); //this works and displays: "0.00"
Unfortunately I cannot use locale-dependent displaying the decimal point with that! I even cannot change the fractions with min/maxFractionDigits after hardcoding the roundingMode.
<f:convertNumber pattern="..." has NOT effect on the display.
This is a real mess, does someone know how to enforce a pattern when displaying a BigDecimal in JSF (not a String! then of course I could use new DecimalFormat).
If the actual format of the textis important - say, you're dealing with locale-dependant data - then you're going to need to use a formatter to render it in a specific 'style'. That's the entire purpose of the class. Using setScale() changes the mathematical precision available to the instance - it doesn't really have any effect (or shouldn't be garuanteed, anyways) about the textual display.

Java and decimals E numbers

Java comes up with numbers like 9.870699812169277E-4
How should I interpret it? Is there a way to parse it in Java and display without that E?
You can use NumberFormat.
Code
// you can format to any output you want
NumberFormat formatter = new DecimalFormat("0.00000000000");
String string = formatter.format(9.870699812169277E-4);
System.out.println(string);
Result
0.00098706998
Related
Java: Format double with decimals and
Format numbers in java
I don't know of any language which doesn't support this notation (except perhaps machine code) Even most calculators support it.
I suspect the languages you have used before support this notation, however it just wasn't used.
9.870699812169277E-4 is the same 9.870699812169277 * 10-4 or 0.0009870699812169277
For your interest there is a P notation e.g. 0x1.fffffffffffffP+1023 which is a hex notation for a double.

Categories