How to get the value without round up/down in Java? [duplicate] - java

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
double d0 = Double.parseDouble("53.82233040000000557");
double d1 = Double.valueOf("53.82233040000000557");
output
d0 = 53.822330400000006
d1 = 53.822330400000006

Precision Numbers in Java
Class java.math.BigDecimal is better for handling numbers where precision matters (like monetary amounts), see BigDecimal VS double.
It could be used for geo-coordinates (latitude/longitude). Although practitionars argue that double is precise enough for lat./long. - since you don't want to locate something at nano-meter scale.
Example Code
If you need high precision and scale for your number, use BigDecimal like this:
BigDecimal decimalValue = new BigDecimal("53.82233040000000557");
System.out.println("as BigDecimal: " + decimalValue.toPlainString());
// prints exactly: 53.82233040000000557
Run this code online (IDE one): Double VS BigDecimal for high precision
Read more
Read more in a tutorial on Java: BigDecimal and BigInteger

If you need precision, you have to use a BigDecimal.

The answer is that you cannot. The values you are getting are the most accurate approximation to your values that can possibly be stored in a double. There is no possible way to get a more accurate, less rounded value stored in a double.
If you require that the answers are not rounded at all, therefore, you should not be using double. The data type you should be using instead is BigDecimal.

Related

Formatting Double to String? [duplicate]

This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Closed 3 years ago.
String.format("%,.0f", 200000000000000000000000.0)
-> 199,999,999,999,999,980,000,000
why?
Understand the Double Data type - it is an approximation of amount and scale.
The Following assignment:
double d = 2.00000000000f;
will generate a value of 1.9999999 at times when printed. What you are seeing here is magnification of that. Double Data types also have a maximum (implementation-dependant) of how many places of significance they can support (upto 15 generally) - which is why the last 6 digits are all zeros (0)
For your particular solution, if you don't require Floating-point Data, stick to Integer.
It is because current processors(and most VMs) work like that if use default data types. Here it is explained in details
If you want precision use BigDecimal. This class is specifically intended for situations like this - to be used in currency related stuff and scientific calculations.
To format decimals in proper way Java has DecimalFormat
String pattern = "###,###.###";
DecimalFormat decimalFormat = new DecimalFormat(pattern);
String format = decimalFormat.format(123456789.123);
System.out.println(format); // -> 123.456.789,123
Here is nice tutorial about it
Hope it helps.
My problem has been solved
String.format("%,.0f", BigDecimal( 200000000000000000000000.0, MathContext.DECIMAL64))

new BigDecimal(double) vs new BigDecimal(String) [duplicate]

This question already has answers here:
BigDecimal from Double incorrect value?
(4 answers)
Convert double to BigDecimal and set BigDecimal Precision
(8 answers)
Closed 7 years ago.
When BigDecimal is used with an input of double and BigDecimal with an input of String different results seem to appear.
BigDecimal a = new BigDecimal(0.333333333);
BigDecimal b = new BigDecimal(0.666666666);
BigDecimal c = new BigDecimal("0.333333333");
BigDecimal d = new BigDecimal("0.666666666");
BigDecimal x = a.multiply(b);
BigDecimal y = c.multiply(d);
System.out.println(x);
System.out.println(y);
x outputs as
0.222222221777777790569747304508155316795087227497352441864147715340493949298661391367204487323760986328125
while y is
0.222222221777777778
Am I wrong in saying that this is because of double imprecision? But since this is a BigDecimal, shouldn't it be the same?
Am I wrong in saying that this is because of double imprecision?
You are absolutely right, this is exactly because of double's imprecision.
But since this is a BigDecimal, shouldn't it be the same?
No, it shouldn't. The error is introduced the moment you create new BigDecimal(0.333333333), because 0.333333333 constant already has an error embedded in it. At that point there is nothing you can do to fix this representation error: the proverbial horse is out of the barn by then, so it's too late to close the doors.
When you pass a String, on the other hand, the decimal representation matches the string exactly, so you get a different result.
Yes, this is floating point error. The problem is that the literals 0.333333333 and 0.666666666 are represented as doubles before being passed as an argument to BigDecimal --- notably, BigDecimal's constructor takes a double as an argument.
This is supported by the standard, which says that floating point literals default to double unless otherwise specified.
Java docs has its answer. According to Java docs of BigDecimal(double val)
The results of this constructor can be somewhat unpredictable. One
might assume that writing new BigDecimal(0.1) in Java creates a
BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with
a scale of 1), but it is actually equal to
0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double.
When you define a double variable in any way, in most cases it won't be the value you have defined, but the closest possible binary representation. You are passing a double to the constructor, so already providing that small imprecision.

