Below is the code and I wanted to know why it gives an output of 2.0 instead of 0.0?
class Main {
public static void main(String[] args) {
double x = 5*4/2 - 5/2*4;
System.out.println(x);
}
}
Because 5/2 is 2 not 2.5. 5 and 2 is integer and / operator generates int.
Integer division truncates any decimal places. You are probably expecting 5/2*4 to equal 10, but it is actually resolving to 8.
This can be solved by writing your numbers like this:
double x = 5.0*4.0/2.0 - 5.0/2.0*4.0;
Simply storing the result in a double does not force the actual arithmetic to consider the values to be doubles.
You're working with integers. So 5/2*4 equals 8.
Related
I am dividing two ints x/y,. Say 3/2. Then one would get 1 as result though the actual result is 1.5. Ok this is obvious as it's int division. But I want 1.5 to be rounded off to the next highest int not the immediate lowest. So 2 is desired as result. (One can write simple logic using mod and then division... But am looking for simple Java based API). Any thoughts?
You can, in general, write (x + y - 1) / y to get the rounded-up version of x/y. If it's 3/2, then that becomes (3 + 2 - 1) / 2 = 4 / 2 = 2.
You can use the ceil (ceiling) function:
https://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#ceil(double)
That will essentially round up to the nearest whole number.
If you can change the datatype to double, following is the best solution -
double x = 3;
double y = 2;
Math.ceil(Math.abs(x/y));
This will give you 2.0
import java.lang.Math;
//round Up Math.ceil(double num)
//round Down Math.floor(double num)
public class RoundOff
{
public static void main(String args[])
{ //since ceil() method takes double datatype value as an argument
//either declare at least one of this variable as double
int x=3;
int y=2; //double y =2;
//or at least cast one of this variable as a (double) before taking division
System.out.print(Math.ceil((double)x/y)); //prints 2.0
//System.out.print(Math.ceil(x/y));
}
}
I was using BigDecimal, but I am still getting different results for two different (mathematically identical) expressions:
First Expression: PI - (10^(-14)/PI)
Second Expression: (PI^2 - 10^(-14))/PI
To put it more simply, here is the equation:
package set1;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class FloatingLaws {
final static BigDecimal PI = BigDecimal.valueOf(Math.PI);
public static void main(String[] args) {
System.out.println(firstExpression());
System.out.println(secondExpression());
}
private static BigDecimal secondExpression() {
return PI.subtract((BigDecimal.valueOf(Math.pow(10, -14)).divide(PI,50,RoundingMode.CEILING)));
}
private static BigDecimal firstExpression() {
return (PI.multiply(PI).subtract(BigDecimal.valueOf(Math.pow(10, -14)))).divide(PI, 50,RoundingMode.CEILING);
}
}
After executing this code, no matter how big is rounding, last digit is always different. In my case I get these two results:
3.14159265358978981690113816209304300915191180404867
3.14159265358978981690113816209304300915191180404866
My question is why is this happening and is it solvable?
It is because You are doing this:
pi - ((10^-4)/pi)<- only the part in bracket is ceiled,
which is different from
((pi^2-10^-14)/pi)<- where the whole expression is ceiled.
You use BigDecimal and you have rounding mode CEILING with precision 50. In both of your expressions the ceiling is applied when you divide by PI number. So if you divide by PI eager like in first expression, then you could get less accurate results - because you CEIL intermediate value, before your formula fully execute, so you loose the CEILED part from the divide by PI operation and this in further computation creates the "error" effect.
When you divide by PI last, like in second expression, you use more accurate formula, which is ceiling only the result, not intermediate value like in first expression, so it calculates more preciselly, rounding only the result and not intermediate value.
The BigDecimal.subtract method always produces exact difference between two BigDecimal numbers, without rounding. On the other hand BigDecimal.divide usually rounds the result. In your case you are use CEILING rounding mode which rounds up (towards +infinity). When you calculate a-ceil(b/a), you are essentially rounding down the whole result (assuming that a is already rounded), while calculating ceil((a*a-b)/a) you're rounding up. That's why firstExpression() is bigger. Were you using HALF_EVEN rounding, the result would be the same. Were you using FLOOR mode, the result would be opposite.
Also take a look to what is BigDecimal.valueOf(Math.PI);:
System.out.println(BigDecimal.valueOf(Math.PI));
> 3.141592653589793
It's not even close to the actual PI number (given the fact that you need 50 digits). You should define PI explicitly like this:
final static BigDecimal PI = new BigDecimal("3.14159265358979323846264338327950288419716939937510");
Now the result is the following:
3.14159265358979005536378154537278750652190194908786
3.14159265358979005536378154537278750652190194908785
Which is quite different from yours one.
I modified your program to try all rounding modes java knows.
Running under oracle jdk 8.72, i get equal results for the rounding modes HALF_UP, HALF_DOWN and HALF_EVEN. But Krzysztof is right, since you are not rounding in the same places, errors are bound to pop up.
public class FloatingLaws {
final static BigDecimal PI = BigDecimal.valueOf(Math.PI);
public static void main(String[] args) {
for (RoundingMode roundingMode : RoundingMode.values()) {
System.out.println(roundingMode);
System.out.println("Equal? "+firstExpression(roundingMode).equals(secondExpression(roundingMode)));
System.out.println(firstExpression(roundingMode));
System.out.println(secondExpression(roundingMode));
}
}
private static BigDecimal secondExpression(RoundingMode roundingMode) {
return PI.subtract((BigDecimal.valueOf(Math.pow(10, -14)).divide(PI, 50, roundingMode)));
}
private static BigDecimal firstExpression(RoundingMode roundingMode) {
return (PI.multiply(PI).subtract(BigDecimal.valueOf(Math.pow(10, -14)))).divide(PI, 50, roundingMode);
}
}
I've been working on an interview question for 1.5 hours and could not find the bug in my Java program.
And then I found what the problem was, which I don't understand (don't pay attention to the values, there were others, it's about the types):
int size=100;
Integer a=12;
if(a >= size/10)...
//didn't work
is different than
if(a >= size*0.1)...
//worked
I understand that there is a conversion, but still, how is it possible that with a=12, if(a>=size/10) returns false?
Why is that?
/10 is integer division. While *0.1 first converts the first operand to a double and performs a floating point multiplication.
If you use the /10, and the operand is 14, it will result in 1 indeed, 14/10=1.4 but integer division rounds this down. Thus 29/10=2.
If you use *0.1, the Java compiler will first convert the value of size to a double, thus 14.0 and then muliplies it with 0.1 resulting in 1.4.
On the other hand it's not all beaty that comes out of floating points. float and double can't represent every integer, and round off after computation.
For the given values for size however, it will result in the effect because 100 is a multiple of 10 and a float or double is capable of representing any integer value in the range from zero to hundred.
Finally /10 is not always an integer division: if the first operand is a floating point (e.g. 14.0d/10), the compiler will convert this to a floating point division.
Short version:
int/int is an integer division that rounds down to the nearest (lower) integer.
int*double is a double multiplication that - with rounding off errors - results in the floating point value, nearest to the correct result (with decimal digits).
I just tested here:
public class a {
public static void main(String[] args) {
int size = 100;
int a = 12;
System.out.println((a >= size / 10) ? "OK" : "Failed?");
}
}
And it worked. I don't think this is your real problem. Probably it's in another part of your code.
I have a simple java program that does not operate the way that I think it should.
public class Divisor
{
public static void main(String[] args)
{
int answer = 5 / 2;
System.out.println(answer);
}
}
Why is this not printing out 2.5?
5 / 2 is integer division (you're even storing it in an integer variable), if you want it to be 2.5, you need to use floating point division:
double answer = 5.0 / 2.0;
Integer division is always going to be equal to normal mathematical division rounded down to the nearest integer.
Java has integer division which says: integer divided by integer results in integer. 2.5 cannot be represented with integer so the result is floored to 2.0. Moreover, you store the result in integer.
If you need floating point division you can cast one of operands to double and change answer type to double as well. You use literal values here, so changing 5 to 5. makes this literal value double.
In the end the following should work for you:
double answer = 5. / 2;
Note, you don't even need a zero sign after a dot symbol!
I came across the following program
class Boolean {
public static void main(String argv[]) {
boolean x;
x = 4.4f == 4.4;
System.out.println(x);
}
}
The output of the following program is false
But if we write the program in the following fashion, then
class Boolean {
public static void main(String argv[]) {
boolean x;
x = 4.5f == 4.5;
System.out.println(x);
}
}
In this case the output is true
Can somebody explain me why ??
You generally shouldn't compare floating point values with == operator. You should use 'close enough' comparison like checking if values differ by some small value:
double epsilon = 0.000001
boolean equal = Math.abs(value1-value2) < epsilon
In your example, 4.4f is not equal to 4.4, because java defaults floating point values to double type, which is 64bit, and to compare them java casts 4.4f to double, which causes it to be slightly different from original double value 4.4(because of problems representing decimal fractions with binary).
Here's a good link on floating point numbers.
The problem is that computers like numbers to be based on base 2 and not base 10 like us.
4.4 is an infinite fraction (like 0.333333333... for us) in binary, and floats have fewer digits than doubles, so there are fewer digits in 4.4f than in 4.4 making them different.
4.5 is not an infinite fraction.
Note: Whenever you need to compare floats or doubles you should always check the size of the difference, not just check for equality.
Run this code to see how casting of float to double works for these cases
NumberFormat nf = new DecimalFormat("0.00000000000000000000");
System.out.println(nf.format(4.4f));
System.out.println(nf.format(4.4));
System.out.println(nf.format(4.5f));
System.out.println(nf.format(4.5));
That is because of a rounding error when the double gets truncated to a float. Sometimes you get it sometimes you won't.
4.4f is a float and 4.4 is a double.
Your prgramm compares a 16-bit float with 32-bit double value. Internaly it is represented a IEEE754 so the difference is a rounding error which leads in some cases to this inequality due to different precision.
This is down to the fact that a float is a not a double and you can't easily do direct comparison, because a float is just an approximation. Take a look at the following code:
public static void main(String args[]) {
double a, b;
a = 4.4f;
b = 4.5f;
System.out.println("4.4f implicitly cast to a double = "+a);
System.out.println("4.5f implicitly cast to a double = "+b);
}
You'll see that 4.4f, when implicitly cast to a double is in fact 4.400000095367432.
In addition to what everyone has said, here is a very popular example to demonstrate this thing with floating point operations.
System.out.println(0.3 - 0.2 - 0.1);
It won't print 0. In fact, it would print a very small number as a result of the truncation errors that happen in floating point operations when certain fractions are non-terminating repeating in the binary representation.