Print a Double as a String with unknown decimal length - java

I need to print a Double as a String but I don't know how many decimal places there will be and I have to be prepared for as many as possible. Right, now I'm using this ugly solution:
Double dubs = 0.000157;
NumberFormat formatter = new DecimalFormat(
"##.########################################################################################");
System.out.println(formatter.format(dubs));

You can do this with no conversion:
public class codesnippets {
public static void main(String[] args)
{
Double dubs = 0.000157;
System.out.printf("%f", dubs);
}
}
You can also use
Double dubs = 0.000157;
String dubs_format = String.format("%f", dubs);
System.out.println(dubs);
EDIT: Apparently there is a precision loss when using "%f" as a format string. If this is the case for you, use "%.10f"

Try here man. I think this is what you're saying. The answer given at the bottom.
Number of decimal digits in a double
Here is what I meant.
double d= 234.12413;
String text = Double.toString(Math.abs(d));
int integerPlaces = text.indexOf('.');
int decimalPlaces = text.length() - integerPlaces - 1;
Then you just concatenate them
String xmlString = integerPlaces.toString() + "." + decimalPlaces.toString();

This seemed to work based on Steampunkery's idea. The catch was that I needed an actual String which I realize I wasn't clear on.
String dubString= String.format("%f", dubs);
System.out.println(dubString);

Related

How to remove decimal places if zeros are present [duplicate]

This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 1 year ago.
I want to remove zeroes from my string as decimal places, but I am not able to do that. Also, I want the decimal places gone only if zeros are there else the decimal places will be there.
Example:
1234.00 should become 1234
1234.25 should remain 1234.25
Here is the code I am using to do that but its not working.
String price_normal2 ="1234.00";
if(price_normal2.contains(".00")){
price_normal2.replace(".00","");
Log.i("PRICEEEEE",""+price_normal2);
}
Please help me in this.
String class are immutable, So replace method will not replace the value in same object instead it will return the new string which can you store it into another object or the same object by assigning it.
String price_normal2 ="1234.00";
if(price_normal2.contains(".00")){
price_normal2 = price_normal2.replace(".00","");
Log.i("PRICEEEEE",""+price_normal2);
}
Parse the price to double to ensure the validity and then convert it to integer
public static void main(String[] args) {
String price_normal2 = "1234.00";
double priceWithFraction = Double.parseDouble(price_normal2);
int price = (int) priceWithFraction;
System.out.println("Price " + price);
}
check this one it will remove the decimal part if it all are zero or remove the any zero on the left side
NumberFormat numberFormat = DecimalFormat.getNumberInstance();
numberFormat.setMinimumFractionDigits(0);
System.out.println(numberFormat.parse("1234.001"));
is it fine with you that 1234.40 be 1234.4 or you want it to be 1234.40?
you can use DecimalFormat class
DecimalFormat decimalFormat = new DecimalFormat("00.##");
String formatted = decimalFormat.format(Double.parseDouble("1234.30"));
String[] splitted = formatted.split("\\.");
if (splitted.length > 1) {
String dec = (splitted[1].length() == 1) ? splitted[1] + "0" : splitted[1];
formatted = splitted[0] + "." + dec;
}
logs
D/mridx: main: 1234.30

String to BigDecimal value

Can someone help me getting the exact value to BigDecimal?
My code is as below,
import java.math.BigDecimal;
public class HelloWorld{
public static void main(String []args){
String x="2.7955814565E10";
BigDecimal y=new BigDecimal(x);
System.out.println(y.toPlainString());
}
}
My actual value in the DB is 27955814565.0, a String. I read this string from DB and set it in a bean class where the amt field has type string, using the value "2.7955814565E10". When I try to convert this to a BigDecimal I get 27955814565 instead of 27955814565.0.
Can someone tell me what is the issue because for rest all fields the logic for converting the string value to BigDecimal is working fine and I want the exact value as in DB?
The BigDecimal doesn't infer extra digits in this case.
If the input is
String x = "2.79558145650E10"; // note the extra 0
you get the expected result. You can also add the digit as required.
String x = "2.7955814565E10";
BigDecimal y = new BigDecimal(x);
if (y.scale() < 1)
y = y.setScale(1);
System.out.println(y.toPlainString());
prints
27955814565.0
BTW If your input is
String x = "2.7955814565000E10"; // note the extra 000
the output is
27955814565.000
As you already know, Your String is in scientific notation,
To translate these value into origional BigDecimal or Decimal we need a proper way.
public class Test {
public static void main(String[] args) {
double firstNumber = 12345678;
double secondNumber = 0.000012345678;
String firstNumberAsString = String.format ("%.0f", firstNumber);
String secondNumberAsString = String.format("%.12f",secondNumber);
System.out.println(firstNumberAsString);
System.out.println(secondNumberAsString);
}
}
output will be:
12345678
0.000012345678
You can use Format method as well on BigDecimal to achieve your goal.
DecimalFormat decimalFormat = new DecimalFormat("0.0000000000");

String to long: error : number format Exception:for Input String "3.1"?