Converting string to float in Java without round it [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Rounding in java Float.parseFloat
I want to convert strings to float i say:
System.out.println(Float.parseFloat("1553781.9829"));
Output:
1553782.0
I say:
System.out.println(Float.valueOf("1553781.9829"));
Output:
1553782.0
How to get Float without lossing precision?
use System.out.println(Double.parseDouble("1553781.9829")); instead
float has a limitation of smaller size (4 bytes) so it's not good for big decimals, double has the double size (8 bytes)
If you are looking for accuracy, I would suggest BigDecimal
This is just like normal wrapper class which provides methods for all your operations. And yes it takes argument as String as well.
BigDecimal bd = new BigDecimal("1553781.9829");
System.out.println(" bd :"+ bd); //prints the same value
URL : http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigDecimal.html
You cannot use float or double without a risk of losing precision. First of all their precision is limited, for float it is approx 7-8 decimal digits, for double ~16 digits. Apart from that Java floating points types are binary internally so they cannot store some decimal fractions without losing precision. If you really need exact decimal fractions use java.math.BigDecimal. Read "Effective Java" Item 48: "Avoid float and double if exact answers are required".
Instead of Float you can use Double
System.out.println(Double.valueOf("1553781.9829"));
System.out.println(Double.parseDouble("1553781.9829"));

Getting numbers after decimal Java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Strange floating-point behaviour in a Java program
Why does JSP/JSTL division by 1000 sometimes give remainder?
I am trying to get the numbers after the decimal.
ex: 60.4 -> 0.4
Yet, when do
double a = 60.4 % 1;
it comes out to be 0.3999999999999986.
Why is this? And how could it be fixed?
Use fixed-point types
BigDecimal src = new BigDecimal("60.4");
BigDecimal a = src.remainder(BigDecimal.ONE);
You can use DecimalFormat to do your desired task.
OK here is how you can do: How to get the numbers after the decimal point? (java)
I think this is exactly what you are looking for. So essentially you can use:
double x = d - Math.floor(d);
OR
BigDecimal class for exact digits after decimal.

how to fix double precision issue in java [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java floats and doubles, how to avoid that 0.0 + 0.1 + … + 0.1 == 0.9000001?
How can I overcome the precision issue with double multiplication in java android??Please note that I am converting a string value into double value.
eg: when I multiply two double value:
double d1 = Double.valueOf("0.3").doubleValue() * Double.valueOf("3").doubleValue();
System.out.println("Result of multiplication : "+d1);
I am getting the following result : 0.8999999999999999
Some of the results that i am getting are.
0.6*3=1.7999999999999998;
0.2*0.2=0.04000000000000001;
etc.
Instead of the above results I would like to get the following results.
0.3*3=0.9;
0.6*3=1.8;
0.2*0.2=0.04;
Please remember that I am not trying to round it to the nearest integer.
You should really be using java.math.BigDecimal to avoid any precision issues, and always use a BigDecimal(String) constructor.
BigDecimal result = new BigDecimal("0.3").multiply( new BigDecimal("3.0") );
The problem isn't with multiplication. It starts with Double.valueOf("0.3"). That value can't be represented exactly in floating-point. You should use java.math.BigDecimal, and you should also Google for a page entitled "What every computer scientist should know about floating point".
Unfortunately, I am not aware of a simple way of doing exactly what you ask for.
Like Strelok says, you should not be using a floating-point type if you need exact results. However, for most purposes, it is enough to just specify a rounding precision for output. The following code is close to, but not quite, what you want:
System.out.printf("Result of multiplication : %.1g\n", d1);
For more info on the syntax of printf, see the java.util.Formatter documentation.

Categories

Resources