rounding decimal points [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Round a double to 2 significant figures after decimal point
I am trying to work with converting a decimal degree (23.1248) into a minutes style degree(23 7'29.3").
this is what I have so far:
double a=23.1248;
int deg=(int)a;//gives me the degree
float b=(float) (a-deg);
int min=(int) (b*60);//gives me the minutes
double sec= (double) ((c*60)-min);//gives me my seconds
everything works fine, but I would like to round the seconds up to either the nearest tenth or hundrenth. I have looked at decimal formatting, but would prefer not to cast it to a string. I have also looked at bigdecimal but do not think that would be helpful,

Try using Math.round(double) on the number after scaling it up, then scaling it back down.
double x = 1.234;
double y = Math.round(x * 100.0) / 100.0; // => 1.23
You can also use BigDecimal if you want to get really heavyweight:
BigDecimal a = new BigDecimal("1.234");
BigDecimal b = a.setScale(2, RoundingMode.DOWN); // => BigDecimal("1.23")

First off, there are library functions to do this, so why not just use those? See Math.round(). No need to reinvent the wheel. If you wanted to, though, you could try what follows. To round a double to the hundredth's place:
x = 0.01 * floor(x * 100.0)
To round a double to the tenth's place:
x = 0.1 * floor(x * 10.0)
To round a double to the 10^k place:
x = 10^k * floor(x / 10^k)
The implementation in any language - including Java - should be straightforward. A problem with this is that it doesn't really round, but truncates, to your position. To fix this, you can simply add 0.5 * 10^k to your number before rounding. If you just want to round up, use the versions above, and add 10^k before or after the computation.

Related

How to cap a double's precision to a precision given in the form of 0.00...1?

I have this strange issue of having to cap the precision of double numbers to a number of decimal places, or no decimal places at all, where the precision is handed to me like so: 0.001, 0.1, 1, 0.00001, etc.
So I could be given, for example, 1.234247324 and a precision indicator of 0.001, and with that I would need to return 1.234. If Instead I had been handed a precision of 1.0, I would then return 1 (no decimal places), and so forth.
I'm not sure how to go about this. Does anyone has pointers on how to tackle this?
Thank you!
Start with your value, and create a BigDecimal, then round to what you want.
double value = 1.23456; //not actually equal to that, but pretend.
BigDecimal better = new BigDecimal(value);
BigDecimal rounded = better.round(new MathContext(3));
Rounded is now the actual value you want. What can you do with the precision indicator?
BigDecimal precision = new BigDecimal("0.001");
Now you can get the scale of the precision, which you can use for rounding.
System.out.println(precision.scale());
//outputs 3.
That would be similar to using the logarithm.
Use a hybrid approach of the two other answers allows unusual precisions like 0.25 to be specified:
BigDecimal rounded = (x / precision).round(new MathContext(0)) * precision;
Try this code
double x = 1.234247324;
double p = 0.001;
double y = (int)(x * 1 / p) / (1 / p);
Don't really understand what you want to do but this results 1.234.

How to round to the nearest 0.05? [duplicate]

This question already has an answer here:
Java rounding to nearest 0.05
(1 answer)
Closed 8 years ago.
I'm trying to find a way on how to round to the nearest 0.05 in java. Let's say that I have the following numbers:
0.33
0.02
0.874
0.876
This should become:
0.35
0.00
0.85
0.90
I tried many things and I can only get it to round to n places behind the comma by using BigDecimal, but I can't seem to find a way for this one.
Can someone help me?
EDIT: Thank you for all your help, I am amazed at how easy this could be done. And how do I get the double converted into a string properly? I can't use Double.toString(double d) because for example the string will be "0.9" instead of "0.90"?
0.05 == 1/20, right? Therefore, what you need is just the nearest number with dividing by 1/20, so, you may multiply this number by 20, get the nearest number with dividing by 1, then get the initial things.
TL;DR: you just may just multiply it by 20, round and divide by 20 again:
public double customRound(double num) {
return Math.round(num * 20) / 20.0;
}
A simple way would be:
double d = 0.33;
double roundedTimes20 = Math.round(d * 20);
double rounded = roundedTimes20 / 20; //0.35
but note that the resulting double is not necessarily the exact representation of the rounded number (usual floating point caveat) and that the method assumes that your original double times 20 can fit in a long.
Try a function:
public static double round05(double num) {
return Math.round(num * 20) / 20.0;
}
You can use String.format to format value to String
String s = String.format("%.2f", 0.9);

Rounding off 2 decimal places in Java for whole number [duplicate]

This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 9 years ago.
I have the following and the question is, for example if zzi = 95 then myNum will be correctly displayed as 32.33, exactly as I want it too with two decimal places.
However if zzi = 94, myNum will be displayed as 32.0 instead of 32.00
How to display it as 32.00?
float xFunction(int zzi) {
float myNum = (zzi + 2);
myNum = myNum / 3;
int precision = 100; // keep 4 digits
myNum = (float) (Math.floor(myNum * precision + .5) / precision);
return myNum;
}
Thanks before.
Your question is not so much about rounding a number as it is about rounding a display or String representation of a number. The solution:
Use new DecimalFormat("0.00");
Or String.format("%.2f", myNumber);
Or new java.util.Formatter("%.2f", myNumber);
Or System.out.printf("%.2f", myNumber);
Note: avoid use of float whenever possible, and instead prefer use of double which greatly improves numeric precision at little cost. For financial calculations use neither but instead opt for integer calculations or use BigDecimal.
Remember:
1) printing the number displaying two decimal places is very different from rounding the actual value. In other words "representation" != actual value.
2) floating point values are always imprecise. Even with rounding, you may or may not get an "exact value".
Having said that, the simplest approach is:
float myNum = ((123.456 * 100.0) + .5) / 100.0;
new DecimalFormat("#.##").format(myNum );
You can use DecimalFormat
System.out.println(new DecimalFormat("0.00").format(xFunction(94)));
You should work on the printing function. I assume you are using a System.out.println: replace it with
System.out.format("%.2f", numberToPrint);
Read the docs for that function to discover more about format strings.

