How does int work in Java math equations? - java

I've been reviewing my Java for a class I've taken for the whole year and haven't been doing well on. They have a separate review book called "Be Prepared." I want to see if I get the math behind this line.
result = (1 / 2) * n * (n + 1); // result is 0.0
The thing is, this is basic basic basic. I need to know if I'm actually getting this. It looks like my like (1/2) is 0.5. That cast to an int is 0. That's why the whole thing is 0.0.
Am I right?
This book is how you get ready for the AP test. Anyone done eimacs who can help?

(1 / 2) will return zero. both are integer and as per integer calculation it will return zero.
Try
result = (1.0 / 2) * n * (n + 1);
Please have a look at :
Division of integers in Java
How do math equations work in Java?
In Java the result of each operation is decided by the higher type involved in calculation. It doesn't matter in what type are you assigning the result.
for e.g
double d = 10/3;
the value of d will be 3.0 only not 3.33.

Yes, and note that 999 / 1000 will also return 0. It's truncation, not rounding down.

Related

NaN error JAVA when multiplying by 0

I really can't understand why this expression gives me a NaN error only when
acceleration.module - Ambient.friction = 0
:
double x = (speed.module * speed.direction.x()) + ((acceleration.module-Ambient.friction) * acceleration.direction.x())*time;
Moreover if I add pharentesis like these:
double x = ((speed.module * speed.direction.x()) + ((acceleration.module-Ambient.friction) * acceleration.direction.x()))*time;
it gives me a NaN error again.
In the first, the second value is multipled by time.
double x = (speed.module * speed.direction.x()) + ((acceleration.module-Ambient.friction) * acceleration.direction.x())*time;
For the other, the whole thing is multiplied by time:
double x = ((speed.module * speed.direction.x()) + ((acceleration.module-Ambient.friction) * acceleration.direction.x()))*time;
This makes me think you are overflowing the double values in the second one before you multiple with time. With double overflow you get the magic values Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY
Most likely you are multiplting time with Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY and the result is NAN.
Change the calculations to a series of steps. With each step, check the result for overflow, by looking for Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY. That will tell you where things go off the rails. You are almost certainly overflowing somewhere, but we cannot see the numbers you are handling so I cannot tell you exactly where.
My (educated) guess is the nan is already in the direction because it will be indeterminate when module is zero

Can anyone tell me why this is evaluating to 0?

Working on a Java class, its making me crazy because this expression is evaluating to zero, I need it to evaluate to a double, then round it down to the nearest int. So what Im trying to get is for days to be a whole number of days, yet when I run it through java it evaluates to 0. When I run it through my calculator it evaluates to the correct value. I would love a fix and an explanation to why this what I already have isn't working.
public int getEventDays(){
//variables
double daysCalc;
int days;
//logic
if (getStatus().equals("filling")){
//this is indented less to fit everything on one line, its not this way in
//the fractions are for unit conversion
daysCalc= Math.floor(((capacity-storage)/(inflow-outflow))*(43560)*(1/3600)*(1/24));
days = (int)daysCalc;
}
else if (getStatus().equals("emptying")){
//this is indented less to fit everything
//the fractions are for unit conversion
daysCalc=Math.floor(((storage-0)/(outflow-inflow))*(43560)*(1/3600)*(1/24));
days = (int)daysCalc;
}
else{
days = -1;
}
return days;
}
Change your code to this :
daysCalc = Math.floor(((storage-0)/(outflow-inflow))*(43560)*(1.0/3600)*(1.0/24));
Explanation:
The right hand expression is returning an integer value. In your case, 1/3600 is rounded to 0, similar to the case of 1/24.
Now by using 1.0 instead of 1, it is giving the unrounded float value of 1/3600.
Your problem is connected with the order of operations within your expression. The parentheses around 1/3600 and 1/24 cause these expressions to be evaluated first - and since each of these divisions has an expression of integer type on either side of the division, it's treated as an integer division. In other words, 1/3600 and 1/24 are both evaluated as integers, to give a result of zero. This means that your arithmetic includes a couple of multiplications by zero, which is why your result is zero.
The simplest fix is to understand that multiplying by the reciprocal of some number is the same as dividing by that number. In other words, you could simplify the calculation to
daysCalc = Math.floor( storage / ( outflow - inflow ) * 43560 / 3600 / 24 );
which will give the correct result, provided storage, outflow and inflow are not all integers.
On the other hand, if storage, outflow and inflow are all integers, then you'll need to make sure that the first division is also not treated as an integer division. You could do this by writing
daysCalc = Math.floor((double) storage / ( outflow - inflow ) * 43560 / 3600 / 24 );
which forces the division to be done with floating point arithmetic; and thereafter, each one of the divisions is done in floating point.

