How can I stop Java from shortening large double? - java

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.

Related

Wrong Decimal Converting from Double to String in java

I have A String that is formatted correctly to be cast to a double and it works fine for most decimals. The issue is that for .33, .67, and possibly others I haven't tested, the decimal becomes something like .6700000000002, or .329999999998. I understand why this happens but does any one have a suggestion to fix it.
It's a result of IEEE-754 rounding rules, some numbers cannot be represented precisely in two's complement. For example, 1/10 is not precisely representable.
You can add more precision (but not infinite) by using BigDecimal.
BigDecimal oneTenth = new BigDecimal("1").divide(new BigDecimal("10"));
System.out.println(oneTenth);
Which outputs 0.1
Some decimal numbers can not be represented accurately with the internal base 2 machine representation.
That's double precision for you. Binary numbers and decimals don't work well together. Unless you are doing something really precise it should be fine, if you are printing it you should use either decimal format or printf.
Value of floating point numbers are not stored directly but with exponential values. You may write 3.1233453456356 as number, but this is stored something like 3 and 2^6 in memory. It tries to store a value as close as your number, but those differences can happen.
It shouldn't be a problem unless you're testing for equality. With floating-point tests for equality you'll need to allow a "delta" so that:
if (a == b)
becomes
if (abs(a-b) < 0.000001)
or a similar small delta value. For printing, limit it to two decimal places and the formatter will round it for you.

Java sum of all double does not return expected result [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Moving decimal places over in a double
Why is the following sum of numbers not equal to 0.4622? but 0.46219999999999994
Double total = new Double(0.08) + new Double(0.0491) + new Double(0.3218) +
new Double(0.0113) + new Double(0.0); // = 0.46219999999999994
I have an application that checks the users input.
The user inputs 5 decimal numbers and a total number. The application checks if the sum of all 5 numbers capped at 4 decimals behind the komma is equal to the total number.
Capping it gives me 0.4621 which is not equal to 0.4622. I can't use DecimalFormat because it rounds it up. And if i explicitly say, round down then it will fail for this situation.
Any suggestion for how I can solve this?
Try with java.math.BigDecimal. Double rounds result. You will just have to use add method, not + operator.
Avoid using float and double if exact answers are required-- Item 48 -- Effective Java Second edition
Use BigDecimal instead.
Looks like a classic case of floating point arithmetic. If you want exact calculations, use java.math.BigDecimal. Have a look at What Every Computer Scientist Should Know About Floating-Point Arithmetic
When you use floating point arithmetic you must also use appropriate rounding.
BTW: Don't use an object when a primitive will do.
double total = 0.08 + 0.0491 + 0.3218 + 0.0113 + 0.0;
System.out.printf("%.4f%n", total);
double rounded = Math.round(total * 1e4) / 1e4;
if (rounded == 0.4622)
System.out.println("rounded matched");
prints
0.4622
rounded matched
as expected.
Double and float in Java are internally represented as binary fractions and can therefore be not precise in representing decimal fractions (IEEE standard 754). If your decimal number calculations require precision, use Java.math.BigDecimal.
Floating point representation is a close approximation so you will have these little rounding errors when you use float and double. If you try to convert 0.08 to binary for instance you will realize that you cannot actually do it exactly. You need to consider this whenever you use double and float in calculations.
0.0810 = 0.00010100011110101110...2
a repeating pattern. So no matter how many bits you use this will have a rounding error.
That is yet another rounding issue. You should never compare doubles and expect them to be exactly equal. Instead define a small epsylon and expect the result to be within epsylon of the expected answer.
Any floating point value is inexact. The solution is to use DecimalFormat when you have to display the values. And no, it doesn't round up but to the nearest value.
From the javadoc :
DecimalFormat uses half-even rounding (see ROUND_HALF_EVEN) for
formatting.
The internal representation of floating point numbers like Double is never a exact one. This is why during calculations such errors can occur.
It is always suggested to format such a result to a specific number of digits past the comma, so you result would be correctly be display as "0.4622" with 4 to 15 or more digits.
Perhaps checking the string input directly would be more feasible for you. That is check the length of characters after the decimal place.

Unify 10^x power in a sequence of number

I have a sequence of numbers like this:
1.687155E21
3.981457E19
0.5532155E21
3.018843E21
2.0532155E21
4.5532155E21
3.1637913E19
My problem is how to convert the two numbers which ends with 10^19 to be like the others (10^21). Because after this unification i need to trunc the number to print only something like 3.5.
In C/C++ i know how to work with precision, but in Java I haven't got any idea.
Divide all your number by / 1e19, round to as many decimal digits you want:
168.7155
3.981457
55.32155
301.8843
205.32155
455.32155
3.1637913
Use the Formatter Class to bring them into the desired scientific notation (java.util.Formatter)
I'd suggest something similar as Tomasz Nurkiewicz did, but instead of dividing by 1E19 divide by 1E21, convert them to strings with the required precision using Formatter (see the comment of count0) but not as scientific format, but as a general one. In the end just add E21 to those strings. In the end you should get (I hope, I got the idea correctly)
1.687155E21
0.03981457E21
0.5532155E21
3.018843E21
2.0532155E21
4.5532155E21
0.031637913E21
Can't you just multiply the E19 numbers by 10 ^ 2 = 100?
After they have been normalized to E21, you should be able to divide all of them by 10^21 (if they're floats), and they will all be in the range of 0-9.999...

Displaying doubles to a certain precision in java

I am currently writing a calculator application. I know that a double is not the best choice for good math. Most of the functions in the application have great precision but the ones that don't get super ugly results. My solution is to show users only 12 decimals of precision. I chose 12 because my lowest precision comes from my numerical derive function.
The issue I am having is that if I multiply it by a scaler then round then divide by the scaler the precision will most likely be thrown out of whack. If I use DecimalFormat there is no way to show only 12 and have the E for scientific notation show up correctly, but not be there if it doesn’t need to be.
for example I want
1.23456789111213 to be 1.234567891112
but never
1.234567891112E0
but I also want
1.23456789111213E23 to be 1.234567891112E23
So basically I want to format the string of a number to 12 decimals places, preserving scientific notation, but not being scientific when it shouldn't
Use String.format("%.12G", doubleVariable);
That is how you use format() to display values in scientific notation, but without the scientific notation if not needed. The one caveat is that you end up with a '+' after the 'E', so yours would end up like 1.234567891112E+23
String.format("%.12d", doubleVariable);
Should give you what you are looking for in your first matter. I'm sorry but I don't know how to define when your E-notification is showed.
You'll be interested in BigDecimal, for example:
BigDecimal number = new BigDecimal("1.23456789111213");
number = number.setScale(12, RoundingMode.HALF_UP);
System.out.println(number);
Choose appropriate to you RoundingMode.

How do I format a decimal value to have appropriate amount of trailing spaces

I have a double value which could be either 9.2 or 13.45 or 198.789 or 110.8.
How do I format this to 9.2000 or 13.4500 198.7890 or 110.8000
This SO post can be of help.
Look into the Decimal Format class.
new DecimalFormat("#0.0000").format(9.2); //"9.2000"
See: The DecimalFormat Class under
http://download.oracle.com/javase/tutorial/java/data/numberformat.html
Have a look at DecimalFormat
You can use String.format() to some extent. For example:
String.format("%07.3f", 1.23d); //prints 001.230
The format is %0<width>.<precision>f where, <width> is the minimum number of character (including the dot) that should be printed padded with 0's (in my example there are 7 characters); <precision> is the number of digits after the decimal point.
This method will work for simple formatting, and you cannot control the rounding (rounding is is half-up by default).

Categories