Removing trailing zeros from BigDecimal in Java - java

I need to remove trailing zeros from BigDecimal along with RoundingMode.HALF_UP. For instance,
Value Output
15.3456 <=> 15.35
15.999 <=> 16 //No trailing zeros.
15.99 <=> 15.99
15.0051 <=> 15.01
15.0001 <=> 15 //No trailing zeros.
15.000000<=> 15 //No trailing zeros.
15.00 <=> 15 //No trailing zeros.
stripTrailingZeros() works but it returns scientific notations in situations like,
new BigDecimal("600.0").setScale(2, RoundingMode.HALF_UP).stripTrailingZeros();
In this case, it returns 6E+2. I need this in a custom converter in JSF where it might be ugly for end users. So, what is the proper way of doing this?

Use toPlainString()
BigDecimal d = new BigDecimal("600.0").setScale(2, RoundingMode.HALF_UP).stripTrailingZeros();
System.out.println(d.toPlainString()); // Printed 600 for me
I'm not into JSF (yet), but converter might look like this:
#FacesConverter("bigDecimalPlainDisplay")
public class BigDecimalDisplayConverter implements Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
throw new BigDecimal(value);
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
BigDecimal bd = (BigDecimal)value;
return bd.setScale(2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
}
}
and then in xhtml:
<h:inputText id="bigDecimalView" value="#{bigDecimalObject}"
size="20" required="true" label="Value">
<f:converter converterId="bigDecimalPlainDisplay" />
</h:inputText>

Note that stripTrailingZeros() doesn't do very well either.
On this:
val = new BigDecimal("0.0000").stripTrailingZeros();
System.out.println(val + ": plain=" + val.toPlainString());
val = new BigDecimal("40.0000").stripTrailingZeros();
System.out.println(val + ": plain=" + val.toPlainString());
val = new BigDecimal("40.50000").stripTrailingZeros();
System.out.println(val + ": plain=" + val.toPlainString());
Output (Java 7):
0.0000: plain=0.0000
4E+1: plain=40
40.5: plain=40.5
Output (Java 8):
0: plain=0
4E+1: plain=40
40.5: plain=40.5
The 0.0000 issue in Java 7 is fixed in Java 8 by the following java fix.

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

You can also accomplish this with String.format(), like so:
final BigDecimal b = new BigDecimal("600.0").setScale(2, RoundingMode.HALF_UP);
String f = String.format("%.0f", b);
System.out.println(f); //600

You should make some calculation on the BigDecimal, and then round it half up e.g.
BigDecimal toPay = new BigDecimal(1453.00005);
toPay = toPay.multiply(new BigDecimal(1)).setScale(2, RoundingMode.HALF_UP)
It worked for me.

You can use DecimalFormat.
For example:
BigDecimal value = new BigDecimal("15.3456").setScale(2, BigDecimal.ROUND_HALF_UP));
String valueString = new DecimalFormat("#.##").format(value);
System.out.println(valueString); //15.35
Please try yourself.

Related

converting float to integer in a special way