unexpected results with decimal arithmetic expression

I have some business logic with arithmetic expression and their results are as follows
(10.0 * 20.58)/1.0=205.7999..98
(6.0 * 37.9)/1.0=227.3999..98
(5.0 * 50.0)/1.0=250.0
(10.0 * 37.9)/1.0=379.0
But expected results are
(10.0 * 20.58)/1.0=205.8
(6.0 * 37.9)/1.0=227.4
(5.0 * 50.0)/1.0=250.0
(10.0 * 37.9)/1.0=379.0
I am not clear why we are getting that .999..98 fraction part? Due to that my equals comparison is failing and so business logic. For few cases we are using
amt = (double)Math.round(orderAmt*100000)/100000;
But that is not possible to do the same in each and every place where we have double arithmetic expression.
I want to know why we get such results randomly and is there any possibility to round the results to 5 decimal places instead of rounding every where?
With radix 10 there are some fractions who can't be expressed exactly with a finite number of digits, like for example 1/3 = 0.33333333....
It's the same with radix 2, except that the dividers that produce this kind of results are not the one we are accustomed to, and for example, for 20.58, which is 2058 / 100, it is the case.
Internally, doubles and floats are stored with bits (an not digit), so the exact value of the double or float just can't be stored in the computer's memory. Each time you perform an operation with this value, you get a small shift, because of the approximation, which becomes visible when converting back to decimal format for printing.
It's something you have to pay attention while perfoming computations where precision is important.
So you have two solutions:
Store all your numbers in decimal type and perform all your calculation with it. This will achieve accuracy but for the price of performance.
You can also keep all the calculation with double or float, and format with a fixed number of digits only for printing results.
You could use BigDecimal for roundoff
BigDecimal bd = new BigDecimal((10.0 * 20.58)/1.0) ;
bd = bd.setScale(4, RoundingMode.UP);
use with a static method
public static double round(double value, int digits) {
BigDecimal bd = new BigDecimal(value);
return bd.setScale(digits, RoundingMode.UP).doubleValue();
}
RoundingMode has :
RoundingMode.UP;
RoundingMode.DOWN;
RoundingMode.HALF_DOWN;
RoundingMode.HALF_EVEN;
The basic problem is that
System.out.println(10.0 * 20.58);
prints
205.79999999999998
has a small rounding error due to a representation error in 20.58
You either need to
round the result before comparing.
use a comparision which allows for some error
use BigDecimal (which is over kill in most cases)
use cents instead of dollars i.e. use int or long with fixed precision.
In the last case, the same operation would read
System.out.println(10 * 2058);
prints
20580
where this is 100x the value you need as its fixed precision e.g. cents instead of dollars.
You may want to use double with rounding as below:
double roundingPlaces = 10.0;//use 10.0 for single decimal digit rounding
double a1 = 10.0;
double b1 = 20.58;
double c1 = 1.0;
System.out.println(Math.round((a1*b1*roundingPlaces)/c1)/roundingPlaces);
This prints 205.8.
float fa1 = (float) 10.0;
float fb1 = (float)20.58;
float fc1 = (float)1.0;
System.out.println(fa1*fb1/fc1);
This also prints 205.8
Use float instead of double
http://ideone.com/L9vwR8
System.out.println((float)((10.0f * 20.58f)/1.0f));
output
205.8

Why does integer division code give the wrong answer? [duplicate]

This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed last year.
I have a very simple division in Java (it's a product quantity / production per hour), however whenever I make this division I get strange errors:
float res = quantity / standard;
I have tried the above division with several values and I always get errors, however the one that I've tried everywhere else and gotten right was this:
Everywhere in the world:
13.6 = 6800 / 500;
Java:
13.0 = 6800 / 500;
I've researched BigDecimal and BigInteger, however I haven't found a way to create this division with them, is there any other way to do this division in Java without having precision errors??
Any help will be greatly appreciated.
You're dividing integers, which means that you're using integer division.
In integer division the fractional part of the result is thrown away.
Try the following:
float res = (float) quantity / standard;
^^^^^^^
The above forces the numerator to be treated as a float which in turn promotes the denominator to float as well, and a float-division is performed instead of an int-division.
Note that if you're dealing with literals, you can change
float f = 6800 / 500;
to include the f suffix to make the denominator a float:
float f = 6800f / 500;
^
If you concerned about precision I would suggest using double which has more than double the number of digits of precision. However floating point only accurately represents fractions which are a sum or powers of 0.5. This means 0.6 is only approximately represented. This doesn't have to be a problem with appropriate rounding.
double d = (double) 6800 / 500;
or
double d = 6800.0 / 500;
In my case I was doing this:
double a = (double) (MAX_BANDWIDTH_SHARED_MB/(qCount+1));
Instead of the "correct" :
double a = (double)MAX_BANDWIDTH_SHARED_MB/(qCount+1);
hi try this one it may help ful your requirement
double percent=(7819140000l-3805200000l)*100f/7819140000l;
public String format_Decimal(double decimalNumber) {
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(5);
nf.setMinimumFractionDigits(2);
nf.setRoundingMode(RoundingMode.HALF_UP);
String x = nf.format(decimalNumber);
return x;
}

Categories

Resources