Parse double on string giving wrong result - java

In my project I am getting a string values from an api and need to pass double values to another api. When I try to parse from string values to double I am not getting the original data.
Here is the code.
String l1="11352721345377306";
String l2="11352721346734307";
String l3="11352721346734308";
String l4="11352721346734309";
DecimalFormat df = new DecimalFormat(".00");
System.out.println(df.format(Double.parseDouble(l1)));
System.out.println(df.format(Double.parseDouble(l2)));
System.out.println(df.format(Double.parseDouble(l3)));
System.out.println(df.format(Double.parseDouble(l4)));
The output is
11352721345377306.00
11352721346734308.00
11352721346734308.00
11352721346734308.00
What went wrong? Is there any problem with parsing? How can i get the original values back.?
Edit: Without using Decimal Format:
1.1352721345377306E16
1.1352721346734308E16
1.1352721346734308E16
1.1352721346734308E16

You can't get original values back. Refer this Java's Floating-Point (Im)Precision.

double only has 15/16 digits of accuracy and when you give it a number it can't represent, it takes the closest representable number.

What is the problem ? ".00" ? If you don't need this, why using a Double ?
You can try like this...
String l1="11352721345377306";
String l2="11352721346734307";
String l3="11352721346734308";
String l4="11352721346734309";
Double d1 = Double.parseDouble(l1);
Double d2 = Double.parseDouble(l2);
Double d3 = Double.parseDouble(l3);
Double d4 = Double.parseDouble(l4);
System.out.println(d1.longValue());
System.out.println(d2.longValue());
System.out.println(d3.longValue());
System.out.println(d4.longValue());
Edit, with BigDecimal to get the correct values:
String l1="11352721345377306";
String l2="11352721346734307";
String l3="11352721346734308";
String l4="11352721346734309";
BigDecimal bd1 = new BigDecimal(l1);
BigDecimal bd2 = new BigDecimal(l2);
BigDecimal bd3 = new BigDecimal(l3);
BigDecimal bd4 = new BigDecimal(l4);
System.out.println(bd1);
System.out.println(bd2);
System.out.println(bd3);
System.out.println(bd4);
Output is:
11352721345377306
11352721346734307
11352721346734308
11352721346734309

You can use
double d = Math.round(Double.parse(yourString) * 100.0) / 100.0;
to get double with rounded decimals.
For printing use:
String formatted = String.format("%.2f", yourDouble);

Related

How to remove scientific notation from double for longest double value

I am experiencing a problem in Double value manipulation.
Lets take,
Double d = new Double(123456789987654321123456789d);
System.out.println(d);
The output is :
1.2345678912345678E35
But I want,
123456789987654321123456789
The complete digit without any notation.
I have tried all permutation using BigDecimal, BigInteger and so and so.
Note: I want to populate into JSON so please don't suggest just a print statement.
I have already read :
How to Avoid Scientific Notation in Double?
Formatting a double and not rounding off
Try this BigDecimal::toPlainString:
BigDecimal d = new BigDecimal("123456789987654321123456789");
String result = d.toPlainString();
Output of d is :
123456789987654321123456789
To populated to JSon there are many ways, I'm not sure what you want exactly, but maybe this can help you How to create JSON Object using String?:
BigDecimal d = new BigDecimal("123456789987654321123456789");
JSONObject myObject = new JSONObject();
myObject.put("number", d.toPlainString());
You can try this
String str = String.format("%.0f", d);
Note that max digits a double can hold is ~17, so 123456789987654321123456789 will rounded

Convert String to Double without BigDecimal type and without loss precision - java

I have a problem when converting a String to Double.
Decimals that remain to the right and are 0 are lost.
I have seen you can solve with the BigDecimal type, but I don't want to use it.
Anyone know any way to fix it?
Regards,
This is an example(using java.Text.DecimalFormat):
Double d = 0.85; // 0.85
DecimalFormat mf = new DecimalFormat("#0.000");
String s = mf.format(d); // "0,850"
s = s.replace(',', '.'); // "0.850"
double conv = Double.parseDouble(s); //0.85
//String -> Double = 0.850???

Round Double value and exponential notation (java)

how to round "3.416436417734133 in "3.416436418" (nine positions after point) but also if i have "3.7578845854848E41" it round to "3.7578845855E41"? i'm trying to realyze a calculator..
You can use DecimalFormat, I am not sure about the other numbers but currently you have numbers which have single digit before the decimal point. So, check following example where you can format the double value. Note one more thing that you may need to change format pattern for your use case.
FOR EXAMPLE :
double d = 3.7578845854848E41;
double d2 = 3.416436417734133;
DecimalFormat f = new DecimalFormat("0.#########E0");
System.out.println(f.format(d));
System.out.println(f.format(d2));
OUTPUT :
3.757884585E41
3.416436418E0
//Replace E0 with space as format returns String
EDIT :
Because of your default locale. You can change local like this,
//Change locale
DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(Locale.US);
DecimalFormat f = new DecimalFormat("0.#########E0", decimalFormatSymbols);
//And than use decimal format
You may use BigDecimal to add a "scale" to your double value :
Double d = 3.416436417734133;
BigDecimal round = new BigDecimal(d);
round = round.setScale(9, BigDecimal.ROUND_CEILING);
System.out.println(round);
You can use this code.
BigDecimal aDecimal = new BigDecimal(3.416436417734133);
BigDecimal another = aDecimal.setScale(9, aDecimal.ROUND_HALF_UP);
System.out.println("another: " + another);
System.out.println(new BigDecimal(3.7578845854848E41,new
MathContext(11,RoundingMode.CEILING)));

