Extract number decimal in BigDecimal - java

How to extract a number after the decimal point using BigDecimal ?
BigDecimal d = BigDecimal.valueOf(1548.5649);
result : extract only : 5649

Try:
BigDecimal d = BigDecimal.valueOf(1548.5649);
BigDecimal result = d.subtract(d.setScale(0, RoundingMode.FLOOR)).movePointRight(d.scale());
System.out.println(result);
prints:
5649

Try BigDecimal.remainder:
BigDecimal d = BigDecimal.valueOf(1548.5649);
BigDecimal fraction = d.remainder(BigDecimal.ONE);
System.out.println(fraction);
// Outputs 0.5649

This should do the trick:
d.subtract(d.setScale(0, RoundingMode.FLOOR));
setScale() rounds the number to zero decimal places, and despite its name, does not mutate the value of d.

If the value is negative, using d.subtract(d.setScale(0, RoundingMode.FLOOR)) will return a wrong decimal.
Use this:
BigInteger decimal =
d.remainder(BigDecimal.ONE).movePointRight(d.scale()).abs().toBigInteger();
It returns 5649 for 1548.5649 or -1548.5649

You don't tell which type you want as a result. The easiest way is probably to transform the BigDecimal into a String, and take a substring:
String s = d.toPlainString();
int i = s.indexOf('.');
if (i < 0) {
return "";
}
return s.substring(i + 1);

try to use d.doubleValue() to get the double value

Related

How to round a number in Java

I need the following results:
10.17111 -> 10.17
10.17445 -> 10.18
I tried BigDecimal and DecimalFormat methods and RoundingMode class:
String value = "10.17111";
BigDecimal bd = new BigDecimal(value);
BigDecimal bdResult = bd.setScale(2, RoundingMode.UP);
String result = bdResult.toString();
System.out.println(result);
Print out = 10.18
Should be = 10.17
double ddd = 10.17111;
DecimalFormat d = new DecimalFormat("#.##");
d.setRoundingMode(RoundingMode.UP);
String outputResult = d.format(ddd).replace(',', '.');
System.out.println(outputResult);
Print out = 10.18
Should be = 10.17
And with BigDecimal:
String value2 = "10.17445";
Print out = 10.18
As I expected
And with DecimalFormat:
double ddd2 = 10.17445;
Print out = 10.17
Should be = 10.18
If you really want to round digit-by-digit and you should really think long and hard about it (and perhaps tell us why if you are so inclined as I'm curious), then you can do any of the following, which I present as a thought exercise rather than as a recommendation that this is mathematically sound which I leave to you to decide for yourself:
1) Write an algorithm which checks from the digit you are rounding to and looks to see if it is a chain of 4's followed by a digit greater (10.44449) than 5 or just a number greater than 5 (10.49). If so round up to 11, otherwise use the normal rules.
2) Use RoundingMode.HALF_UP in a loop or recursively doing one digit at a time. If you have 10.17445, then you define a decimal format #.#### and round. Then #.### and round. Then #.## and round.
The reason there isn't a standard way to do this is because it is not standard.
Just do all of the digits one by one, starting from the end, until you've done as many as you need to do.
public static BigDecimal RoundIt(BigDecimal valueToRound, int precision)
{
BigDecimal result = valueToRound;
for (int i = valueToRound.precision(); i >= precision; i--)
{
result = result.setScale(i, RoundingMode.HALF_UP);
}
return result;
}
My workaround and it works fine:
public static String roundUp(String value) {
BigDecimal bd = new BigDecimal(value.replace(',', '.'));
BigDecimal bdResult = bd.setScale(4, RoundingMode.HALF_UP);
BigDecimal bdResult2 = bdResult.setScale(3, RoundingMode.HALF_UP);
BigDecimal bdResult3 = bdResult2.setScale(2, RoundingMode.HALF_UP);
String result = bdResult3.toString();
return result;
}

How to always round off upto 2 decimal places in java

