I have a long type value which represents cents in currency. I try to convert it to euros. So, I did the following:
long val = 348;
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.FRANCE);
System.out.println(nf.format(val/100));
I thought the above code will print out 3,48 € but I got 3,00 €. Why?
because val/100 is an Integer operation, so the deciaml part is stripped away. For instane
int i = 1; int result = i / 2; will give you 0
Change to System.out.println(nf.format(((float)val/100)));
To force floating point arithmetic , you can use a double literal 100.0 or float literal 100.0f :
System.out.println(nf.format(val/100.0));
Related
How can I get an Integer to be two digits. If it's under 10 it would show 01,02, etc. I want to keep the Integer as an Integer. String.format gives a string. How can I do this with Decimalformat for ex
Decimalformat df = new Decimalformat(???);
If you want to keep the value as an int or Integer, there's nothing to be done here. A number doesn't have a format - it just has a value. For example, an int isn't "in decimal" or "in hex" or "in binary" - if you write
int x = 16;
int y = 0x10;
those are the exact same values.
The idea of "padding" only makes any sense when it comes to a textual representation of the number - which is when you end up with a string.
you do something likewise, but directly you can't get into int or Integer
NumberFormat formatter = new DecimalFormat("00");
String s = formatter.format(1); // ----> 01
I need a line of code that I can use to get the digits after the decimal place when I execute
the code below:
double results = 1500 / 1000;
txtview.setText("K " + resultsoldk);
I need the results to include the reminder as well.
The problem is that the result of
double results = 1500 / 1000;
is 1.0, not 1.5, because you are doing integer division. Make sure at least one of the numbers is a floating-point number when you do the division. For example:
// By adding .0 you make it a double literal instead of an int literal
double results = 1500.0 / 1000;
You can cast using double like below
double results = (double)1500 / 1000;
Also you can format the result using DecimalFormat
DecimalFormat df = new DecimalFormat("0.00##");
String formattedResult=df.format(results);
You can use the String.format(...) method to format the String like this:
txtview.setText(String.format("K %f", resultsoldk));
However, this will not work in you case. As you are dividing two integers, the result will be an integer (which has no remainder). Afterwards it is converted to a double (because you assign it to a double) but at this point, the precision is already lost. You must at least convert one of the integers to a double before you divide them:
double results = (double)1500 / 1000;
or, if you use constants
double results = 1500.0 / 1000;
or
double results = 1500 / 1000.0;
or even
double results = 1500.0 / 1000.0;
String strResult = Double.toString(d);
strResult = strResult.replaceAll("\\d?\\.", "");
Don't know if I get it, but if what you want is the digits after the dot, then you can use this regex.
I am truncating a float here.But my value is getting rounded.I do not want that.E.g If my value is 12.989 -> it should be printed as 12.98 only. Can someone help
I cannot use decimal format's SetRoundingMode because that is supported from java 1.6 only.
Mine is 1.5 JDK. CAn someone help me out without using SetRoundingMode() Method????
String pattern = "##,##0.00";
NumberFormat nf = NumberFormat.getNumberInstance();
DecimalFormat df = (DecimalFormat)nf;
double fPart;
Float value=233.989f;
String dstr = String.valueOf(value);
dstr = dstr.substring(dstr.indexOf(".")+1);
Long db = Long.valueOf(dstr);
if(db > 0){
df.applyPattern(pattern);
System.out.println("input="+value+", fPart="+dstr);
}
String output = df.format(value);
System.out.println(output);
You can always use old school trick, multiply by 10^n, truncate, divide by 10^n:
float x = 233.989f;
x = (float)(Math.floor(x * 100) / 100);
I've also experimented with BigDecimal:
MathContext mc = new MathContext(5, RoundingMode.FLOOR)
BigDecimal decimal = new BigDecimal(233.989, mc);
System.out.println(decimal);
It does the job but you have to specify total number of digits. You can't just say I want 2 decimal places and I don't care about digits left of decimal point. That's way first parameter of MathContext is 5, not 2. If you opt for this approach, you can quickly calculate non decimal digits with Math.Ceil(Math.log10(x)).
Note:
When dividing (first approach) at least one of operands must be floating point (float or double)
When working with strings (you code), it's not safe to presume that '.' is decimal separator
Truncating decimals with Math.floor only works for positive values
Not sure If I understood you problem correclty. But If you want to truncate without rounding up or down, you can use just like
DecimalFormat df = new DecimalFormat("##.##");
df.format(12.912385);
You can use regular expressions to get the second digit after "." and then subtract the string from the beginning to that position and then transform the string into a float or double.
Pattern pattern = Pattern.compile("regular expression");
Matcher matcher = pattern.matcher("your string");
if(matcher.find())
{
int poz_begin = matcher.start();
int poz_end = matcher.end();
}
In my app want to round a double to 2 significant figures after decimal point. I tried the code below.
public static double round(double value, int places) {
long factor = (long) Math.pow(10, places);
value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}
also i tried
double val = ....;
val = val*100;
val = (double)((int) val);
val = val /100;
both code do not working for me.
Thanks in advance....
As Grammin said, if you're trying to represent money, use BigDecimal. That class has support for all sorts of rounding, and you can set you desired precision exactly.
But to directly answer your question, you can't set the precision on a double, because it's floating point. It doesn't have a precision. If you just need to do this to format output, I'd recommend using a NumberFormat. Something like this:
NumberFormat nf = NumberFormat.getInstance();
nf.setMinimumFractionDigits(2);
nf.setMaximumFractionDigits(2);
String output = nf.format(val);
Or you can use a java.text.DecimalFormat:
String string = new DecimalFormat("####0.00").format(val);
I would recommend using BigDecimal if you are trying to represent currency.
This example may be helpful.
As Gramming suggested you could use BigDecimals for that, or NumberFormat tobe sure about the number of shown figures
Your code appears to work to me
double rounded = round(0.123456789, 3);
System.out.println(rounded);
>0.123
Edit: just seen your new comment on your question. This is a formatting problem, not a maths problem.
I took the decision to use all as int. In this way no problem.
DecimalFormatSymbols currencySymbol = DecimalFormatSymbols.getInstance();
NumberFormat numberF = NumberFormat.getInstance();
after...
numberF.setMaximumFractionDigits(2);
numberF.setMinimumFractionDigits(2);
TextView tv_total = findViewById(R.id.total);
int total = doYourStuff();//calculate the prices
tv_total.setText(numberF.format(((double)total)/100) + currencySymbol.getCurrencySymbol());
I would like to convert a possibly Decimal value prefixed with currency symbol into only numeric value.
For example -
The value can be like any of the following
String s1 = "£32,847,676.65";
String s2 = "£3,456.00";
String s3 = "£831,209";
I would like the result after conversion to be like - 32847676.65, 3456.00 and 831209.
I tried using the parse() method of the NumberFormat in this way -
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.UK);
numberFormat.setMinimumFractionDigits(2);
Number num = nf.parse(s1);
double dd = num.doubleValue();
BigDecimal gg = new BigDecimal(dd);
System.out.println(gg);
But the result is - 32847676.649999998509883880615234375 which is not quite exactly the correct one.
I need it to be numeric so that may be I can perform some kind of calculation.
Can you guys guide me with what else can I try
You already parse the value correctly. The problem is this:
BigDecimal gg = new BigDecimal(dd);
You covnert the value to BigDecimal, and the rounding problems of doubles account for the decimal places after the dot. Use:
BigDecimal gg = new BigDecimal(dd).setScale(2);
or
BigDecimal gg = new BigDecimal(dd).setScale(2,RoundingMode.HALF_UP);
When playing with BigDecimal, the appropriate constructor is BigDecimal(String val)
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.UK);
BigDecimal gg = new BigDecimal(nf.parse(s1).toString());
System.out.println(gg);
BigDecimal(double val) does construct an exact decimal representation of the double value, which is not the human readable value you expected.
"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 (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
[...]
Therefore, it is generally recommended that the String constructor be used in preference to this one"
Source : BigDecimal javadoc
You can try the following without BigDecimal or NumberFormat. ;)
String s1 = "£32,847,676.65";
// remove the £ and ,
String s2 = s1.replaceAll("[£,]", "");
// then turn into a double
double d = Double.parseDouble(s2);
// and round up to two decimal places.
double value = (long) (d * 100 + 0.5) / 100.0;
System.out.printf("%.2f%n", value);
prints
32847676.65
If youw ant to avoid rounding error in your calculations but don't want the heavy weight BigDecimal you can use long cents.
// value in cents as an integer.
long value = (long) (d * 100 + 0.5);
// perform some calculations on value here
System.out.printf("%.2f%n", value / 100.0);
It is not guaranteed to work, but according to the NumberFormat API documentation, its getXyzInstance methods will return a DecimalFormat instance for "the vast majority of locales". This can probably be interpreted as "for all locales, unless proprietary locale service providers are installed".
If you can cast your NumberFormat to DecimalFormat, you can tell it to parse to a BigDecimal directly, reducing your code to:
DecimalFormat nf = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.UK);
nf.setParseBigDecimal(true);
BigDecimal gg = (BigDecimal) nf.parse(s1);
System.out.println(gg);
In this case, you will have no problem with the inaccuracy of binary floating point numbers.