java 2 different formula problems - java

I want to calculate the volume of a sphere using a Java program. So, I used
double result = 4/3*Math.PI*Math.pow(r,3);
This formula gives the wrong answers it seems.
Like Java program opt 4/3, but if I change it to
double result= Math.PI*Math.pow(r,3)*4/3;
it gives me the correct answer. Does any one know what is going on?

This has to do with the order in which casting occurs in Java (or C for that matter).
For the full details on operator precedence, see http://introcs.cs.princeton.edu/java/11precedence/.
In your first case, since the multiply and divide operators are computed from left to right, the first operation java interprets is 4/3. Since both operands are integer, java computes an integer division, the result of which is 1.
In your second case, the first operation is the double multiply: (Math.PIMath.pow(r,3)). The second operation multiplies a double (Math.PIMath.pow(r,3)) by an integer (4). This is performed by casting 4 to a double and performing a double multiply. Last, java has to divide a double (Math.PI*Math.pow(r,3)*4) by an integer (3), which java performs as a double division after casting 3 to a double. This gives you the result you expect.
If you want to correct your first answer, cast 3 to double first:
4/ (double)3
and you will get the result you expect.

The difference in the outcome is due to operator precedence. In Java, multiplication and division have equal precedence, and therefore are evaluated from left to right.
So, your first example is equivalent to
double result = (4/3)*Math.PI*Math.pow(r,3);
Here, 4/3 is a division of two integers, and in Java, in such cases integer division is performed, with outcome 1. To solve this, you have to explicitly make sure that one or both of the operands is a double:
double result = (4.0/3.0)*Math.PI*Math.pow(r,3);
Your second example, however, is equivalent to
double result = (Math.PI*Math.pow(r,3)*4)/3;
Here, the Math.PI*Math.pow(r,3)*4 part is evaluated to a double, and thus we have no integer division anymore and you get the correct result.

4/3 is a division between two int, so Java assumes that the result is also an int (in this case, this results in the value 1). Change it to 4.0/3.0 and you'll be fine, because 4.0 and 3.0 are interpreted as double by Java.
double result = 4.0 / 3.0 * Math.PI * Math.pow(r,3);

Related

Can you have a half of any array? [duplicate]

