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

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;
}

Related

Dividing float by double vs dividing double by double in java [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 5 years ago.
When I tried the following codes in Java:
System.out.println("0.1d/0.3d is " + 0.1d/0.3d)
System.out.println("0.1f/0.3d is " + 0.1f/0.3d)
I get the following output:
0.1d/0.3d is 0.33333333333333337
0.1f/0.3d is 0.3333333383003871
If float/double should get a double then float/double should be same with double/double in this case.
Just execute the below code to see binary string of number you want to check for:
System.out.println(Long.toBinaryString(Double.doubleToLongBits(0.1d)));
System.out.println(Integer.toBinaryString(Float.floatToIntBits(0.1f)));
Output:
11111110111001100110011001100110011001100110011001100110011010
111101110011001100110011001101
And you see the difference in float bits and double bits. so we can't get the same result for float/double and double/double for a longer precision values .
yes "milbrandt" said right when we are converting float quantity into double by implicit typecasting some information at decimal point will differ. That's why it is showing the different result while dividing float/ double.
As you probably know, double uses 64 bits to store a value but float 32 bits.
To represent significand, double uses 52 bits, and float uses 23 bits. Thus double can give 15 digit precision at most, and float can give 7.
If you do float / double, you actually try to divide a floating point with 7 digit precision at most (far to exact) by a floating point with 15 digit precision at most (closer to exact), and then implicitly typecast the result to a floating point with 15 digit precision. The typecast cannot restore your result from 7 digit precision to 15 digit. Therefore, the results are different though both of them are double.
initialize a double with a float and divide then. You will see the same result.
double f = 0.1f;
double d = 0.1d;
double n = 0.3d;
System.out.println("float /double = " + f/n);
System.out.println("double/double = " + d/n);
result is
float /double = 0.3333333383003871
double/double = 0.33333333333333337
The reason why you see this difference is because you don't have these exact values.
Even if we suppose 0.1d and 0.3d would be exact (which they aren't, what you can see on the result 0.33333333333333337), 0.1f is 0.10000000149011612, which makes the difference.

Division operation is giving me the wrong result [duplicate]

This question already has answers here:
Why does integer division code give the wrong answer? [duplicate]
(4 answers)
Closed last year.
I'm trying to divide one number by another in Processing, and I keep getting the wrong answer.
float a;
a = 3/2;
println(a);
gives me
1.0
when then answer should be 1.5.
Trying a different number,
float a;
a = 2/3;
println(a);
gives me
0.0
when the answer should be 0.666666....
Is there something I'm missing? I looked over the Processing documentation for division and it seems like I'm using the right syntax.
Like others have said, you're using integer division.
Remember that int values can't hold decimal places. So if you do a calculation that would result in decimal places, those values are truncated and you're left with only the whole number part (in other words, the integer part).
int x = 1;
int y = 2;
int z = x/y; //0
int x = 5;
int y = 2;
int z = x/y; //2
You're using int literal values (digits like 2 and 3), and those don't have decimal places, so Processing treats them like int values, and they obey the above rules.
If you care about the decimal places, then either store them in float or double variables:
float x = 1;
float y = 2;
float z = x/y; //.5
float x = 5;
float y = 2;
float z = x/y; //2.5
Or just use float literals by adding a decimal part:
float a = 2.0/3.0;
Processing now knows that these are float values, so you'll keep the decimal places.
Perhaps Processing is interpreting both 3 and 2 as integers. And, since you are dividing one integer by another, it is giving you integer division.
Try changing one or both to 3.0 and/or 2.0 instead.
Your division in interpreted as an integer division and will most probably follow Java integer division rules (since Processing seem to be based on Java).
Java inherits most of its division rules from C, these being explained in more details in a specific question/answer here.

Java percent of number [duplicate]

This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
Is there any way to calculate (for example) 50% of 120?
I tried:
int k = (int)(120 / 100)*50;
But it doesn't work.
int k = (int)(120 / 100)*50;
The above does not work because you are performing an
integer division expression (120 / 100) which result is
integer 1, and then multiplying that result to 50, giving
the final result of 50.
If you want to calculate 50% of 120, use:
int k = (int)(120*(50.0f/100.0f));
more generally:
int k = (int)(value*(percentage/100.0f));
int k = (int)(120*50.0/100.0);
Never use floating point primitive types if you want exact numbers and consistent results, instead use BigDecimal.
The problem with your code is that result of (120/100) is 1, since 120/100=1.2 in reality, but as per java, int/int is always an int.
To solve your question for now, cast either value to a float or double and cast result back to int.
I suggest using BigDecimal, rather than float or double. Division by 100 is always exact in BigDecimal, but can cause rounding error in float or double.
That means that, for example, using BigDecimal 50% of x plus 30% of x plus 20% of x will always sum to exactly x.
it is simple as 2 * 2 = 4 :)
int k = (int)(50 * 120) / 100;
Division must be float, not int
(120f * 50 / 100f)
You don't need floating point in this case you can write
int i = 120 * 50 / 100;
or
int i = 120 / 2;

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.

How to resolve a Java Rounding Double issue [duplicate]

This question already has answers here:
Retain precision with double in Java
(24 answers)
Closed 4 years ago.
Seems like the subtraction is triggering some kind of issue and the resulting value is wrong.
double tempCommission = targetPremium.doubleValue()*rate.doubleValue()/100d;
78.75 = 787.5 * 10.0/100d
double netToCompany = targetPremium.doubleValue() - tempCommission;
708.75 = 787.5 - 78.75
double dCommission = request.getPremium().doubleValue() - netToCompany;
877.8499999999999 = 1586.6 - 708.75
The resulting expected value would be 877.85.
What should be done to ensure the correct calculation?
To control the precision of floating point arithmetic, you should use java.math.BigDecimal. Read The need for BigDecimal by John Zukowski for more information.
Given your example, the last line would be as following using BigDecimal.
import java.math.BigDecimal;
BigDecimal premium = BigDecimal.valueOf("1586.6");
BigDecimal netToCompany = BigDecimal.valueOf("708.75");
BigDecimal commission = premium.subtract(netToCompany);
System.out.println(commission + " = " + premium + " - " + netToCompany);
This results in the following output.
877.85 = 1586.6 - 708.75
As the previous answers stated, this is a consequence of doing floating point arithmetic.
As a previous poster suggested, When you are doing numeric calculations, use java.math.BigDecimal.
However, there is a gotcha to using BigDecimal. When you are converting from the double value to a BigDecimal, you have a choice of using a new BigDecimal(double) constructor or the BigDecimal.valueOf(double) static factory method. Use the static factory method.
The double constructor converts the entire precision of the double to a BigDecimal while the static factory effectively converts it to a String, then converts that to a BigDecimal.
This becomes relevant when you are running into those subtle rounding errors. A number might display as .585, but internally its value is '0.58499999999999996447286321199499070644378662109375'. If you used the BigDecimal constructor, you would get the number that is NOT equal to 0.585, while the static method would give you a value equal to 0.585.
double value = 0.585;
System.out.println(new BigDecimal(value));
System.out.println(BigDecimal.valueOf(value));
on my system gives
0.58499999999999996447286321199499070644378662109375
0.585
Another example:
double d = 0;
for (int i = 1; i <= 10; i++) {
d += 0.1;
}
System.out.println(d); // prints 0.9999999999999999 not 1.0
Use BigDecimal instead.
EDIT:
Also, just to point out this isn't a 'Java' rounding issue. Other languages exhibit
similar (though not necessarily consistent) behaviour. Java at least guarantees consistent behaviour in this regard.
I would modify the example above as follows:
import java.math.BigDecimal;
BigDecimal premium = new BigDecimal("1586.6");
BigDecimal netToCompany = new BigDecimal("708.75");
BigDecimal commission = premium.subtract(netToCompany);
System.out.println(commission + " = " + premium + " - " + netToCompany);
This way you avoid the pitfalls of using string to begin with.
Another alternative:
import java.math.BigDecimal;
BigDecimal premium = BigDecimal.valueOf(158660, 2);
BigDecimal netToCompany = BigDecimal.valueOf(70875, 2);
BigDecimal commission = premium.subtract(netToCompany);
System.out.println(commission + " = " + premium + " - " + netToCompany);
I think these options are better than using doubles. In webapps numbers start out as strings anyways.
Any time you do calculations with doubles, this can happen. This code would give you 877.85:
double answer = Math.round(dCommission * 100000) / 100000.0;
Save the number of cents rather than dollars, and just do the format to dollars when you output it. That way you can use an integer which doesn't suffer from the precision issues.
See responses to this question. Essentially what you are seeing is a natural consequence of using floating point arithmetic.
You could pick some arbitrary precision (significant digits of your inputs?) and round your result to it, if you feel comfortable doing that.
This is a fun issue.
The idea behind Timons reply is you specify an epsilon which represents the smallest precision a legal double can be. If you know in your application that you will never need precision below 0.00000001 then what he suggests is sufficient to get a more precise result very close to the truth. Useful in applications where they know up front their maximum precision (for in instance finance for currency precisions, etc)
However the fundamental problem with trying to round it off is that when you divide by a factor to rescale it you actually introduce another possibility for precision problems. Any manipulation of doubles can introduce imprecision problems with varying frequency. Especially if you're trying to round at a very significant digit (so your operands are < 0) for instance if you run the following with Timons code:
System.out.println(round((1515476.0) * 0.00001) / 0.00001);
Will result in 1499999.9999999998 where the goal here is to round at the units of 500000 (i.e we want 1500000)
In fact the only way to be completely sure you've eliminated the imprecision is to go through a BigDecimal to scale off. e.g.
System.out.println(BigDecimal.valueOf(1515476.0).setScale(-5, RoundingMode.HALF_UP).doubleValue());
Using a mix of the epsilon strategy and the BigDecimal strategy will give you fine control over your precision. The idea being the epsilon gets you very close and then the BigDecimal will eliminate any imprecision caused by rescaling afterwards. Though using BigDecimal will reduce the expected performance of your application.
It has been pointed out to me that the final step of using BigDecimal to rescale it isn't always necessary for some uses cases when you can determine that there's no input value that the final division can reintroduce an error. Currently I don't know how to properly determine this so if anyone knows how then I'd be delighted to hear about it.
So far the most elegant and most efficient way to do that in Java:
double newNum = Math.floor(num * 100 + 0.5) / 100;
Better yet use JScience as BigDecimal is fairly limited (e.g., no sqrt function)
double dCommission = 1586.6 - 708.75;
System.out.println(dCommission);
> 877.8499999999999
Real dCommissionR = Real.valueOf(1586.6 - 708.75);
System.out.println(dCommissionR);
> 877.850000000000
double rounded = Math.rint(toround * 100) / 100;
Although you should not use doubles for precise calculations the following trick helped me if you are rounding the results anyway.
public static int round(Double i) {
return (int) Math.round(i + ((i > 0.0) ? 0.00000001 : -0.00000001));
}
Example:
Double foo = 0.0;
for (int i = 1; i <= 150; i++) {
foo += 0.00010;
}
System.out.println(foo);
System.out.println(Math.round(foo * 100.0) / 100.0);
System.out.println(round(foo*100.0) / 100.0);
Which prints:
0.014999999999999965
0.01
0.02
More info: http://en.wikipedia.org/wiki/Double_precision
It's quite simple.
Use the %.2f operator for output. Problem solved!
For example:
int a = 877.8499999999999;
System.out.printf("Formatted Output is: %.2f", a);
The above code results in a print output of:
877.85
The %.2f operator defines that only TWO decimal places should be used.

Categories

Resources