How do math equations work in Java? - java

When I do something like this
int test = 5 + 3 * (4 - 1) / 2;
I get 9. I suspected this was because int rounds down. However, when I do this
float test = 5 + 3 * (4 - 1) / 2;
I also get 9. However, when I do this
float test1 = 5;
float test2 = 4.5;
float test = test1 + test2;
Test finally outputs 9.5. Could someone explain the logic behind this? Why don't I get 9.5 in the second example? Thanks.

In your second example, although you are assigning the result to a variable of type float, the calculation itself is still performed exactly the same way as the first example. Java does not look at the destination variable type to determine how to calculate the right hand side. In particular, the subexpression 3 * (4 - 1) / 2 results in 4.
To fix this, you can use floating point literals instead of all integers:
float test = 5 + 3 * (4 - 1) / 2.0f;
Using 2.0f triggers floating point calculations for the arithmetic expression.

Although you represent the result of 5 + 3 * (4 - 1) / 2 in a float, the actual evaluation is done with the precision of an integer, meaning that the division of 9 / 2 returns 4 rather than the 4.5 you would receive if they were evaluated as floats.

Expressions have their own type. So start with:
5 + 3 * (4 - 1) / 2
Each value has its own type. This type happens to be int, so this is the same as:
((int)5) + ((int)3) * (((int)4) - ((int)1)) / ((int)2)
Making it clearer that we're dealing with ints. Only after this is evaluated as 9 does it get assigned to a float.

The short answer is that integer types operate on modular arithmetic, with modulus 1, and discard the remainder.
Since you cast test as an integer, modular arithmetic is employed with modulus 1 (e.g. 9.5 mod 1),
int test = 5 + 3 * (4 - 1) / 2;
With a 32-or-64 bit float this would give 9.5; however, because you have cast test as an int, the remainder is discarded, and the value referenced by test is 9.

Related

Android Math Calculation Not Giving Expected Value

I'm trying to run a calculation but I'm not getting the correct result and struggling to understand why.
Calculation
float Signal = ((20 - 0) / (20 - 4)) * (F5 - 4) + 0;
F5 = 12 and is declared as a "Float" type
When run through a calculator, you end up with the following:
((20 - 0) / (20 - 4)) * (12 - 4) + 0
((20) / (16)) * (12 - 4) + 0
(1.25) * (8) + 0
Result = 10
However, when this is run through the Android code, I get the result of 8.
Why is this, I'd like to understand what's going on
The first term ((20 - 0) / (20 - 4)) is calculated using integer arithmetic, giving a value of 1. This makes the final result 8 regardless of the type of F5. If you want it to happen in floating point, use floating point constants
float Signal = ((20f - 0f) / (20f - 4f)) * (F5 - 4f) + 0f;
Technically you don't need all the constants to be floats due to numeric promotion, but it is much clearer to those reading your code that you intended for everything to be a float.

Why are the outcomes of the two calculations different? [duplicate]

