How to round a number to within a certain range? - java

I have a value like this:
421.18834
And I have to round it mathematical correctly with a mask which can look like this:
0.05
0.04
0.1
For example, if the mask is 0.04, i have to get the value 421.20, because .18 is nearer at .20 than .16.
All functions that I found using Google didn't work.
Can you please help me?

double initial = 421.18834;
double range = 0.04;
int factor = Math.round(initial / range); // 10530 - will round to correct value
double result = factor * range; // 421.20

You don't need a special function. You multiply your original number by (1/mask), you round it to a decimal and you divide again by the same factor.
Example with 0.05
factor = 1/0.05 = 20
421.18834 * 20 = 8423.7668
int( 8423.7668 ) = 8424
8424.0 / 20.0 = 421.20
Example with 0.01
factor = 1/0.1 = 10
421.18834 * 10 = 4211.8834
int( 4211.8834 ) = 4212
4212.0 / 10.0 = 421.20

Contrary to all the answers you will probably get here about multiplying and dividing, you can't do this accurately because floating point doesn't have decimal places. To need to convert to a decimal radix and then round. BigDecimal does that.

Both fredley and Matteo make the assumption that the rounding factor is itself a factor of 100. For factors like 0.06 or 0.07, this is an incorrect assumption.
Here's my Java routine:
public double rounded(double number, double factor) {
long integer = (long) number;
double fraction = number - integer;
double multiple = (fraction / factor);
multiple = Math.round(multiple);
return factor * multiple + integer;
}

Related

How to round without Math#round?

So it's easy to round the tenths place with just doing something like:
int y;
double x = 2.5;
y = (int) (x+.5);
but how would you go about rounding to the hundredths or even thousands place without using Math.round()?
You can multiply the original number by a power of 10 so that the desired place to round is in the unit's place, apply the "add half and round" method you already have, then divide the same power of 10, so the resulting number is now back to the original scale.
For hundredths:
Declare y to be a double. This is so that rounding 2.125 to the hundredths' place will result in 2.13, not 2.
Multiply the x value by 100.0.
Add 0.5.
Cast to int. (Or long for more precision.)
Divide by 100.0.
Ex.: Rounding 2.125 to the hundredths' place.
1. 2.125 * 100.0 is 212.5.
2. 212.5 + 0.5 is 213.0.
3. 213.0 cast to int is 213.
4. 213 divided by 100.0 is 2.13.
For thousandths, the procedure is the same, except that 100.0 is replaced by 1000.0.
The above method is subject to floating-point errors due to the finite precision of the double floating-point type.
You can also convert your value to a BigDecimal. Then you can use BigDecimal's round method. It takes a MathContext that allows you directly to round to the desired precision.
public class Decimal {
public static void main(String[] args) {
double xd = 2.125;
double mult = xd * 100.0;
double add = mult + 0.5;
int reuslts = (int) add;
double result = reuslts / 100.0;
System.out.println(result);// 2.13
}
}

Rounding UP double values in java based on parameters

I have the following scenario , let us assume 125,250,500 are rounding parameter based on which we have to do rounding.
when the rounding parameter is 125 then I need to round off to 1/8 th dollar,
ie, value = 10.01 then it should return 10.125
value = 110.2 then it should return 110.250
when the rounding parameter is 250 then I need to round off to quarter dollar,
ie, value = 10.01 then it should return 10.250
value = 110.3 then it should return 110.500
when the rounding parameter is 500 then I need to round off to half dollar,
ie, value = 10.01 then it should return 10.500
value = 110.6 then it should return 111.
I have written code using Math.round(8f * value/8f) which rounds of to nearest 1/8 th dollar but the rounding should be UP always but in my case 10.01 rounds off to 10
First off, you're not rounding, you're doing a ceiling.
This code does what you want:
Math.ceil(n * 1000 / factor) * factor / 1000;
Here is the code bundled as a method:
public static double ceil(double n, int factor) {
return Math.ceil(n * 1000 / factor) * factor / 1000;
}
Note that no casting is required, because in java arithemtic if one of the operands is double, the others are automatically (and safely) widened to double too.
I have written code using Math.round(8f * value/8f) which rounds of to nearest 1/8 th dollar
No it doesn't. It rounds to the nearest integer.
Try for example Math.round(((8f+1/8f) * value))/8f.
Break it down to manageable steps, no value trying to do it on one line. So:
How many 1/8th dollars are there in value?
float dollar8ths = value * 8f;
Round that up:
int dollar8thsRoundedUp = (int) Math.ceil(dollar8ths);
Finally, put back into dollars:
float dollars = dollar8thsRoundedUp / 8f;
This should do what you want:
double myRound(double val, int param)
{
val = 1000 * val / param;
val = Math.ceil(val);
return val * param / 1000;
}
e.g.:
System.out.println(myRound(10.01, 125));
gives
10.125