I am trying to convert float number in Java to integer on the following way:
4.55 = 455
12.45 = 1245
11.1234 = 111234
How can I do it?
One option would be like this:
float number = 4.55f;
int desiredNumber = Integer.parseInt(String.valueOf(number).replaceAll("\\.", ""));
But something like this will only work if the conversion pattern will stay the same. By this I mean the way you want to convert from float to int. Hope this helps.
here is an example
double f1 = 4.5;
String str = new Double(f1).toString();
str = str.replace(".", "");
Integer i = Integer.parseInt(str);
System.out.println(i);
If you want to be able to hanlde arbitrarily large numbers and arbitrarily many decimals, then you can use BigDecimal and BigInteger
BigDecimal number = new BigDecimal(
"5464894984546489498454648949845464894984546489498454648949845464894984546489498454648949845464894984.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
String valueOf = number.toPlainString();
BigInteger desired = new BigInteger((valueOf.replaceAll("\\.", "")));
System.out.println(desired);
Constructor can take double or float if needed
BigDecimal number = new BigDecimal(Double.MAX_VALUE);
BigDecimal number = new BigDecimal(Float.MAX_VALUE);
Something like that :
public int convert( float numbre) {
String nmbre = String.valueOf(numbre).replace(".", "");
return Integer.parseInt(nmbre );
}
You can convert the number to a String, remove the dot, and create a new Long:
private long removeTheDot(Number number) {
return Long.valueOf(number.toString().replace(".", ""));
}
Ka-Bam!

How to retain trailing zeroes when converting BigDecimal to String

I have to convert a BigDecimal value, e.g. 2.1200, coming from the database to a string. When I use the toString() or toPlainString() of BigDecimal, it just prints the value 2.12 but not the trailing zeroes.
How do I convert the BigDecimal to string without losing the trailing zeroes?
try this..
MathContext mc = new MathContext(6); // 6 precision
BigDecimal bigDecimal = new BigDecimal(2.12000, mc);
System.out.println(bigDecimal.toPlainString());//2.12000
To convert a BigDecimal to a String with a particular pattern you need to use a DecimalFormat.
BigDecimal value = .... ;
String pattern = "#0.0000"; // If you like 4 zeros
DecimalFormat myFormatter = new DecimalFormat(pattern);
String output = myFormatter.format(value);
System.out.println(value + " " + pattern + " " + output);
To check the possible values of pattern see here DecimalFormat
double value = 1.25;
// To convet double to bigdecimal
BigDecimal bigDecimalValue = BigDecimal.valueOf(value);
//set 4 trailing value
BigDecimal tempValue = bigDecimalValue.setScale(4, RoundingMode.CEILING);
System.out.println(tempValue.toPlainString());
You can use below code .
BigDecimal d = new BigDecimal("1.200");
System.out.println(d);
System.out.println(String.valueOf(d));
Output is as below :
1.200
1.200
In a practical way, just don't use BigDecimal, instead use toString() of Double class.

Remove Decimals from String

I have a function that converst a BigDecimal into a String plus the currency. When I use this the number (e.g. 34) turns into a number with a lot of decimals (e.g. 34.000000).
What can I do to solve this and just show the 34?
Here is my function:
row.put("Money", GcomNullPointerValidator.isNullField(formatUtils.formatCurrency(MoneyDto.getAmount().stripTrailingZeros())));
What is the language? Java?
You can use the split() function of String if you just want to keep numbers before "." :
String mystring = "34.000000";
String correctstring[] = mystring.split(".");
System.out.println(correctstring[0]);
// display : 34
it will delete all digits after "." !
Inside your method that converts a BigDecimal into a String, you can use BigDecimal.setScale() to set the number of digits after the decimal point. For example:
BigDecimal d = new BigDecimal("34.000000");
BigDecimal d1 = d.setScale(2, BigDecimal.ROUND_HALF_UP); // yields 34.00
BigDecimal d2 = d.setScale(0, BigDecimal.ROUND_HALF_UP); // yields 34
You can use this:
String number = "150.000";
number.replaceAll("\\.\\d+$", "");
Or you can use this:
number.split(Pattern.quote("."))[0];

Truncate the fractional part of a BigDecimal when its scale is zero in Java

I need to remove the fractional part of a BigDecimal value when its scale has a value of zero. For example,
BigDecimal value = new BigDecimal("12.00").setScale(2, RoundingMode.HALF_UP);
It would assign 12.00. I want it to assign only 12 to value in such cases.
BigDecimal value = new BigDecimal("12.000000").setScale(2, RoundingMode.HALF_UP);
should assign 12,
BigDecimal value = new BigDecimal("12.0001").setScale(2, RoundingMode.HALF_UP);
should assign 12.
BigDecimal value = new BigDecimal("12.0051").setScale(2, RoundingMode.HALF_UP);
should assign12.01
BigDecimal value = new BigDecimal("00.000").setScale(2, RoundingMode.HALF_UP);
should assign 0.
BigDecimal value = new BigDecimal("12.3456").setScale(2, RoundingMode.HALF_UP);
should assign 12.35 and alike. Is this possible? What is the best way to do?
For the crosslink from there: https://codereview.stackexchange.com/questions/24299/is-this-the-way-of-truncating-the-fractional-part-of-a-bigdecimal-when-its-scale
Is this possible? What is the best way to do?
Probably stripTrailingZeros().
To check your tests:
public static void main(final String[] args) {
check(truncate("12.000000"), "12");
check(truncate("12.0001"), "12");
check(truncate("12.0051"), "12.01");
check(truncate("12.99"), "12.99");
check(truncate("12.999"), "13");
check(truncate("12.3456"), "12.35");
System.out.println("if we see this message without exceptions, everything is ok");
}
private static BigDecimal truncate(final String text) {
BigDecimal bigDecimal = new BigDecimal(text);
if (bigDecimal.scale() > 2)
bigDecimal = new BigDecimal(text).setScale(2, RoundingMode.HALF_UP);
return bigDecimal.stripTrailingZeros();
}
private static void check(final BigDecimal bigDecimal, final String string) {
if (!bigDecimal.toString().equals(string))
throw new IllegalStateException("not equal: " + bigDecimal + " and " + string);
}
output:
if we see this message without exceptions, everything is ok
The following code does what you specify with the help of regex and the construction of BigDecimal, it is probably not the most efficient way to go about:
BigDecimal value = new BigDecimal("12.0000").setScale(2, RoundingMode.HALF_UP);
Pattern pattern = Pattern.compile("\\d+\\.(\\d)0");
Matcher matcher = pattern.matcher(value.toString());
if (matcher.find()) {
if (matcher.group(1).equals("0"))
value = value.setScale(0);
else
value = value.setScale(1);
}
Note: this also makes 12.100 -> 12.1, I assume that is wanted functionality.
Instead of modifying the original value on my own by hand, I have simply tried to apply some conditions like,
String text="123.008";
BigDecimal bigDecimal=new BigDecimal(text);
if(bigDecimal.scale()>2)
{
bigDecimal=new BigDecimal(text).setScale(2, RoundingMode.HALF_UP);
}
if(bigDecimal.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO)==0)
{
bigDecimal=new BigDecimal(text).setScale(0, BigDecimal.ROUND_HALF_UP);
}
System.out.println("bigDecimal = "+bigDecimal);
The first if condition checks, if the scale is greater than 2. If so, then perform the rounding operation as specified.
The next if condition checks, if the value of the fractional part yields zero. If so, then truncate it. Two BigDecimal objects that are equal in value but have a different scale (like 2.0 and 2.00) are considered equal by the compareTo() method. Therefore, the condition is satisfied whenever the the value of the fractional part is evaluated to zero.
Otherwise, the original value is left untouched (if the scale is either 1 or 2).
If I'm missing something or it's a wrong thing to implement, then please clarify it.
Try this one:
new BigDecimal("12.3456").setScale(2, RoundingMode.FLOOR).stripTrailingZeros()