My String result is: 3.1
I want to convert it into long :
I use some code like :
String txt_capplot="3.1";
Long.parseLong(String.valueOf(txt_capplot));
After Execute It made some error like:
java.lang.NumberFormatException: For input string: "3.1"
How to solve this?
Long is like integer it cant have decimal on them, but it will round it off.
solution:
you need to parse it to double first and then cast it to long.
sample:
String s = "3.1";
double d = Double.valueOf(s);
long l = (long) d;
Since long does not contains decimal fractions, So need to convert your String to double and then the long.
You should try this one line solution :
Double.valueOf(txt_capplot).longValue();
Long doesn't have a decimal part so you need to decide if you want to round it or truncate it. This code shows both
package se.wederbrand.stackoverflow;
public class ConvertToLong {
public static void main(String[] args) {
String s = "3.6";
double d = Double.parseDouble(s);
long truncated = (long) d;
long rounded = Math.round(d);
System.out.println(" original: " + s);
System.out.println("truncated: " + truncated);
System.out.println(" rounded: " + rounded);
}
}

Java Remove all cases of .0

I want a filter to run through a string and eliminate all of the un-needed .0's from the doubles. I have already tried replaces, but cases like 8.02 turn into 82.
I have a feeling this has been done before, but I cannot find any help.
I am looking for a method that will take in a String, example: "[double] plus [double] is equal to [double]", where the [double] is a double that will need to be checked for the redundant decimal.
Thanks in advance!
let's say you have a string called s that contains text like you described. simply do:
s = s.replaceAll("([0-9])\\.0+([^0-9]|$)", "$1$2");
and you're done.
ok, so i edited this a couple of times. now it works though!
You can do this with a java.text.DecimalFormat object.
Can you not take away the trailing zeros before you construct them into your string? This way you could use the DecimalFormatter method someone posted earlier and then deleted.
NumberFormat formatter = new DecimalFormat("0.##");
String str = formatter.format("8.0200");
System.out.println(str);
Give them credit for the code if they come back.
The other posts assume you're working with a short string containing only decimal.
Assuming you're working with large strings of text, you can use Pattern/Matcher classes (I'm at work, so posting in a hurry. Check for errors)
Use this regex to replace:
/* >1 digits followed by a decimal and >1 zeros. Note capture group on first set of digits. This will only match decimals with trailing 0s, and not 8.0002 */
(\d+)\.0+
Replace with
/* First capture group */
$1
I'm unsure of the regex rules for Java, so use this as a concept to get what you want.
The following program will remove all trailing zeros from the fractional part of a double value. If your requirements are somewhat different, you may need to modify it slightly.
final public class Main
{
public static void main(String...args)
{
System.out.println("Enter how many numbers you want to check:->");
Scanner scan = new Scanner(System.in);
final double KEY_VALUE = 0.0;
final Double TOLERANCE = 0.000000000001d;
int n = scan.nextInt();
double[] a = new double[n];
for (int i = 0; i < n; i++)
{
a[i] = scan.nextDouble();
}
List<Double> newList = new ArrayList<Double>();
for (int k = 0; k < n; k++)
{
if (Math.abs(a[k] - KEY_VALUE) < TOLERANCE)
{
continue;
}
newList.add(a[k]);
}
System.out.println(newList);
}
}
You can specifically use DecimalFormat to truncate the specified number of decimal places, if you need such as follows.
double x=10.4555600500000;
DecimalFormat df=new DecimalFormat("#.##");
System.out.println(df.format(x));
Would return 10.46.

How to parse a currency Amount (US or EU) to float value in Java