How to always round off upto 2 decimal places in java

I have tried the following code but it is not working in a particular case.
Eg: Suppose, I have a double value=2.5045 and i want it to be rounded off upto two decimal places using the below code.After rounding off, i get the answer as 2.5. But I want the answer to be 2.50 instead. In this case,zero is trimmed off. Is there any way to retain the zero so as to get the desired answer as 2.50 after rounding off.
private static DecimalFormat twoDForm = new DecimalFormat("#.##");
public static double roundTwoDecimals(double amount) {
return Double.valueOf(twoDForm.format(amount));
}
try this pattern
new DecimalFormat("0.00");
but this will change only formatting, double cannot hold number of digits after decimal poin, try BigDecimal
BigDecimal bd = new BigDecimal(2.5045).setScale(2, RoundingMode.HALF_UP);
Look at the documentation for DecimalFormat. For # it says:
Digit, zero shows as absent
0 is probably what you want:
Digit
So what you are looking for is either "0.00" or "#.00" as a format string, depending on whether you want the first digit before the period, to be visible in case the numbers absolute value is smalle than 0.
Try this
DecimalFormat format = new DecimalFormat("#");
format.setMinimumFractionDigits(2);
answer.setText(format.format(data2));
Try This
double d = 4.85999999999;
long l = (int)Math.round(d * 100); // truncates
d = l / 100.0;
You are returning a double. But double or Double are objects representing a number and don't carry any formatting information. Ìf you need to output two decimal places the point to do this is when you convert your double to a String.
use # if you want to ignore 0
new DecimalFormat("###,#0.00").format(d)
There is another way to achieve this . I have already posted answer in post
will just answer again here. As we will require rounding off values many times .
public class RoundingNumbers {
public static void main(String args[]){
double number = 2.5045;
int decimalsToConsider = 2;
BigDecimal bigDecimal = new BigDecimal(number);
BigDecimal roundedWithScale = bigDecimal.setScale(decimalsToConsider, BigDecimal.ROUND_HALF_UP);
System.out.println("Rounded value with setting scale = "+roundedWithScale);
bigDecimal = new BigDecimal(number);
BigDecimal roundedValueWithDivideLogic = bigDecimal.divide(BigDecimal.ONE,decimalsToConsider,BigDecimal.ROUND_HALF_UP);
System.out.println("Rounded value with Dividing by one = "+roundedValueWithDivideLogic);
}
}
Output we will get is
Rounded value with setting scale = 2.50
Rounded value with Dividing by one = 2.50
double kilobytes = 1205.6358;
double newKB = Math.round(kilobytes*100.0)/100.0;
DecimalFormat df = new DecimalFormat("###.##");
System.out.println("kilobytes (DecimalFormat) : " + df.format(kilobytes));
Try this if u are still getting the above problem

Java BigDecimal without E

I have a BigDecimal variable
BigDecimal x = new BigDecimal("5521.0000000001");
Formula:
x = x.add(new BigDecimal("-1")
.multiply(x.divideToIntegralValue(new BigDecimal("1.0"))));
I want to remove the integer part, to get the value x = ("0.0000000001"), but my new value is 1E-10 and not the 0.0000000001.
To get a String representation of the BigDecimal without the exponent part, you can use
BigDecimal.toPlainString(). In your example:
BigDecimal x = new BigDecimal("5521.0000000001");
x = x.add(new BigDecimal("-1").
multiply(x.divideToIntegralValue(new BigDecimal("1.0"))));
System.out.println(x.toPlainString());
prints
0.0000000001
Try using BigDecimal.toPlainString() to get value as plain string as you require.
Perhaps using BigDecimal isn't really helping you.
double d = 5521.0000000001;
double f = d - (long) d;
System.out.printf("%.10f%n", f);
prints
0.0000000001
but the value 5521.0000000001 is only an approximate representation.
The actual representation is
double d = 5521.0000000001;
System.out.println(new BigDecimal(d));
BigDecimal db = new BigDecimal(d).subtract(new BigDecimal((long) d));
System.out.println(db);
prints
5521.000000000100044417195022106170654296875
1.00044417195022106170654296875E-10
I suspect whatever you are trying to is not meaningful as you appear to be trying to obtain a value which is not what you think it is.
If you want to do this at your BigDecimal object and not convert it into a String with a formatter you can do it on Java 8 with 2 steps:
stripTrailingZeros()
if scale < 0 setScale to 0 if don't like esponential/scientific
notation
You can try this snippet to better understand the behaviour
BigDecimal bigDecimal = BigDecimal.valueOf(Double.parseDouble("50"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
if (bigDecimal.scale()<0)
bigDecimal= bigDecimal.setScale(0);
System.out.println(bigDecimal);//50
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50.20"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
if (bigDecimal.scale()<0)
bigDecimal= bigDecimal.setScale(0);
System.out.println(bigDecimal);//50.2
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
System.out.println(bigDecimal);//5E+1
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50.20"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
System.out.println(bigDecimal);//50.2

Categories

Resources