I have tried the following code but it is not working in a particular case.
Eg: Suppose, I have a double value=2.5045 and i want it to be rounded off upto two decimal places using the below code.After rounding off, i get the answer as 2.5. But I want the answer to be 2.50 instead. In this case,zero is trimmed off. Is there any way to retain the zero so as to get the desired answer as 2.50 after rounding off.
private static DecimalFormat twoDForm = new DecimalFormat("#.##");
public static double roundTwoDecimals(double amount) {
return Double.valueOf(twoDForm.format(amount));
}
try this pattern
new DecimalFormat("0.00");
but this will change only formatting, double cannot hold number of digits after decimal poin, try BigDecimal
BigDecimal bd = new BigDecimal(2.5045).setScale(2, RoundingMode.HALF_UP);
Look at the documentation for DecimalFormat. For # it says:
Digit, zero shows as absent
0 is probably what you want:
Digit
So what you are looking for is either "0.00" or "#.00" as a format string, depending on whether you want the first digit before the period, to be visible in case the numbers absolute value is smalle than 0.
Try this
DecimalFormat format = new DecimalFormat("#");
format.setMinimumFractionDigits(2);
answer.setText(format.format(data2));
Try This
double d = 4.85999999999;
long l = (int)Math.round(d * 100); // truncates
d = l / 100.0;
You are returning a double. But double or Double are objects representing a number and don't carry any formatting information. Ìf you need to output two decimal places the point to do this is when you convert your double to a String.
use # if you want to ignore 0
new DecimalFormat("###,#0.00").format(d)
There is another way to achieve this . I have already posted answer in post
will just answer again here. As we will require rounding off values many times .
public class RoundingNumbers {
public static void main(String args[]){
double number = 2.5045;
int decimalsToConsider = 2;
BigDecimal bigDecimal = new BigDecimal(number);
BigDecimal roundedWithScale = bigDecimal.setScale(decimalsToConsider, BigDecimal.ROUND_HALF_UP);
System.out.println("Rounded value with setting scale = "+roundedWithScale);
bigDecimal = new BigDecimal(number);
BigDecimal roundedValueWithDivideLogic = bigDecimal.divide(BigDecimal.ONE,decimalsToConsider,BigDecimal.ROUND_HALF_UP);
System.out.println("Rounded value with Dividing by one = "+roundedValueWithDivideLogic);
}
}
Output we will get is
Rounded value with setting scale = 2.50
Rounded value with Dividing by one = 2.50
double kilobytes = 1205.6358;
double newKB = Math.round(kilobytes*100.0)/100.0;
DecimalFormat df = new DecimalFormat("###.##");
System.out.println("kilobytes (DecimalFormat) : " + df.format(kilobytes));
Try this if u are still getting the above problem

java rounding to two decimals

I have a number
double num = 1.234567;
and I'm trying to keep only two decimals
num = (int)((num * 100) + 0.5) / 100.0;
but the actual number I got is 1.230000000001. How can I get rid of the 0000000001 part?
Try DecimalFormat:
DecimalFormat twoDp= new DecimalFormat("#.##");
Double.valueOf(twoDp.format(num));
You can't, unless you switch to a decimal radix. Doubles and floats don't have decimal places, they have binary places, so you can't round or truncate them to specific numbers of decimal places except in the cases where the value representations are congruent, i.e. the negative powers of 2.
So you have to either use DecimalFormat if you are presenting the result, or BigDecimal if you want to keep computing with it.
Any solution that ends by turning the value back into floating point is incorrect.
String result = String.format("%.2f", num);
Try this .. this should solve it
Double num = //value
num = //arithmetic
String temp =num.toString().split("\\.")[0];
int precision=temp.length();
BigDecimal b =new BigDecimal(num,new MathContext(precision+2));
System.out.println(b.doubleValue());

Java BigDecimal without E

I have a BigDecimal variable
BigDecimal x = new BigDecimal("5521.0000000001");
Formula:
x = x.add(new BigDecimal("-1")
.multiply(x.divideToIntegralValue(new BigDecimal("1.0"))));
I want to remove the integer part, to get the value x = ("0.0000000001"), but my new value is 1E-10 and not the 0.0000000001.
To get a String representation of the BigDecimal without the exponent part, you can use
BigDecimal.toPlainString(). In your example:
BigDecimal x = new BigDecimal("5521.0000000001");
x = x.add(new BigDecimal("-1").
multiply(x.divideToIntegralValue(new BigDecimal("1.0"))));
System.out.println(x.toPlainString());
prints
0.0000000001
Try using BigDecimal.toPlainString() to get value as plain string as you require.
Perhaps using BigDecimal isn't really helping you.
double d = 5521.0000000001;
double f = d - (long) d;
System.out.printf("%.10f%n", f);
prints
0.0000000001
but the value 5521.0000000001 is only an approximate representation.
The actual representation is
double d = 5521.0000000001;
System.out.println(new BigDecimal(d));
BigDecimal db = new BigDecimal(d).subtract(new BigDecimal((long) d));
System.out.println(db);
prints
5521.000000000100044417195022106170654296875
1.00044417195022106170654296875E-10
I suspect whatever you are trying to is not meaningful as you appear to be trying to obtain a value which is not what you think it is.
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

How do I round a double to two decimal places in Java? [duplicate]