BigDecimal to string

I have a BigDecimal object and i want to convert it to string.
The problem is that my value got fraction and i get a huge number (in length) and i only need the original number in string for example:
for
BigDecimal bd = new BigDecimal(10.0001)
System.out.println(bd.toString());
System.out.println(bd.toPlainString());
the output is:
10.000099999999999766941982670687139034271240234375
10.000099999999999766941982670687139034271240234375
and i need the out put to be exactly the number 10.0001 in string
To get exactly 10.0001 you need to use the String constructor or valueOf (which constructs a BigDecimal based on the canonical representation of the double):
BigDecimal bd = new BigDecimal("10.0001");
System.out.println(bd.toString()); // prints 10.0001
//or alternatively
BigDecimal bd = BigDecimal.valueOf(10.0001);
System.out.println(bd.toString()); // prints 10.0001
The problem with new BigDecimal(10.0001) is that the argument is a double and it happens that doubles can't represent 10.0001 exactly. So 10.0001 is "transformed" to the closest possible double, which is 10.000099999999999766941982670687139034271240234375 and that's what your BigDecimal shows.
For that reason, it rarely makes sense to use the double constructor.
You can read more about it here, Moving decimal places over in a double
Your BigDecimal doesn't contain the number 10.0001, because you initialized it with a double, and the double didn't quite contain the number you thought it did. (This is the whole point of BigDecimal.)
If you use the string-based constructor instead:
BigDecimal bd = new BigDecimal("10.0001");
...then it will actually contain the number you expect.
For better support different locales use this way:
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(2);
df.setMinimumFractionDigits(0);
df.setGroupingUsed(false);
df.format(bigDecimal);
also you can customize it:
DecimalFormat df = new DecimalFormat("###,###,###");
df.format(bigDecimal);
By using below method you can convert java.math.BigDecimal to String.
BigDecimal bigDecimal = new BigDecimal("10.0001");
String bigDecimalString = String.valueOf(bigDecimal.doubleValue());
System.out.println("bigDecimal value in String: "+bigDecimalString);
Output:
bigDecimal value in String: 10.0001
// Convert BigDecimal number To String by using below method //
public static String RemoveTrailingZeros(BigDecimal tempDecimal)
{
tempDecimal = tempDecimal.stripTrailingZeros();
String tempString = tempDecimal.toPlainString();
return tempString;
}
// Recall RemoveTrailingZeros
BigDecimal output = new BigDecimal(0);
String str = RemoveTrailingZeros(output);
If you just need to set precision quantity and round the value, the right way to do this is use it's own object for this.
BigDecimal value = new BigDecimal("10.0001");
value = value.setScale(4, RoundingMode.HALF_UP);
System.out.println(value); //the return should be "10.0001"
One of the pillars of Oriented Object Programming (OOP) is "encapsulation", this pillar also says that an object should deal with it's own operations, like in this way:
The BigDecimal can not be a double.
you can use Int number.
if you want to display exactly own number, you can use the String constructor of BigDecimal .
like this:
BigDecimal bd1 = new BigDecimal("10.0001");
now, you can display bd1 as 10.0001
So simple.
GOOD LUCK.
To archive the necessary result with double constructor you need to round the BigDecimal before convert it to String e.g.
new java.math.BigDecimal(10.0001).round(new java.math.MathContext(6, java.math.RoundingMode.HALF_UP)).toString()
will print the "10.0001"

Categories