This question already has answers here:
The accuracy of a double in general programming and Java
(2 answers)
Division of integers in Java [duplicate]
(7 answers)
Closed 6 years ago.
I have the following two calculation using Math.round(...):
double x = 0.57145732;
x = x * 100;
x = Math.round(x * 10);
x = x / 10;
If I now print the value of x it will show me: 57.1.
double x = 0.57145732;
x = (Math.round((x * 100) * 10)) / 10;
// x = (Math.round(x * 1000)) / 10; //Also gives me 57.0.
If I now print the value of x it will show me: 57.0.
Why is there this difference in the outcome?
The Math.round() method returns an integer (of type long - as pointed out by Ole V.V). It's usually thought to return a float or double which gives rise to confusions as these.
In the second calculation,
Math.round((x * 100) * 10)
returns 571. Now, this value and 10 both are integers (571 is long, 10 is int). So when the calculation takes the form
x = 571 / 10
where x is double, 571/10 returns 57 instead of 57.1 since it is int. Then, 57 is converted to double and it becomes 57.0
If you do
x = (double)Math.round((x * 100) * 10) / 10.0;
its value becomes 57.1.
Edit: There are two versions of the Math.round() function. The one you used accepts a double (since x is double) and returns long. In your case, implicit type casting spares you the trouble of considering the precise little details.
The reason of the difference is that in the second formula you're making a division of two integer. in order to have the same result you have to add a cast to double:
double x = 0.57145732;
x = (double)(Math.round((x * 100) * 10)) / 10;
The difference is between
x = Math.round(571.45732) / 10;
and
x = Math.round(571.45732);
x = x / 10;
Since round(double) returns a long, in the first case you divide a long by an int, giving the long 57. Converting back to double leads to 57.0. The second case is equivalent to
x = ((double)Math.round(571.45732)) / 10;
where a double is divided by an int, resulting in 57.1.
This because Math.round() returns an int. If you do this step-by-step (as in the first example), you assign the result of Math.round() to a float value. The following calculation uses then a float division.
In the second example, you let the JVM decide which types to use (and it uses an integer division as the intermediate step). This is why the precision gets lost.

Why does % round up

So today at school, we were learning some of the math classes in java, but I don't particularly understand this why it automatically rounds from -11.87 to -12.
import java.util.*;
public class println{
public static void main (String [] args){
System.out.println(8 % 3 / 15 - 12);
}
}
It does not "round up". The steps done here are pretty simple:
8%3 is evaluated. the modulo operator % returns the rest of the integer-division 8/3 (so it returns 2)
2 / 15 is evaluated. Both 2 and 15 are integers (int) in java. Integer division will cut off any decimal places. So this expression will be evaluated to 0!
0 - 12 is evaluated. Result is -12
The reason for this is that all of the numbers you provided in the expression are in the form of non floating point numbers. Because of this, the JVM does not process the expressions with floating point numbers.
8 % 3 = 2
2 / 15 = 0
0 - 12 = -12
This is how the operation actually proceeds due to the fact that none of the numbers are floating point numbers (e.g. double).
In order to understand this, you should understand the structure of integer and double in Java. For example, if you code like that, it will not "round up".
public class println {
public static void main(String[] args) {
System.out.println(8.0 % 3.0 / 15.0 - 12.0);
}}
Because, the numbers, you used are integers (without any decimal). If you give the numbers in double form, the program gives you the exact result, which is -11.866666666666667.
Your expresion is ugual at this:
System.out.println(((8 % 3) / 15) - 12);
First evaluated
(8 % 3) = 2
And
(2/15) = 0
And finally
0-12 =-12

Data values and types