Math.cos not working

This bit of my program is supposed to calculate bottomAngle using cosine rule.
public double bottomAngle() {
topAngleinRadians = Math.toRadians(topAngle) ;
return (Math.cos(topAngleinRadians)(bottomAngle() = ladderLength^2 + floorLength^2 - verticalHeight^2) / 2 * ladderLength * floorLength) ;
}
Errors produced:
Here is my list of errors and I can't figure it out what's wrong with my formula. All the methods such verticalHeight , ladderLength works perfectly fine in other methods. There is something wrong with the way I put this formula. Can you please help me out?
Without seeing your list of errors, you do have syntax errors:
return (Math.cos(topAngleinRadians)(bottomAngle() = ladderLength^2 + floorLength^2 - verticalHeight^2) / 2 * ladderLength * floorLength);
You have no operator between your call to Math.cos() and the next part of your expression.
You're also appear to be assigning values to a function call, which doesn't make sense.
The ^ operator is also not the exponential operator, but a bitwise exclusive OR operator. You're probably looking for Math.pow().
Those are just what I'm seeing right off the top. It might be helpful to read up about the Java operators and how they are evaluated.
There's a few issues here.
Multiplication - unlike in regular algebra, you have to explicitly define that you want multiplication between two expressions Math.cos(topAngleinRadians)*...
Assignment - you appear to be trying to assign something to a method call (bottomAngle() = ...). This is not really something you can do, and I'm not really sure what you are trying to achieve by it.
Squaring - 10^2 does not square 10 into 100 in java, but is rather the XOR (exclusive OR) operator. You probably want to use Math.pow(ladderLength, 2) or simply ladderLength * ladderLength
Unlike algebraic notation, Java parentheses do not implicitly multiply.
You need to insert a * between )(.
Can't really understand the purpose of your return statement, but I would rather break the statement into 2-3 lines to make it more readable: -
public double bottomAngle() {
topAngleinRadians = Math.toRadians(topAngle) ;
double bottomAngle = Math.pow(ladderLength, 2) + Math.pow(floorLength, 2) -
Math.pow(verticalHeight, 2);
double denom = 2 * ladderLength * floorLength;
double numerator = bottomAngle * Math.cos(topAngleinRadians);
return numerator / denom ;
}
Note that, 3 ^ 2 does mean 3 squared in Java. You would need Math.pow method for that.
Also, you need to check why you were having bottomAngle() method call on LHS. I have assumed it to be a temp variable here.
As you can see, your code looks much more readable. And it becomes easy to find out compiler errors.
Your sytnax is incorrect. Parenthesis do not mean mutliplication, you need explicit * (multiplication operator). Also, you have some other mistakes:
Math.cos(topAngleinRadians)(bottomAngle() = ladderLength^2 + floorLength^2...
this looks like a method call i.e. bottomAngle() being set equal to some other expression, this is invalid also..

How to calculate integer expression in Java

Suppose, I need to calculate 3 * (2 / 3) = 2 but 3 * (2 / 3) = 0 in integer arithmetic. So, it looks like I should use floating-point arithmetic 3 * (2.0 / 3) = 2.0 and cast the floating point result to int.
Does it make sense? How would you avoid casting here?
In this particular example, you may be better off rearranging the expression as 3 * 2 / 3, or as 3 / 3 * 2. This way you'll get the exact result using integer math alone.
Using floating-point math is the more general solution, but you need to be aware of rounding issues. In general, you shouldn't expect that x * (y / x) would give you exactly y when x and y are floating-point numbers.
If you know that the result is an integer, or simply want to round it to the nearest integer, you could use Math.round():
Math.round(3 * (2f / 3))
Simply casting the result to int is not a good idea since floating-point numbers are inexact, and such a cast would simply truncate the number.
You can't avoid casting. You can either use integer division or you can use full division but then arguments and result will be in floating point.
You can try moving around the expression parts to bring out the integer division to the top level. In your case you could transform 3 * (2 / 3) to (3 * 2) / 3 which will result in 2 without any floating point operations.
* and / have the same precedence, so omitting the parentheses will provide you with a correct result of the example.
Casting (or truncating) is unavoidable otherwise.
Personally I would re-arrange the equation to be:
3 / 3 * 2 = 2
But not sure if thats what you need. You could try doing the calculation on float's and then use round() to round it up or down to the nearest integar.
This is because of the integer division. In these kinds of expressions you are better off using float, yes.
You can avoid the explicit casting only if you are using the compound operator. The compound operator does an automatic cast for you.
int a = 3;
a *= (2.0/3);
System.out.println(a);
What exactly is it you want to achieve? Using integer arithmetic the result depends on where you set you parentheses. (a/b) * (c/d) * (e/f) will, as you noticed yourself, in general result in something different than (a*c*d) / (b*d*f), even though mathematically both expressions are equal. Nontheless both expressions may be correct depending on the task you want to solve. I do miss a clear statement of this.
If you are looking for the integer closest to the mathematically correct value just calculate nominator and denominator seperately and then perform the division. This way intermediate errors do not occur. If not you need to reformulate your question.

Why is it that when I have X(long) / (Y*Y*Y)(long) I get Error: Divide by Zero?

In my example X is already long and Y is a long also. I am not casting at then.
I really just want to divide by a number that is cubed. (using native libraries)
These numbers are extremely large. If I convert them to floats and do it, its value is Infinite...
System.out.println(formatter.format("%20d", (X/(Y*Y*Y))));
Y is an extremely large number, it is not 0. X is a measurement of time in milliseconds.
I will post the exact code in a short while if this question doesn't get closed... I don't have access to it right this minute.
Context: I am dealing with a big notation calculation for O(n^3).
Error: "Exception in thread "main" java.lang.ArithmeticException: / by zero"
Answers:
Assuming you didn't really mean the quotes, the likely reason is that
Y * Y * Y is greater than 2 ^ 31. It's overflowing, with a lower part
of 0. I believe this would only happen if Y is a multiple of 2^11
(2048) - but I'm not certain*
-This is the case for me, Y is a multiple of 2048, hopefully this helps with trying to find a solution.
// Algorithm 3
for( int n = 524288; n <= 5000000; n *= 2 ){
int alg = 3;
long timing;
maxSum = maxSubSum3( a );
timing = getTimingInfo( n, alg );
System.out.println(fmt.format("%20s %20d %20d %20d %20d %20s%n", "Alg. 3", n, timing, timing, timing/(n*n), "time/(n*log(n))"));
}
Assuming you didn't really mean the quotes, the likely reason is that Y * Y * Y is greater than 2 ^ 31. It's overflowing, with a lower part of 0.
I believe this would only happen if Y is a multiple of 2^11 (2048) - but I'm not certain.
It can be avoided by making sure that the computation of Y^3 is done using some datatype that can hold it. If it's less than 2 million, you can use a long instead. If not, you'll have to either use a double or a BigInteger. Given that your other value is in milliseconds, I'd guess that floating point would be fine. So you'd end up with:
System.out.println(formatter.format("%20d", (int)(X/((double)Y*Y*Y))));
You may want to use floating point for the output as well - I assumed not.
Surely you don't mean to pass "(X/(Y*Y*Y))" as a string literal? that's a string containing your express, and not compilable Java code that expresses a computation that Java will perform. So that's problem #1: remove those quotes.
Second, the formatter has nothing to do with dividing numbers, so that is not relevant nor your problem.
Third, casting has nothing to do with this. Your problem is exactly what it says: you're dividing by zero. I assume you don't want to do that. So, Y must be 0.
Fourth, nothing here uses native libraries. It's all Java. Right, that's what you mean?
You may want to use BigInteger to perform math on very large values that overflow a long. But, that will not make division by zero somehow not be division by zero.
Perhaps you should try, either with long or float conversions:
( ( X / Y ) / Y ) / Y
If Y is a high enough power of 2 (2^22 or more), then Y^3 will be a higher than 2^64 power of 2. And long uses 64 bits in Java, isn't that correct?

Categories

Resources