I am using DecimalFormatter to read in formatted decimal string values and convert them to float. However, when I run:
DecimalFormat formatter = new DecimalFormat("####,####.00");
String floatStr = "177,687.71";
float val1 = formatter.parse(floatStr).floatValue();
System.out.println(val1);
...I get 177678.7 instead of 177678.71. Why is this? How do I avoid rounding the hundredths place?
Thanks!
You appear to need more precision than a float to represent that number.
Taking the formatter out of the picture:
Float.parseFloat("177687.71");
177687.7 // Ouch
Double.parseDouble("177687.71");
177687.71 // Ok
It seems that you'll need to use a double instead.
If this is for representing money though as #Dawood is suggesting , then yes, do not use floating types to represent money, since they are estimations and will accumulate errors over time. A format like BigDecimal would be more appropriate, or even just storing an integer representing cents. Money is not something that you want to subject to rounding errors.
Related
I've been looking for a way to convert a double, which is big to a readable String.
The double:
double myValue = 1000000000000000.123456789;
Which when printed out gives me this:
1.0000000000000001E15
The result im looking for would be this:
1.000.000.000.000.000,12
I've been searching for this for days but i couldn't find a solution for this unfortunately so i thought maybe i could ask here:) thanks for reading!
If you are interested in setting your own separator characters (i.e. not using the default for your locale) then you can do the following:
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setGroupingSeparator('.');
symbols.setDecimalSeparator(',');
DecimalFormat format = new DecimalFormat("#,##0.00", symbols);
System.out.println(format.format(100000000000.123456789));
You also mentioned rounding in your question. Unfortunately that has nothing to do with the formatting at all - you are hitting the limit of precision for double in Java. A double is a 64 bit floating points which gives you 15-16 digits of precision. You can verify this by checking the following expression in Java: 1000000000000000.123456789 == 1000000000000000.1.
So, in reality what is happening is that once you have assigned your value to the myValue variable it has already been rounded. It doesn't matter how you format it from that point you won't get the precision back.
If you need greater precision than double you should look at BigDecimal that supports arbitrary precision.
I'm doing calculations on High decimal precision BigDecimal objects.
I'm using a third party library that requires the parameter in double. When I try to convert this to double i get the values in exponential format instead of decimals .
BigDecimal 0.000035000000000
Double 3.5E-5
BigDecimal bd;
BigDecimal(0.0000349999999995631583260546904057264328002929687500);
bd= bd.setScale(15,BigDecimal.ROUND_CEILING);
Log.i("bd","bd "+bd.toPlainString());
Log.i("bd","double"+bd.doubleValue());
I have found various ways of converting this 3.5E-5 value as correct decimal in points but in String format only . Whereas I need the value in double
Able to get without exponential in String object But not in double
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(16);
String test=df.format(bd,doubleValue());
System.out.println("op2 "+test);
Double test1=Double.parseDouble(test);
System.out.println("op2 "+test1);
OUTPUT op2 .000035 op2 3.5E-5
I'm struggling since since days to find a solution as I have no control over 3rd party library that requires the value to be in double
Refferred Links
Format BigDecimal without scientific notation with full precission
Converting exponential value in java to a number format
Conversion from exponential form to decimal in Java
How to resolve a Java Rounding Double issue
Java BigDecimal without E
How to Avoid Scientific Notation in Double?
My question is different then these links, I do not want the double as string without exponential instead I want it in double format only.
EDIT
If the double value passed is in exponential format, the NDK based libary will further do calculations on this object, which will result inmore decimal points and larger Exponential value. So, I want to pass a simple double without E
You seem to be confusing a double, a 64 bit value where different bits have a different meaning, with its string representation.
Let's take a value of 0.015625. Internally, the double is represented as 64 bits (I don't know right now which combination of bits, but that is irrelevant anyway).
But the string representation depends on the format settings of the library you are using. Note that the representations 0.015625 and 1.5625E-2 represent the exact same double value. The double is not stored as a string, it does not contain a . or an E, just a number of bits. The combination of these bits form its real value, and it is the same, no matter how you represent it as a string. If you have a different format setting, the result can just as well be 1.56E-2. This just means that the code that converts the internal bit combination of the double to a string does some rounding.
So, to obtain a double from a BigDecimal, simply use bd.doubleValue(). There is no need to use an intermediate string representation, and it can even be detrimental to do so, because if the string representation performs some rounding, you don't get the best approximation of the value in the BigDecimal.
So again, bd.doubleValue() is the only correct way to do this. This does not return a specific format, it simply returns the double that is closest to the value in the BigDecimal.
And again, do not confuse the double type with how it is represented as a string. These are different things. A double is a double is a double, and that is not stored as a string, exponential or plain or rounded or whatever.
Actually, BigDecimal.toString() and BigDecimal.toPlainString() also return different string representations of the same BigDecimal. AFAIK, there is even a third string conversion function, toEngineeringString(), which gives you yet another string representation of the same BigDecimal. This is similar for double: different output routines with different arguments return different strings for the exact same value.
use this: amount=value to be converted to double from string
double dd = new BigDecimal(amount).doubleValue();
String val = String.format("%.4f", dd);
BigDecimal bd = BigDecimal.valueOf(Double.valueOf(val));
Double d=bd.doubleValue() ;
DecimalFormat formatter = new DecimalFormat("0.0000");
System.out.println("doubleValue= " + formatter .format(d));
In Android, the value entered into the EditText is converted to float using the following line of code.
Float addPurchUnitCostPrice = Float.valueOf(addPurchaseCostPrice.getText().toString());
I would like to have the value of addPurchUnitCostPrice with 2 decimal places (always). How can this be done?
Floating-point values don't have decimal places. They have binary places, and the two are incommensurable. If you want decimal places you have to use a decimal radix, i.e. BigDecimal.
You will be better off using the currency formatter in Android, however it requires a double. The currency formatter will also deal with countries that use commas in place of decimal points.
So change your code to
double addPurchUnitCostPrice = Double.parseDouble(addPurchaseCostPrice.getText().toString());
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
String formattedPrice = currencyFormat.format(price);
You will create price with 2 decimal places and format according to the country defined by the users device.
You can just use BigDecimal for that
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to round a number to n decimal places in Java
I am having difficulties rounding a float to two decimal places. I have tried a few methods I have seen on here including simply just using Math.round(), but no matter what I do I keep getting unusual numbers.
I have a list of floats that I am processing, the first in the list is displayed as 1.2975118E7. What is the E7?
When I use Math.round(f) (f is the float), I get the exact same number.
I know I am doing something wrong, I just am not sure what.
I just want the numbers to be in the format x.xx. The first number should be 1.30, etc.
1.2975118E7 is scientific notation.
1.2975118E7 = 1.2975118 * 10^7 = 12975118
Also, Math.round(f) returns an integer. You can't use it to get your desired format x.xx.
You could use String.format.
String s = String.format("%.2f", 1.2975118);
// 1.30
If you're looking for currency formatting (which you didn't specify, but it seems that is what you're looking for) try the NumberFormat class. It's very simple:
double d = 2.3d;
NumberFormat formatter = NumberFormat.getCurrencyInstance();
String output = formatter.format(d);
Which will output (depending on locale):
$2.30
Also, if currency isn't required (just the exact two decimal places) you can use this instead:
NumberFormat formatter = NumberFormat.getNumberInstance();
formatter.setMinimumFractionDigits(2);
formatter.setMaximumFractionDigits(2);
String output = formatter.format(d);
Which will output 2.30
You can make use of DecimalFormat to give you the style you wish.
DecimalFormat df = new DecimalFormat("0.00E0");
double number = 1.2975118E7;
System.out.println(df.format(number)); // prints 1.30E7
Since it's in scientific notation, you won't be able to get the number any smaller than 107 without losing that many orders of magnitude of accuracy.
Try looking at the BigDecimal Class. It is the go to class for currency and support accurate rounding.
I'm trying to convert a double to a string without notation, and tried this:
f= Double.valueOf(c.getString(c.getColumnIndex(NotesDbAdapter.KEY_VALUE)));
NumberFormat formatter = new DecimalFormat("###.##############");
However, the value of 7^3^7 is returning as: 558546000000000000 opposed to 558545864083284007. As always help would be greatly appreciated.
You already had the value as a String. Why convert it to double at all?
You can't get precision out of a double that it cannot hold. 558545864083284007 has 18 decimal digits. A double has 53 bits of binary precision, which is about 15.9 decimal digits. Google for 'What every computer scientist should know about floating-point'.
###.############## is not a suitable formatting mask for 558545864083284007.
If you already have the huge decimal number in string format, try using the BigDecimal class, something like this:
BigDecimal bigDecimalValue = new BigDecimal("1234567890123456789012345678901234567890.54321");
LOGGER.info("bigDecimalValue: {}", bigDecimalValue.toPlainString());
You should get back the original value with no precision loss:
bigDecimalValue: 1234567890123456789012345678901234567890.54321