Possible loss of precision during conversion of float number

I have google on how to get 2 decimal for a float number in java. Below are my codes. Finally here float totalWeight = 0.1*levinWeight+0.8*lsmWeight; I get the error of possible loss of precision ? I would want to first covert the string into float and then have it to be 2 decimal places.
float levinWeight = Float.parseFloat(dataOnlyCombine[2]);
float lsmWeight = Float.parseFloat(dataOnlyCombine[3]);
DecimalFormat df = new DecimalFormat("#.##");
levinWeight = Float.valueOf(df.format(levinWeight));
lsmWeight = Float.valueOf(df.format(lsmWeight));
float totalWeight = 0.1*levinWeight+0.8*lsmWeight;
If you are concerned about precision
don't use float, it has the lowest precision of any option available. I suggest using double or BigDecimal
use operation which involve values which can be accurately represented. 0.1 * x will give you error because 0.1 cannot be represented precisely. Using x / 10.0 will have less error.
I would write something like this
double levinWeight = Double.parseDouble(dataOnlyCombine[2]);
double lsmWeight = Double.parseDouble(dataOnlyCombine[3]);
double totalWeight = (levinWeight + 8 * lsmWeight) / 10.0;
// perform rounding only at the end as appropriate.
// to round to two decimal places
double totalWeight2 = Math.round(totalWeight * 100) / 100.0;
float levinWeight = Float.parseFloat(dataOnlyCombine[2]);
float lsmWeight = Float.parseFloat(dataOnlyCombine[3]);
float totalWeight = 0.1*levinWeight+0.8*lsmWeight;
DecimalFormat df = new DecimalFormat("#.##");
String totalWeightValue = df.format(totalWeight);
If you really want to do it like that, then use BigDecimal. Those floating point classes are perfect for precision. Take a look at them:
http://voidexception.weebly.com/java-bigdecimal---dealing-with-high-precision-calculations.html
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
http://www.javaworld.com/article/2075315/core-java/make-cents-with-bigdecimal.html
Default IEEE 746 floating points will not suit your needs. Alternatively, you could use integers and thread them factor 100. So:
100 is equivalent to 1.00
452 is equivalent to 4.52
1 is equivalent to 0.01

How can I show up to 2 decimal places without rounding off?

I want to take two decimal places only for a float without rounding off. eg. 4.21777 should be 4.21 and not 4.22. How do I do this?
A simple answer:
double x = 4.21777;
double y = Math.floor(x * 100) / 100;
Subtract 0.005 and then round. For example if you just want to print the number you can use a format of %f6.2 and the value x-0.005.
float f = 4.21777 * 100;
int solution = (int)f;
f = solution/100;
This should work ;)
Explanation: By multiplying with 100, you will get 421.777, which, castet to int, is being rounded down to 421. Now divided by 100 returns its actual value.

Rounding a double

Hey guys, I am trying to round to 3 decimal places.
I used the following code.
this.hours = Round(hours + (mins / 60), 3);
But it's not working.
Where have I gone wrong?
Thanks
You can use this function:
public static double Round(double number, int decimals)
{
double mod = Math.pow(10.0, decimals);
return Math.round(number * mod ) / mod;
}
First thing is that all your variables are int so the result of your division is also an int, so nothing to Round.
Then take a look to: How to round a number to n decimal places in Java
If mins is an integer, then mins / 60 will result in an integer division, which always results in 0.
Try changing from 60 to 60.0 to make sure that the division is treated as a floating point division.
Example:
int hours = 5;
int mins = 7;
// This gives 5.0
System.out.println(Math.round(1000 * (hours + (mins / 60 ))) / 1000.0);
// While this gives the correct value 5.117. (.0 was added)
System.out.println(Math.round(1000 * (hours + (mins / 60.0))) / 1000.0);
if mins is an integer you have to divide through 60.0 to get a floating number which you can round
try using like follow
this.hours = Round(hours + (((double)mins) / 60), 3);
You can't. Doubles don't have decimal places, because they are binary, not decimal. You can convert it to something that does have decimal places, i.e. a base-ten number, e.g. BigDecimal, and adjust the precision, or you can format it for output with the facilities of java.text, e.g. DecimalFormat, or the appropriate System.out.printf() string.

Categories