Given:
int x = 10;
double d = -3.0;
boolean f = false;
1.
Why does the following remain a double after it is cast as an int... For the second one also, why does it output a float when defined as a long?:
(int) d / 2.0
(long) d * 2f
2.
Why does the first of the following print a string(?), and the latter a number?
"2" + x + 2
"3" + 3 * x
But then there is an error with the following:
"5" + i + 2
3.
Also, with the follwing, what is actually happening and what is the result?
d++ + d
4.
When Math.round is used, why does it convert the following double into a float, or are they the same thing?
Math.round(x / d)
1.
This:
(int) d / 2.0
is the same as this:
((int) d) / 2.0
Perhaps you meant this?
(int)(d / 2.0)
2.
They both "print" strings (assuming you're talking about using them as the argument to System.out.println).
These:
"2" + x + 2
"3" + 3 * x
are the same as these:
("2" + x) + 2
"3" + (3 * x)
which are the same as these (assuming x = 10):
("2" + 10) + 2
"3" + 30
which are the same as these:
"2102"
"330"
3.
I can't remember what should happen here. But you should never need/want to write code like that, so it doesn't matter!
4.
The return type of Math.round is an integer type, not a floating-point type.
Why does the following remain a double after it is cast as an int... For the second one also, why does it output a float when defined as a long?:
(int) d / 2.0
(long) d * 2f
Because priority of cast (int) operator is higher that / and * operators.
You should read it like this:
((int) d) / 2.0
((long) d) * 2f
Why does the first of the following print a string(?), and the latter a number?
"2" + x + 2
"3" + 3 * x
I think it's string in both casesm you must "read" this expressions like this:
("2" + x) + 2
"3" + (3 * x)
But then there is an error with the following:
"5" + i + 2
What is the error?
Also, with the follwing, what is actually happening and what is the result?
d++ + d
This is a sequence of actions:
tmp = d
d = d + 1
return tmp + d
When Math.round is used, why does it convert the following double into a float, or are they the same thing?
Math.round(x / d)
It converts to long, because return type of Math.round(double) is long
(int) d / 2.0
(long) d * 2f
You still do floating point math, i.e. one operand is still a double/float and thus the result is a double/float.
"2" + x + 2
"3" + 3 * x
The first would just be concatenation, i.e. the type of the expression is String and thus all operands are converted to a string. For x=1 you'd get "212".
The second is subject to operator precendence, i.e. * is evaluated before + and thus the expression 3 * x is an integer math operation whose result will then be converted to a string by "3" + result.
"5" + i + 2
The error lies in your code, post the exception. Most probably i is undefined.
d++ + d
Have a look at operator precedence and post increment operators. x++ would return the value of x and then increment it. Then the previous value of x will be added to the new value. You can think of it being similar to x + (x+1).
When Math.round is used, why does it convert the following double into a float, or are they the same thing?
Math.round(x / d)
There's no conversion, just an overloaded method (one taking a double and one taking a float). Basically float has less precision than double but both are floating point numbers.
Too many questions in one.
You're casting the operand, not the expression, and types will be promoted.
What do they actually print, and how are you differentiating their types? Check out Java operator precedence.
Because there's no i.
You can print the result.
The Conversions and Promotions JLS section may also be helpful; many of your questions are answered there.

3 / 2 = 1.0? really? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java Integer Division, How do you produce a double?
double wang = 3 / 2;
Log.v("TEST", "Wang: " + Double.toString(wang));
Logcat output...
07-04 09:01:03.908: VERBOSE/TEST(28432): Wang: 1.0
I'm sure there's an obvious answer to this and probably I'm just tired from coding all night but this has me stumped.
In many languages, Java being one of them, the way you write a number in an expression decides what type it gets. In Java, a few of the common number types behave like this1:
// In these cases the specs are obviously redundant, since all values will be
// cast correctly anyway, but it was the easiest way to show how to get to the
// different data types :P
int i = 1;
long l = 1L;
float f = 1.0f; // I believe the f and d for float and double are optional, but
double d = 1.0d; // I wouldn't bet on what the default is if they're omitted...
Thus, when you declare 3 / 2, you're really saying (the integer 3) / (the integer 2). Java performs the division, and finds the result to be 1 (i.e. the integer 1...) since that's the result of dividing 3 and 2 as integers. Finally, the integer 1 is cast to the double 1.0d which is stored in your variable.
To work around this, you should (as many others have suggested) instead calculate the quotient of
(the double 3) / (the double 2)
or, in Java syntax,
double wang = 3.0 / 2.0;
1 Source: The Java Tutorial from Oracle
Integer division of 3 by 2 is equal to 1 with residue of 1. Casting to double gives 1.0
3 and 2 are integer constants and therefore 3 / 2 is an integer division which results in 1 which is then cast into a double. You want 3.0 / 2.0
Try: double wang = 3.0 / 2.0;
That's the expected behaviour. "3" and "2" are both int values, and when you perform 3 / 2 the result will also be an int value which gets rounded down to 1. if you cast both to double before you perform the division then you'll get the result that you expect:
double wang = (double)3 / (double)2;

Categories