I am an experienced php developer just starting to learn Java. I am following some Lynda courses at the moment and I'm still really early stages. I'm writing sample programs that ask for user input and do simple calculation and stuff.
Yesterday I came across this situation:
double result = 1 / 2;
With my caveman brain I would think result == 0.5, but no, not in Java. Apparantly 1 / 2 == 0.0. Yes, I know that if I change one of the operands to a double the result would also be a double.
This scares me actually. I can't help but think that this is very broken. It is very naive to think that an integer division results in an integer. I think it is even rarely the case.
But, as Java is very widely used and searching for 'why is java's division broken?' doesn't yield any results, I am probably wrong.
My questions are:
Why does division behave like this?
Where else can I expect to find such magic/voodoo/unexpected behaviour?
Java is a strongly typed language so you should be aware of the types of the values in expressions. If not...
1 is an int (as 2), so 1/2 is the integer division of 1 and 2, so the result is 0 as an int. Then the result is converted to a corresponding double value, so 0.0.
Integer division is different than float division, as in math (natural numbers division is different than real numbers division).
You are thinking like a PHP developer; PHP is dynamically typed language. This means that types are deduced at run-time, so a fraction cannot logically produce a whole number, thus a double (or float) is implied from the division operation.
Java, C, C++, C# and many other languages are strongly typed languages, so when an integer is divided by an integer you get an integer back, 100/50 gives me back 2, just like 100/45 gives me 2, because 100/45 is actually 2.2222..., truncate the decimal to get a whole number (integer division) and you get 2.
In a strongly typed language, if you want a result to be what you expect, you need to be explicit (or implicit), which is why having one of your parameters in your division operation be a double or float will result in floating point division (which gives back fractions).
So in Java, you could do one of the following to get a fractional number:
double result = 1.0 / 2;
double result = 1f / 2;
double result = (float)1 / 2;
Going from a loosely typed, dynamic language to a strongly typed, static language can be jarring, but there's no need to be scared. Just understand that you have to take extra care with validation beyond input, you also have to validate types.
Going from PHP to Java, you should know you can not do something like this:
$result = "2.0";
$result = "1.0" / $result;
echo $result * 3;
In PHP, this would produce the output 1.5 (since (1/2)*3 == 1.5), but in Java,
String result = "2.0";
result = "1.0" / result;
System.out.println(result * 1.5);
This will result in an error because you cannot divide a string (it's not a number).
Hope that can help.
I'm by no means a professional on this, but I think it's because of how the operators are defined to do integer arithmetic. Java uses integer division in order to compute the result because it sees that both are integers. It takes as inputs to this "division" method two ints, and the division operator is overloaded, and performs this integer division. If this were not the case, then Java would have to perform a cast in the overloaded method to a double each time, which is in essence useless if you can perform the cast prior anyways.
If you try it with c++, you will see the result is the same.
The reason is that before assigning the value to the variable, you should calculate it. The numbers you typed (1 and 2) are integers, so their memory allocation should be as integers. Then, the division should done according to integers. After that it will cast it to double, which gives 0.0.
Why does division behave like this?
Because the language specification defines it that way.
Where else can I expect to find such magic/voodoo/unexpected behaviour?
Since you're basically calling "magic/voodoo" something which is perfectly defined in the language specification, the answer is "everywhere".
So the question is actually why there was this design decision in Java. From my point of view, int division resulting in int is a perfectly sound design decision for a strongly typed language. Pure int arithmetic is used very often, so would an int division result in float or double, you'd need a lot of rounding which would not be good.
package demo;
public class ChocolatesPurchased
{
public static void main(String args[])
{
float p = 3;
float cost = 2.5f;
p *= cost;
System.out.println(p);
}
}

Testing for upper bound violation in Java

I'm trying to use Junit to test a java program, and I'm not sure how to go about testing for upper-bound violations.
Specifically, I have written a simple program to convert between kilometers and miles.
For example, here is the method for converting from miles to kilometers
public static double mileToKm(double mile){
//1.1170347260596139E308 / 0.621371192 = Double.MAX_VALUE
try{
if (mile < 0 || mile > 1.1170347260596139E308){
throw new IllegalArgumentException();
}
else
return mile / 0.621371192;}
return 0;
}
So, I guess my question is two-fold: First, why is it that I can't conjure up an exception when I try
mileToKm(1.1170347260596139E308 + 1)
in junit? I assume it's a rounding issue, but if that's the case then how can I get the exception thrown?
Second, for the method to convert from km to mile, I want to throw an exception if the parameter is greater than Double.MAX_VALUE. How can I pass such a parameter? I can get the Junit test to pass if I just pass as parameter Double.MAX_VALUE * 10, but I also get a message in the Console (this is all in Eclipse Mars 4.5.1, btw) saying 'MAX = 1.7976931348623157E308'. The parameter has to be a double so it can't be BigDecimal or something like that.
OK, I lied, the question is three-fold. What's up with this:
double value = Double.MAX_VALUE * 0.621371192; //max_value * conversion factor
System.out.println(value);
prints 1.1170347260596138E308, but then these two statements
System.out.println(value / 0.621371192);
System.out.println(Double.MAX_VALUE);
print 1.7976931348623155E308 and 1.7976931348623157E308, respectively. In other words, I would expect these two values to both be equivalent to Double.MAX_VALUE, but the first statement has a 5 right before the E, instead of a 7. How can I fix this? Thanks so much, hope this isn't too prolix.
You're confused about floating point numbers.
Firstly, the number 1.1170347260596139E308 + 1 is not representable using primitives in Java, as doubles have ~16 significant digits, and that addition requires 308 significant digits.
Secondly, float/double operations are not idempotent if you use intermediate storage (and most of the times even without it). Floating point operations lose accuracy, and arithmetic methods that retain accuracy over large computations (think weather models) are sought after in the scientific sector.
Thirdly, there's Double.MAX_VALUE, which represents the largest representable number in a primitive in Java; the only other value X such that X > Double.MAX_VALUE can hold is Double.POSITIVE_INFINITY, and that's not a real number.

Java: Variable assignment issue

just a quick question and I'm probably gonna feel stupid for asking but still would like to know why it is so...!
Anyways, quick example:
x is a double.
double conversion = (x-32)*5/9;
This does the maths just fine.
double conversion = (x-32)*(5/9);
This isn't fine because the (5/9) is being treated as an int, thus result is overall 0.
double conversion = (x-32)*(5f/9f);
This does the maths just fine, as it explicitly makes the 5/9 values a float.
So my question is: Why does the first equation work perfectly fine? ( double conversion = (x-32)*5/9; )
Why isn't the 5/9 being made a 0 if it were an int supposedly? What makes the 5/9 different from (5/9) ?
The difference is between whether you do the multiplication first or the division first - and what the types of those operations are.
This:
(x - 32) * 5 / 9
is equivalent to:
((x - 32) * 5) / 9
So if the type of x is double, then the type of x - 32 is double, so the 5 is promoted to double, the multiplication is done in double arithmetic, giving a double result, and then the division is also done in double arithmetic.
Even if x is an integer type, you're doing the multiplication first, which will presumably give you a value bigger than 9 (in your test case), leaving you with a non-zero result. For example, if x is 45, then x-32 is 13, (x - 32) * 5 is 65, and the overall result is 7, then converted to 7.0 on assignment. That's not the same result you'll get if x is a double with the value 45.0, but it's still better than multiplying by 0...
You basically answered your own question. Evaluation order makes all the difference.
basic left to right evaluation results in different type casting than your explicit evaluation order in your second example
Assuming x is a double then your first equation divides a double by an integer due to order of operations.
(x-32) = y-> y*5 = z -> z/9
at each stage a double is being operated on, overriding integer arithmetic.
It is the order it's done in.
If you multiply by 5, you get a large number. If you then divide by 9, you still get an int,
But the remainder is discarded.
The reason is the order of the operations.
(x-32)*5/9 makes first (x-32)*5 and then divides the result by 9
(x-32)*(5/9) makes first (x-32) and (5/9). After both results are multiplied.
Your value of x might be double and it is making entire equation in double because brackets execute first.
It's a matter of when the conversion takes place. 5/9 consists of one 5 and one 9 (both ints) being divided with integer division. If either is a float (5f/9 or 5/9f) they will divide as floats.

Java: Is (int) double reliable?

When I perform simple math in java with doubles and other number data types, the double values seem to randomly vary a bit from the supposed result, which might be 5,59999999997 or 6,0000000002 or something. When I cast to int, the double value is obviously rounded down to the next whole number. Does this mean the double could be both 5 or 6? Or does that "5,999999999997" still count as 6 though which would be depending on the binary float value? If not, is there a way to let the negative vary be rounded up, but not lower values from 5,5 to 5,999999999996?
I mean, I dont really want to round the value as described in my last sentence. I'd like to always round down to the next whole number, but I don't want to cause an extra decrement due to wrong double math results.
Converting a double to an int always rounds down. You can round to the nearest whole integer via Math.round(double). The double is varying from what you expect because of floating point error.
If you want to round, you can use the round() method.
double d = 6 +/- some small error
long l = Math.round(d);
Or you can add 0.5 for positive numbers
long l = (long) (d + 0.5);
or
long l = (long) (d + (d < 0 ? -0.5 : 0.5));
I'm not sure I understand the question. Usually when you cast a double to int you add 0.5 to have a nice round.
From the Java Language Specification:
The Java programming language uses round toward zero when converting a floating value to an
integer (ยง5.1.3), which acts, in this case, as though the number were truncated, discarding
the mantissa bits. Rounding toward zero chooses at its result the format's value closest to
and no greater in magnitude than the infinitely precise result.
So 5,999999999997 when casted to an int will 5 and 6,0000000002 will be 6. If I understand what you are asking with having negative versions of the values (e.g. -5.97), I fail to see how
Math.round() does not suffice you. -6,0000000002 will be rounded to -6 as will -5,999999999997 and every other value above (but not including) -5.5.

Not sure why programme returns an int

Ok so basic question here.
double test = 1/3 * 3.14;
I realize that you need to do (1.0/3) in order to get the actual double number. But what I am wondering is why. I would have thought that since you are multiplying by 3.14 this would make it a double.
So am I correct in thinking that whenever two values are used in an arithmetic equation, regardless of what is happening around them, if they are integers then you will get an integer value?
ie. x/y * z
while x is divided by y that is all that the programme cares about and if they are both integers you will get an integer value back? It is only when you multiply it by z (3.14) that it becomes a double.
Evaluation occurs from left to right when two operators have equal precedence. * and / have equal precedence.
1 / 3 * 3.14 evaluates 1 / 3 first. Both operands are int, the first operation is integer division, and the result is an int.
Next, result * 3.14 is evaluated. One operand is an int, the other operand is a double, and we have mixed types. Java does us a favor and casts the int to a double to preserve accuracy. Floating point division occurs, and the result is a double.
With operators of equal precedence, the associativity takes over. These operators / and * are left-associative, which means that the order of operations proceeds from left to right.
So, 1/3 happens first, and integer division happens before the 3.14 has a chance to promote them to doubles.
Because according to the rules of arithmetics, 1/3 is calculated first. Since it's 2 integers, it's an integer division, resulting in 0. Afterwards you have a double calculation, but the error has already happened.
My understanding is that this has to do with autoboxing in java. Java assumed that the 1/3 is dividing two ints so you'd get an int back (casted into a double).
If you did 1/3D, you'd get 0.33333333 back

Categories