In Europe decimals are separated with ',' and we use optional '.' to separate thousands. I allow currency values with:
US-style 123,456.78 notation
European-style 123.456,78 notation
I use the next regular expression (from RegexBuddy library) to validate the input. I allow optional two-digits fractions and optional thousands separators.
^[+-]?[0-9]{1,3}(?:[0-9]*(?:[.,][0-9]{0,2})?|(?:,[0-9]{3})*(?:\.[0-9]{0,2})?|(?:\.[0-9]{3})*(?:,[0-9]{0,2})?)$
I would like to parse a currency string to a float. For example
123,456.78 should be stored as 123456.78
123.456,78 should be stored as 123456.78
123.45 should be stored as 123.45
1.234 should be stored as 1234
12.34 should be stored as 12.34
and so on...
Is there an easy way to do this in Java?
public float currencyToFloat(String currency) {
// transform and return as float
}
Use BigDecimal instead of Float
Thanks to everyone for the great answers. I have changed my code to use BigDecimal instead of float. I will keep previous part of this question with float to prevent people from doing the same mistakes I was gonna do.
Solution
The next code shows a function which transforms from US and EU currency to a string accepted by BigDecimal(String) constructor. That it is to say a string with no thousand separator and a point for fractions.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestUSAndEUCurrency {
public static void main(String[] args) throws Exception {
test("123,456.78","123456.78");
test("123.456,78","123456.78");
test("123.45","123.45");
test("1.234","1234");
test("12","12");
test("12.1","12.1");
test("1.13","1.13");
test("1.1","1.1");
test("1,2","1.2");
test("1","1");
}
public static void test(String value, String expected_output) throws Exception {
String output = currencyToBigDecimalFormat(value);
if(!output.equals(expected_output)) {
System.out.println("ERROR expected: " + expected_output + " output " + output);
}
}
public static String currencyToBigDecimalFormat(String currency) throws Exception {
if(!doesMatch(currency,"^[+-]?[0-9]{1,3}(?:[0-9]*(?:[.,][0-9]{0,2})?|(?:,[0-9]{3})*(?:\\.[0-9]{0,2})?|(?:\\.[0-9]{3})*(?:,[0-9]{0,2})?)$"))
throw new Exception("Currency in wrong format " + currency);
// Replace all dots with commas
currency = currency.replaceAll("\\.", ",");
// If fractions exist, the separator must be a .
if(currency.length()>=3) {
char[] chars = currency.toCharArray();
if(chars[chars.length-2] == ',') {
chars[chars.length-2] = '.';
} else if(chars[chars.length-3] == ',') {
chars[chars.length-3] = '.';
}
currency = new String(chars);
}
// Remove all commas
return currency.replaceAll(",", "");
}
public static boolean doesMatch(String s, String pattern) {
try {
Pattern patt = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
Matcher matcher = patt.matcher(s);
return matcher.matches();
} catch (RuntimeException e) {
return false;
}
}
}
To answer a slightly different question: don't use the float type to represent currency values. It will bite you. Use a base-10 type instead, like BigDecimal, or an integer type like int or long (representing the quantum of your value - penny, for example, in US currency).
You will not be able to store an exact value - 123.45, say, as a float, and mathematical operations on that value (such as multiplication by a tax percentage) will produce rounding errors.
Example from that page:
float a = 8250325.12f;
float b = 4321456.31f;
float c = a + b;
System.out.println(NumberFormat.getCurrencyInstance().format(c));
// prints $12,571,782.00 (wrong)
BigDecimal a1 = new BigDecimal("8250325.12");
BigDecimal b1 = new BigDecimal("4321456.31");
BigDecimal c1 = a1.add(b1);
System.out.println(NumberFormat.getCurrencyInstance().format(c1));
// prints $12,571,781.43 (right)
You don't want to muck with errors when it comes to money.
With respect to the original question, I haven't touched Java in a little while, but I know that I'd like to stay away from regex to do this kind of work. I see this recommended; it may help you. Not tested; caveat developer.
try {
String string = NumberFormat.getCurrencyInstance(Locale.GERMANY)
.format(123.45);
Number number = NumberFormat.getCurrencyInstance(locale)
.parse("$123.45");
// 123.45
if (number instanceof Long) {
// Long value
} else {
// too large for long - may want to handle as error
}
} catch (ParseException e) {
// handle
}
Look for a locale with rules that match what you expect to see. If you can't find one, use multiple sequentially, or create your own custom NumberFormat.
I'd also consider forcing users to enter values in a single, canonical format. 123.45 and 123.456 look way too similar for my tastes, and by your rules would result in values that differ by a factor of 1000. This is how millions are lost.
As a generalized solution you can try
char[] chars = currency.toCharArray();
chars[currency.lastIndexOf(',')] = '.';
currency = new String(chars);
instead of
if(currency.length()>=3) {
char[] chars = currency.toCharArray();
if(chars[chars.length-2] == ',') {
chars[chars.length-2] = '.';
} else if(chars[chars.length-3] == ',') {
chars[chars.length-3] = '.';
}
currency = new String(chars);
}
so that fractional part can be of any length.
Try this.............
Locale slLocale = new Locale("de","DE");
NumberFormat nf5 = NumberFormat.getInstance(slLocale);
if(nf5 instanceof DecimalFormat) {
DecimalFormat df5 = (DecimalFormat)nf5;
try {
DecimalFormatSymbols decimalFormatSymbols = DecimalFormatSymbols.getInstance(slLocale);
decimalFormatSymbols.setGroupingSeparator('.');
decimalFormatSymbols.setDecimalSeparator(',');
df5.setDecimalFormatSymbols(decimalFormatSymbols);
df5.setParseBigDecimal(true);
ParsePosition pPosition = new ParsePosition(0);
BigDecimal n = (BigDecimal)df5.parseObject("3.321.234,56", pPosition);
System.out.println(n);
}catch(Exception exp) {
exp.printStackTrace();
}
}
A quick a dirty hack could be:
String input = input.replaceAll("\.,",""); // remove *any* , or .
long amount = Long.parseLong(input);
BigDecimal bd = BigDecimal.valueOf(amount).movePointLeft(2);
//then you could use:
bd.floatValue();
//but I would seriously recommended that you don't use floats for monetary amounts.
Note this will only work if the input is in the form ###.00, ie with exactly 2 decimal places. For example input == "10,022" will break this rather naive code.
Alternative is to use the BigDecimal(String) constructor, but you'll need to convert those euro style numbers to use '.' as the decimal separator, in addition to removing the thousand separators for both.

Categories

Resources