This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 3 years ago.
This is what I did to round a double to 2 decimal places:
amount = roundTwoDecimals(amount);
public double roundTwoDecimals(double d) {
DecimalFormat twoDForm = new DecimalFormat("#.##");
return Double.valueOf(twoDForm.format(d));
}
This works great if the amount = 25.3569 or something like that, but if the amount = 25.00 or the amount = 25.0, then I get 25.0! What I want is both rounding as well as formatting to 2 decimal places.
Just use: (easy as pie)
double number = 651.5176515121351;
number = Math.round(number * 100);
number = number/100;
The output will be 651.52
Are you working with money? Creating a String and then converting it back is pretty loopy.
Use BigDecimal. This has been discussed quite extensively. You should have a Money class and the amount should be a BigDecimal.
Even if you're not working with money, consider BigDecimal.
Use a digit place holder (0), as with '#' trailing/leading zeros show as absent:
DecimalFormat twoDForm = new DecimalFormat("#.00");
Use this
String.format("%.2f", doubleValue) // change 2, according to your requirement.
You can't 'round a double to [any number of] decimal places', because doubles don't have decimal places. You can convert a double to a base-10 String with N decimal places, because base-10 does have decimal places, but when you convert it back you are back in double-land, with binary fractional places.
This is the simplest i could make it but it gets the job done a lot easier than most examples ive seen.
double total = 1.4563;
total = Math.round(total * 100);
System.out.println(total / 100);
The result is 1.46.
You can use org.apache.commons.math.util.MathUtils from apache common
double round = MathUtils.round(double1, 2, BigDecimal.ROUND_HALF_DOWN);
double amount = 25.00;
NumberFormat formatter = new DecimalFormat("#0.00");
System.out.println(formatter.format(amount));
You can use Apache Commons Math:
Precision.round(double x, int scale)
source: http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html#round(double,%20int)
Your Money class could be represented as a subclass of Long or having a member representing the money value as a native long. Then when assigning values to your money instantiations, you will always be storing values that are actually REAL money values. You simply output your Money object (via your Money's overridden toString() method) with the appropriate formatting. e.g $1.25 in a Money object's internal representation is 125. You represent the money as cents, or pence or whatever the minimum denomination in the currency you are sealing with is ... then format it on output. No you can NEVER store an 'illegal' money value, like say $1.257.
Starting java 1.8 you can do more with lambda expressions & checks for null. Also, one below can handle Float or Double & variable number of decimal points (including 2 :-)).
public static Double round(Number src, int decimalPlaces) {
return Optional.ofNullable(src)
.map(Number::doubleValue)
.map(BigDecimal::new)
.map(dbl -> dbl.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP))
.map(BigDecimal::doubleValue)
.orElse(null);
}
You can try this one:
public static String getRoundedValue(Double value, String format) {
DecimalFormat df;
if(format == null)
df = new DecimalFormat("#.00");
else
df = new DecimalFormat(format);
return df.format(value);
}
or
public static double roundDoubleValue(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
long factor = (long) Math.pow(10, places);
value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}
DecimalFormat df = new DecimalFormat("###.##");
double total = Double.valueOf(val);
First declare a object of DecimalFormat class. Note the argument inside the DecimalFormat is #.00 which means exactly 2 decimal places of rounding off.
private static DecimalFormat df2 = new DecimalFormat("#.00");
Now, apply the format to your double value:
double input = 32.123456;
System.out.println("double : " + df2.format(input)); // Output: 32.12
Note in case of double input = 32.1;
Then the output would be 32.10 and so on.
If you want the result to two decimal places you can do
// assuming you want to round to Infinity.
double tip = (long) (amount * percent + 0.5) / 100.0;
This result is not precise but Double.toString(double) will correct for this and print one to two decimal places. However as soon as you perform another calculation, you can get a result which will not be implicitly rounded. ;)
Math.round is one answer,
public class Util {
public static Double formatDouble(Double valueToFormat) {
long rounded = Math.round(valueToFormat*100);
return rounded/100.0;
}
}
Test in Spock,Groovy
void "test double format"(){
given:
Double performance = 0.6666666666666666
when:
Double formattedPerformance = Util.formatDouble(performance)
println "######################## formatted ######################### => ${formattedPerformance}"
then:
0.67 == formattedPerformance
}
Presuming the amount could be positive as well as negative, rounding to two decimal places may use the following piece of code snippet.
amount = roundTwoDecimals(amount);
public double roundTwoDecimals(double d) {
if (d < 0)
d -= 0.005;
else if (d > 0)
d += 0.005;
return (double)((long)(d * 100.0))/100);
}
where num is the double number
Integer 2 denotes the number of decimal places that we want to print.
Here we are taking 2 decimal palces
System.out.printf("%.2f",num);
Here is an easy way that guarantee to output the myFixedNumber rounded to two decimal places:
import java.text.DecimalFormat;
public class TwoDecimalPlaces {
static double myFixedNumber = 98765.4321;
public static void main(String[] args) {
System.out.println(new DecimalFormat("0.00").format(myFixedNumber));
}
}
The result is: 98765.43
int i = 180;
int j = 1;
double div= ((double)(j*100)/i);
DecimalFormat df = new DecimalFormat("#.00"); // simple way to format till any deciaml points
System.out.println(div);
System.out.println(df.format(div));
You can use this function.
import org.apache.commons.lang.StringUtils;
public static double roundToDecimals(double number, int c)
{
String rightPad = StringUtils.rightPad("1", c+1, "0");
int decimalPoint = Integer.parseInt(rightPad);
number = Math.round(number * decimalPoint);
return number/decimalPoint;
}

Categories

Resources