I would like the convert string value with 3 significant digits.
I am using this code :
String s = "0,92";
float f = Float.parseFloat(s);
DecimalFormat formatter = new DecimalFormat("#,###");
String end = formatter.format(f);
The result is end= 0.000. But ı want to get end = 0,920. How can i do that?
If in your current locale the decimal separator is a dot then you will get 0.920. If you want to get the result independent from you current locale to have as decimal separator a comma and as thousand separator a dot you could achieve it for example like this
String s = "0.92";
float f = Float.parseFloat(s);
DecimalFormat formatter = new DecimalFormat("0.000", DecimalFormatSymbols.getInstance(Locale.GERMANY));
String end = formatter.format(f);
System.out.println("end = " + end);
This prints
end = 0,920
This works for me:
String s = "0.92";
float f = Float.parseFloat(s);
DecimalFormat formatter = new DecimalFormat("0.000");
String end = formatter.format(f);
System.out.println(end);
Please note the '.' in the String s and the pattern in DecimalFormat.
',' here means the 1000 marker, ie. 1,000,000.00 for one million.
Related
I have a text file with entries of numbers in the format of 00:00. I know how to read this String from the file. What I don't know is how to parse it so that the left side of the decimal knows to join with the right side as one number.
If I do a split within a split, the inner split gives me two values when I only want one.
File database = new File (FILE);
Scanner read = new Scanner (database);
String [] dataEntry;
String [] times;
float [] correctTime = null;
while (read.hasNext ())
{
dataEntry = read.nextLine().split(",");
times = dataEntry[0].split(":");
correctTime = new double[times.length];
//I get stuck here, I know the above line is incorrect
}
I guess you want to have a double for something like work time management.
// 06:30 -> 6.5
// 07:45 -> 7.75
String[] hhmm = dataEntry[0].split(":");
int hh = Integer.parseInt(hhmm[0]);
int mm = Integer.parseInt(hhmm[1]);
double decimalTime = hh + mm / 60.0; // Floating point division because of 60.0
Alternatively one could use the new java time API.
I am assuming that you got a string in 00:00 format so you can first replace ':' with '.' then you will get a string in 00.00 format, after that parse that string to double as follows.
Double.parseDouble(str.replace(':','.'))
here 'str' is the String which you got in 00:00 format.
My string is "1234567" and I want to get two big decimal object like these
12345,67 and 12.345,67 but I couldn't do this. Code is shown as below:
DecimalFormat decimalFormat = new DecimalFormat("#,##0.###");
decimalFormat.setParseBigDecimal(true);
String n = decimalFormat.format(1234567);
BigDecimal bigDecimal = (BigDecimal)decimalFormat.parse(n);
DecimalFormat decimalFormat1 = new DecimalFormat("#,0#");
decimalFormat1.setParseBigDecimal(true);
String n1 = decimalFormat.format(1234567);
BigDecimal bigDecimal1 = (BigDecimal)decimalFormat.parse(n1);
System.out.println(n);
System.out.println(bigDecimal);
System.out.println(n1);
System.out.println(bigDecimal1);
Output:
1.234.567,00
1234567.00
1.234.567,00
1234567.00
Expected output:
12.345,67
12.345,67
12345,67
12345,67
Thank you for your help
Number formatting is always locale specific. Therefore a defined locale is needed.
Following approach will work for the formatting:
BigDecimal money = new BigDecimal("1234567");
DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.GERMAN);
symbols.setDecimalSeparator(',');
symbols.setGroupingSeparator('.');
// https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html
DecimalFormat format = new DecimalFormat("###,###.00");
format.setDecimalFormatSymbols(symbols);
System.out.println(format.format(money));
However, this does not meet the requirement to parse any given number as a decimal with 2 digits. Here, I would personally would apply a division by 100 or, insert a decimal separator into the given String.
BigDecimal money = new BigDecimal("1234567").divide(new BigDecimal("100"));
Inserting a defined decimal separator could work like this:
private static String prepare(String input) {
if (input.length() == 2) {
return ","+input;
}
if (input.length() == 1) {
return ",0"+input;
}
String integerPart = input.substring(0, input.length()-2);
String fraction = input.substring(input.length()-2);
return integerPart+","+fraction;
}
Using the new DecimalFormat and the prepare() method it would work to parse a String as a number with 2 decimals by default.
String input = "1234567";
String prepared = prepare(input);
DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.GERMAN);
symbols.setDecimalSeparator(',');
symbols.setGroupingSeparator('.');
DecimalFormat format = new DecimalFormat("###,###.00");
format.setDecimalFormatSymbols(symbols);
format.setParseBigDecimal(true);
BigDecimal bigDecimal = (BigDecimal)format.parse(prepared);
String n = format.format(bigDecimal);
System.out.println(n);
I'm trying to parse a String to a float with the float.parsefloat() method but it gives me an error concerning the format.
int v_CurrentPosX = Math.round(Float.parseFloat(v_posString)); //where v_posString is the float that I want to convert in this case 5,828
And the error:
Exception in thread "main" java.lang.NumberFormatException: For input
string: "5,828" at
sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseFloat(FloatingDecimal.java:122)
Your problem is that colon (,) is not a default locale in the JVM...
you can use a NumberFormat for that, with the right locale
String x = "5,828";
NumberFormat myNumForm = NumberFormat.getInstance(Locale.FRENCH);
double myParsedFrenchNumber = (double) myNumForm.parse(x);
System.out.println("D: " + myParsedFrenchNumber);
Try replacing the comma with a dot before parsing like so:
v_posString = v_posString.replace(",",".");
int v_CurrentPosX = Math.round(Float.parseFloat(v_posString));
The problem is that your locale is set to use . for floats and not ,.
Try this
NumberFormat.getNumberInstance(Locale.FRANCE).parse("5,828");
Float.parseFloat() doesn't consider locale and always expects '.' to be your decimal point separator. You can use DecimalFormat instead.
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator(',');
String str = "5,200";
DecimalFormat format = new DecimalFormat("0.#");
format.setDecimalFormatSymbols(symbols);
float f = format.parse(str).floatValue();
I always like input in my function to get numbers that range from 0.1 to 999.9 (the decimal part is always separated by '.', if there is no decimal then there is no '.' for example 9 or 7 .
How do I convert this String to float value regardless of localization (some countries use ',' to separate decimal part of number. I always get it with the '.')? Does this depend on local computer settings?
The Float.parseFloat() method is not locale-dependent. It expects a dot as decimal separator. If the decimal separator in your input is always dot, you can use this safely.
The NumberFormat class provides locale-aware parse and format should you need to adapt for different locales.
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator('.');
DecimalFormat format = new DecimalFormat("0.#");
format.setDecimalFormatSymbols(symbols);
float f = format.parse(str).floatValue();
valueStr = valueStr.replace(',', '.');
return new Float(valueStr);
Done
See java.text.NumberFormat and DecimalFormat:
NumberFormat nf = new DecimalFormat ("990.0");
double d = nf.parse (text);
What about this:
Float floatFromStringOrZero(String s){
Float val = Float.valueOf(0);
try{
val = Float.valueOf(s);
} catch(NumberFormatException ex){
DecimalFormat df = new DecimalFormat();
Number n = null;
try{
n = df.parse(s);
} catch(ParseException ex2){
}
if(n != null)
val = n.floatValue();
}
return val;
}
You can use the placeholder %s-String for any primitive type.
float x = 3.15f, y = 1.2345f;
System.out.printf("%.4s and %.5s", x, y);
Output: 3.15 and 1.234
%s is always english formatting regardless of localization.
If you want a specif local formatting, you could also do:
import java.util.Locale;
float x = 3.15f, y = 1.2345f;
System.out.printf(Locale.GERMAN, "%.2f and %.4f", x, y);
Output: 3,15 and 1,2345
I hope this piece of code may help you.
public static Float getDigit(String quote){
char decimalSeparator = new DecimalFormatSymbols().getDecimalSeparator();
String regex = "[^0-9" + decimalSeparator + "]";
String valueOnlyDigit = quote.replaceAll(regex, "");
if (String.valueOf(decimalSeparator).equals(",")) {
valueOnlyDigit = valueOnlyDigit.replace(",", ".");
//Log.i("debinf purcadap", "substituted comma by dot");
}
try {
return Float.parseFloat(valueOnlyDigit);
} catch (ArithmeticException | NumberFormatException e) {
//Log.i("debinf purcadap", "Error in getMoneyAsDecimal", e);
return null;
}
}
I want to be able to convert a string to a Double given a number of decimal places in a format string. So "###,##0.000" should give me a Double to 3 decimal places.
Edit - added more info to what happens
The user enters the value in the UI - which is input into a String. The rule is this value is limited to 3 decimal places. The underlying code stores the value in the database which is then used in a calculation. Therefore the trailing decimal places will cause the calculations to be out slightly to what would be expected.
I have the following code:
try {
// output current locale we are running under (this happens to be "nl_BE")
System.out.println( "Current Locale is " + Locale.getDefault().toString() );
// number in Central European Format with a format string specified in UK format
String numberCE = "1,234567"; // 1.234567
String formatUK = "###,##0.000";
// do the format
DecimalFormat formatterUK = new DecimalFormat( formatUK );
Double valCEWithUKFormat = formatterUK.parse( numberCE ).doubleValue();
// I want the number to DPs in the format string!!!
System.out.println( "CE Value " + numberCE + " in UK format (" + formatUK + ") is "
+ valCEWithUKFormat );
} catch( ParseException ex ) {
System.out.println("Cannot parse number");
}
}
The DecimalFormat seems to ignore the format string and gives me the complete string as a Double of 1.234567.
Can DecimalFormat be forced to use the format string when parsing? Am I missing something?
Cheers,
Andez
DecimalFormat is used for two distinct purposes: parsing input and formatting output. If you want to do both, you'll have to use the format object twice.
If you want to take that value and format the output, restricting the number of significant digits, you need to use the format object again. This time it uses your formatting rules to create an output string from a numeric value:
String output = formatterUK.format(valCEWithUKFormat.doubleValue() );
This will give you the output of 1,235
It seems you want this numeric value to be presented in the 1.235 format. To do this, you should format the output using a specific locale (if yours uses a different format).
HOWEVER, I would recommend approaching this problem differently:
String text = "1,234567";
NumberFormat nf_in = NumberFormat.getNumberInstance(Locale.GERMANY);
double val = nf_in.parse(text).doubleValue();
NumberFormat nf_out = NumberFormat.getNumberInstance(Locale.UK);
nf_out.setMaximumFractionDigits(3);
String output = nf_out.format(val);
A few notes:
Input parsing should be kept separate from output formatting. Especially when you start throwing in multiple Locales.
Allow the standard library to do the heavy lifting for determining what a valid input value is for a given Locale. You just need to select an appropriate Locale (I chose GERMANY, but this would obviously work with others). Always use Locales when possible. Don't try to recreate formatting strings.
Always store your input value SEPARATE from any output formatting. IE, if you want to show only three digits in the output, that's fine, but store the whole double value anyway.
Taking on board what you said I have modified my code slightly to cover different locales. The key was taking a value string in a localised format to a Double that is rounded based on the format string.
The format string is always a UK based format with the decimal seperators specified as "." and thousand seperators specified as ",".
I am using the DecimalFormat to initially parse the localised format based on a specified locale. This gives a Double equivalent of the string correctly. I then use a BigDecimal to handle the rounding. I can get the number of decimal places from the DecimalFormat instance and call setScale on the BigDecimal to perform the rounding.
The initial code structure has been modified to allow you to see what happens under different locale circumstances thanks #RD01 for noting importance of other locales.
I now have code as follows:
private void runTests3() {
// output current locale we are running under
System.out.println( "Current Locale is " + Locale.getDefault().toString() );
// number in Central European Format with a format string specified in UK format
String numbersInEuropeanFormatString[] = new String[] { "1.000,234567", "1,2345678", "1.222.333,234567" };
String formatUK = "###,##0.0000";
// output numbers using the german locale
System.out.println("Output numbers using the German locale\n");
for(String num : numbersInEuropeanFormatString ) {
formatNumberAsDouble(num, formatUK, Locale.GERMAN);
}
// output numbers using the UK locale.
// this should return unexpected results as the number is in European format
System.out.println("Output numbers using the UK locale\n");
for(String num : numbersInEuropeanFormatString ) {
formatNumberAsDouble(num, formatUK, Locale.UK);
}
// output numbers using new DecimalFormat( formatUK ) - no locale specified
System.out.println("\n\nOutput numbers using new DecimalFormat( " + formatUK + " )\n");
for(String num : numbersInEuropeanFormatString ) {
formatNumberAsDouble( num, formatUK, null);
}
}
private void formatNumberAsDouble(String value, String format, Locale locale) {
NumberFormat formatter;
int decimalPlaces;
// create the formatter based on the specified locale
if( locale != null ) {
formatter = NumberFormat.getNumberInstance(locale);
// creating the above number format does not take in the format string
// so create a new one that we won't use at all just to get the
// decimal places in it
decimalPlaces = (new DecimalFormat(format)).getMaximumFractionDigits();
} else {
formatter = new DecimalFormat( format );
decimalPlaces = formatter.getMaximumFractionDigits();
}
// get the result as number
Double result = null;
try {
result = formatter.parse( value ).doubleValue();
} catch( ParseException ex ) {
// not bothered at minute
}
// round the Double to the precision specified in the format string
BigDecimal bd = new BigDecimal(result );
Double roundedValue = bd.setScale( decimalPlaces, RoundingMode.HALF_UP ).doubleValue();
// output summary
System.out.println("\tValue = " + value);
System.out.println( locale == null ? "\tLocale not specified" : "\tLocale = " + locale.toString());
System.out.println( format == null || format.length() == 0 ? "\tFormat = Not specified" : "\tFormat = " + format);
System.out.println("\tResult (Double) = " + result);
System.out.println("\tRounded Result (Double) (" + decimalPlaces + "dp) = " + roundedValue);
System.out.println("");
}
This produces the following output:
Current Locale is nl_BE
Output numbers using the German locale
Value = 1.000,234567
Locale = de
Format = ###,##0.0000
Result (Double) = 1000.234567
Rounded Result (Double) (4dp) = 1000.2346
Value = 1,2345678
Locale = de
Format = ###,##0.0000
Result (Double) = 1.2345678
Rounded Result (Double) (4dp) = 1.2346
Value = 1.222.333,234567
Locale = de
Format = ###,##0.0000
Result (Double) = 1222333.234567
Rounded Result (Double) (4dp) = 1222333.2346
Output numbers using the UK locale
Value = 1.000,234567
Locale = en_GB
Format = ###,##0.0000
Result (Double) = 1.0
Rounded Result (Double) (4dp) = 1.0
Value = 1,2345678
Locale = en_GB
Format = ###,##0.0000
Result (Double) = 1.2345678E7
Rounded Result (Double) (4dp) = 1.2345678E7
Value = 1.222.333,234567
Locale = en_GB
Format = ###,##0.0000
Result (Double) = 1.222
Rounded Result (Double) (4dp) = 1.222
Output numbers using new DecimalFormat( ###,##0.0000 )
Value = 1.000,234567
Locale not specified
Format = ###,##0.0000
Result (Double) = 1000.234567
Rounded Result (Double) (4dp) = 1000.2346
Value = 1,2345678
Locale not specified
Format = ###,##0.0000
Result (Double) = 1.2345678
Rounded Result (Double) (4dp) = 1.2346
Value = 1.222.333,234567
Locale not specified
Format = ###,##0.0000
Result (Double) = 1222333.234567
Rounded Result (Double) (4dp) = 1222333.2346
The restriction of decimal places in DecimalFormat is really meant for use in the format() method and doesn't have much effect in the parse() method.
In order to get what you want you need this:
try {
// output current locale we are running under (this happens to be "nl_BE")
System.out.println("Current Locale is " + Locale.getDefault().toString());
// number in Central European Format with a format string specified in UK format
String numberCE = "1,234567"; // 1.234567
String formatUK = "###,##0.000";
// do the format
DecimalFormat formatterUK = new DecimalFormat(formatUK);
Double valCEWithUKFormat = formatterUK.parse(numberCE).doubleValue();
// first convert to UK format string
String numberUK = formatterUK.format(valCEWithUKFormat);
// now parse that string to a double
valCEWithUKFormat = formatterUK.parse(numberUK).doubleValue();
// I want the number to DPs in the format string!!!
System.out.println("CE Value " + numberCE + " in UK format (" + formatUK + ") is " + valCEWithUKFormat);
} catch (ParseException ex) {
System.out.println("Cannot parse number");
}
You first need to get the number as a UK format string and then parse that number, using the UK formatter. That will get you the result you're looking for. NB, this will round the number to 3 decimal places, not truncate.
By the way, I'm slightly surprised that your UK formatter is able to parse the CE format number. You really should be parsing the original number with a CE format parser.
Sure you can. Try running this:
String in = "1,234567";
System.out.println(NumberFormat.getNumberFormat(new Locale("fr", "FR")).parse(in));
System.out.println(NumberFormat.getNumberFormat(new Locale("en", "GB")).parse(in));
Clearly they result in different output, the first reading 1.234567 and the second 1234567. Maybe there's something wrong with your pattern? Anyway the last line there would be the preferred way of getting the UK standard format.