it´s a simple task but i´m not able to solve it on my own..
i got
double digit1 = 12.1;
double digit2 = 12.99;
and need a method which gives me this:
anyMethod(digit1); //returns 10
anyMethod(digit2); //returns 99
what i have is
public static void getAfterComma(double digit) {
BigDecimal bd = new BigDecimal(( digit - Math.floor( digit )) * 100 );
bd = bd.setScale(4,RoundingMode.HALF_DOWN);
System.out.println(bd.toBigInteger()); // prints digit1=1 and digit2=99
}
anyway i prefer integer as the returntype..
anybody got a quick solution/tip?
kindly
Why not you simply use:
int anyMethod(double a){
//if the number has two digits after the decimal point.
return (int)((a + 0.001) * 100) % 100;
}
A simple way of getting the fractional part of a double is to use the modulo operator, %. However, you'll have to take into account the fact that floating point arithmetic isn't precise. For example,
System.out.println(12.1 % 1); // outputs 0.09999999999999964
System.out.println(12.99 % 1); // outputs 0.9900000000000002
If you want to get two decimal digits as an int, which is what I think you're asking, you can achieve this, glossing over the floating point issues, like so:
System.out.println(Math.round((12.1 % 1) * 100)); // outputs 10
System.out.println(Math.round((12.99 % 1) * 100)); // outputs 99
However, you should consider going further down the BigDecimal path you started down, which uses arbitrary precision arithmetic. You could do something like this:
System.out.println(new BigDecimal("12.1").remainder(BigDecimal.ONE)); // outputs 0.1
System.out.println(new BigDecimal("12.99").remainder(BigDecimal.ONE)); // outputs 0.99
If, as before, you want two decimal digits from this, you can do this:
System.out.println(new BigDecimal("12.1").remainder(BigDecimal.ONE).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP).intValue()); // outputs 0.1
System.out.println(new BigDecimal("12.99").remainder(BigDecimal.ONE).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP).intValue()); // outputs 0.99
Note that there a couple of differences between these last two methods and the first two: they preserve the sign of the argument, so if you use the final example for -12.99, you'll get -99 back, and they treat the fractional part of an integer as 1, so if you use the final example for 12, you'll get 100 back.
It's not necessary to use Number tyeps all the time. You can take advantage of String as a mediator.
String mediator = Double.valueOf(d1).toString();
mediator = mediator.substring(mediator.indexOf('.') + 1);
Integer result = Integer.valueOf(mediator);
Try this out
public static void main(String args[]){
double a=12.99;
double b=12.1;
System.out.println(method(a));
System.out.println(method(b));
}
private static int method(double a) {
return (int) ((a*100)%100);
}
sachin-pasalkar done it! little fix but fine!
public static int anyMethod(double a){
return (int) (a*100)%100;
}
check out this code returns digits after '.' always. Without any extra parameters other than double variable.
public int anyMethod(double d)
{
String numString = d+"";
return Integer.parseInt(numString.substring(numString.indexOf('.')+1));
}
If I understand correctly, you need to return n digits after the dot for a given double number. So... let's see:
public int decimalDigits(double x, int n) {
double ans;
ans = (x - (int) x) * Math.pow(10, n);
return (int) ans;
}
Done. Hope this helps you.
For your specific example, 'n = 2' should do.
Related
I want a particular number of digits in double/float primitive type. Is there any way to do this?
For example: (fixed to 6 digits)
If we have 12.666666667 gives output as 12.6667
If we have 5.6666666667 gives output as 5.66667
However, if we have 9.00000000 gives output as only 9.*
For, more clear understanding, I have attached an image.enter image description here
How to replicate the same output that I got from below mentioned code in java:
#include<iostream>
using namespace std;
int main()
{
float num = 9.34333666666663;
float num2 = 12.0000000
cout << num;
cout << num2;
return 0;
}
Output:-
9.34334
12
Two things to consider. One is if you need an exact precision, since floating point arithmetic might not give you that. See the BigDecimal class for more information. The other is what you're trying to do: display a number with a certain number of decimal places. You can accomplish this with String.format. For example
double num = 5.666666666;
String formatted = String.format("%.5f", num);
And
System.out.println(formatted)
Will output
5.66667
import java.text.DecimalFormat;
public class rounding {
public static void main(String[] args) {
double num = 23.122345899;
double rounded = Math.round(num * 1000000) / 1000000.0;
System.out.println(rounded);
}
}
This question already has answers here:
Java: How to set Precision for double value? [duplicate]
(11 answers)
Closed 5 years ago.
I’m working on a project at the java and can’t get a very important method to work
I have tried multiple solutions many from similar questions in stackoverflow none of the answers seems to work for may case
What I need is a simple method that will get a double and no matter what is the value of the double as long as there is more than two digits after the dot it will return the same number with only the first two digits after the dot
For example even if the input is “-3456.679985432333”
The output would be “-3456.67” and not “-3456.68” like other solutions gave me
The closest solution that seems to work was
public static double round (double d) {
d = (double) (Math.floor(d * 100)) / (100);
return d;
}
Yet it did failed when the input was “-0.3355555555555551” the output was “-0.34” and not “-0.33” as expected
I have no idea why did it fail and I’m out of solutions with only a few hours left for this project.
Edit: the fix I found was simple and worked great
public static double round (double d){
if (d>0) return (double) (Math.floor(d*100))/100;
else
{
return (double) (Math.ceil(d*100))/100;
}
}
Anyway thanks for everyone that explained to me what was wrong with my method and I will make sure to try all of your solutions
Explanation
Java is working correct. It's rather that floor returns the first integer that is less than (or equal) to the given value. It does not round towards zero.
For your input -0.335... you first multiply by 100 and receive -33.5.... If you now use floor you correctly receive -34 since its a negative number and -34 is the first integer below 33.5....
Solution
If you want to strip (remove) everything after the decimal you need to use ceil for negative numbers. Or use a method which always rounds towards zero, i.e. the int cast:
public static double round (double d) {
d = (double) ((int) (d * 100)) / (100);
return d;
}
(also see round towards zero in java)
Better alternatives
However there are dedicated, better, methods to achieve what you want. Consider using DecimalFormat (documentation):
DecimalFormat formatter = new DecimalFormat("##.##"); //
formatter.setRoundingMode(RoundingMode.DOWN); // Towards zero
String result = formatter.format(input);
Or any other variant, just search for it, there are plenty of questions like this: How to round a number to n decimal places in Java
Something like this would suffice:
public static double truncate(double input) {
DecimalFormat decimalFormat = new DecimalFormat("##.##");
decimalFormat.setRoundingMode(RoundingMode.DOWN);
String formatResult = decimalFormat.format(input);
return Double.parseDouble(formatResult);
}
returns:
-3456.67
and
-0.33
respectively for both examples provided.
you are able to do this, all you need to do is:
number * 10 or (100),
then convert to a int,
then back to double and / 10 (or 100).
10 = for 1 number after digit,
100 = for 2 (if i remember correctly).
public static double CustomRound(double number, int digits)
{
if (digits < 0)
throw new IllegalArgumentException();
long f = (long)Math.pow(10, digits);
number = number * f;
long rnd = Math.round(number);
return (double)(rnd / f);
}
An alternative approach:
public static double round(double number, int digits)
{
if (digits < 0)
throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(digits, RoundingMode.HALF_UP);
return bd.doubleValue();
}
What I would like to do is a method to round float number to N decimal places (N will be given in stdin), do some math operation with it and then print the result. I found this:
public BigDecimal round(float number, int decimal){
BigDecimal obj = new BigDecimal(number).setScale(decimal, BigDecimal.ROUND_HALF_UP);
return obj;
Which works pretty well, but not when number N (int decimal in this method) is high. For example: x = -10, y = -11.8814, N = 8 and it prints this:
-10.00000000 + -11.88140011 = -21.88140106
And this is what I would want:
-10.00000000 + -11.88140000 = -21.88140000
Thanks everybody for suggestions :)
I think the easiest thing to do is multiply your numbers by 10^N and use round() to turn them into integers. Run your math and then divide them back down
public static void main(String[] args) {
double a = -10.0;
double b = -11.88140011;
int n = 4;
long total = round(a, n) + round(b, n);
System.out.println(String.format("%.8f%n", total * Math.pow(10, -1*n)));
}
static Long round(double number, int decimal) {
return Math.round(number * Math.pow(10, decimal));
}
There is no float representation of 11.88140000 with all 8 decimal places intact, so at the moment you pass that number to your method regardless of the implementation it has no chance to return the wanted result, see article for float on Wikipedia:
... the total precision is 24 bits (equivalent to log10(224) ≈ 7.225 decimal digits)
And that precision is including all digits, not only those after the decimal separator.
Your question already has an answer, but to understand the problem float vs. decimal better, there is another post about the problem explaining it a bit more in depth (same for every programming language):
Just for completeness: 0.3 would be exactly stored as it is in a BigDecimal. In float (due to it's binary nature), it would be stored as 0.30000001192092896. You instantiate your BigDecimal using a float and directly step into this problem.
So, here is the answer. I didn't use function round I only printed the numbers with results:
System.out.printf("%." + n + "f + %." + n + "f = %." + n + "f\n", a, b, a + b);
Which I tried before I posted this question, BUT I used float and haven't tried using double (with function nextDouble() for scanning). So, double was the answer.
Thanks for your suggestions! :))
I want to round a Java BigDecimal to a certain number of significant digits (NOT decimal places), e.g. to 4 digits:
12.3456 => 12.35
123.456 => 123.5
123456 => 123500
etc. The basic problem is how to find the order of magnitude of the BigDecimal, so I can then decide how many place to use after the decimal point.
All I can think of is some horrible loop, dividing by 10 until the result is <1, I am hoping there is a better way.
BTW, the number might be very big (or very small) so I can't convert it to double to use Log on it.
Why not just use round(MathContext)?
BigDecimal value = BigDecimal.valueOf(123456);
BigDecimal wantedValue = value.round(new MathContext(4, RoundingMode.HALF_UP));
The easierst solution is:
int newScale = 4-bd.precision()+bd.scale();
BigDecimal bd2 = bd1.setScale(newScale, RoundingMode.HALF_UP);
No String conversion is necessary, it is based purely on BigDecimal arithmetic and therefore as efficient as possible, you can choose the RoundingMode and it is small. If the output should be a String, simply append .toPlainString().
You can use the following lines:
int digitsRemain = 4;
BigDecimal bd = new BigDecimal("12.3456");
int power = bd.precision() - digitsRemain;
BigDecimal unit = bd.ulp().scaleByPowerOfTen(power);
BigDecimal result = bd.divideToIntegralValue(unit).multiply(unit);
Note: this solution always rounds down to the last digit.
Someone will probably come up with a better solution, but the first thing that comes to mind is chuck it in to a StringBuilder, check whether it contains a '.' and return an appropriate length substring. E.g.:
int n = 5;
StringBuilder sb = new StringBuilder();
sb.append("" + number);
if (sb.indexOf(".") > 0)
{
n++;
}
BigDecimal result = new BigDecimal(sb.substring(0, n));
To me this seems as simple as:
Given N = 5, D = 123.456789
get the string representation of the number, "123.456789"
retrieve the first N-1 digits of the number, "123.4"
evaluate D[N] and D[N+1], in this case "5" and "6"
6 meets the criteria for rounding up (6 > 4), therefore carry 1 and make D[N] = 5+1 = 6
D post rounding is now 123.46
Order can be calculated using Math.floor(Math.log(D)).
hope this helps.
Since BigDecimal is basically a string, perhaps this:
import java.math.BigDecimal;
public class Silly {
public static void main( String[] args ) {
BigDecimal value = new BigDecimal("1.23238756843723E+5");
String valueString = value.toPlainString();
int decimalIndex = valueString.indexOf( '.' );
System.out.println( value + " has " +
(decimalIndex < 0 ? valueString.length() : decimalIndex) +
" digits to the left of the decimal" );
}
}
Which produces this:
123238.756843723 has 6 digits to the left of the decimal
A.H.'s answer is technically correct, but here is a more general (and easier to understand) solution:
import static org.bitbucket.cowwoc.requirements.core.Requirements.assertThat;
/**
* #param value a BigDecimal
* #param desiredPrecision the desired precision of {#code value}
* #param roundingMode the rounding mode to use
* #return a BigDecimal with the desired precision
* #throws NullPointerException if any of the arguments are null
*/
public BigDecimal setPrecision(BigDecimal value, int desiredPrecision, RoundingMode roundingMode)
{
assertThat("value", value).isNotNull();
assertThat("roundingMode", roundingMode).isNotNull();
int decreaseScaleBy = value.precision() - desiredPrecision;
return value.setScale(value.scale() - decreaseScaleBy, roundingMode);
}
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;
}