Data values and types - java

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.

Related

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.

Java post-increment and pre increment behaviour

I have a simple Java expression depicted below. Based on Operator Precedence table, I expect that this expression would return division by zero exception (since post-fix increment operator has highest priority) and expect that resulting expression would look like:
2 + 2 + 5 / 0
But result is 7, why ? (By little bit of experimentation I found that all operators are assigned value of 1 for some reason, but this does not make sense to me in case priority table is correct)
int intCountOperator = 0;
unaryOperand = ++intCountOperator + intCountOperator + 5 / intCountOperator++;
System.out.println(unaryOperand); // Prints 7
The operator precedence does not control the evaluation order. It controls only how the expression is to be read. For example, since multiplication has a higher precedence than addition, x + y * z is read as x + (y * z), not (x + y) * z. However, it does not change that first x is evaluated, then y and finally z.
Giving a good example with ++ and -- is more difficult, because there is usually only one reading which makes sense. However, you might notice that y - x++ compiles without error (if x and y are numerical variables). If ++ would have had a lower precedence than - it would be evaluated as (x - y)++ which would not compile.
Because of operator precedence, your expression is evaluated as:
(++intCountOperator) + (intCountOperator + (5 / (intCountOperator++)));
but the evaluation order is not changed by it.
The expression is evaluated from left to right :
unaryOperand = ++intCountOperator + intCountOperator + 5 / intCountOperator++;
1 + 1 + 5 / 1 = 7
Note that the operators are evaluated in the order you expect, i.e. 1 + 1 + (5/1) = 1 + 1 + 5 = 7, but the operands of all those expressions are evaluated from left to right.
The order of evaluation is from left to right and not right to left. So the result 7 which you are getting is correct.
unaryOperand = ++intCountOperator + intCountOperator + 5 / intCountOperator++;
is actually
unaryOperand = 1 + 1 + 5 / 1; = 7

elements not being written into array in java

So I've written a programme used to solve a concrete equation having been given one parameter int n. The code I have is:
static double getSolution1(int n)
{
double [] a = new double[n+1];
a[0] =-1;
for (int i = 1; i < n+1; i++)
{
a[i] = a[i-1] * ( ( 2 / ( 3 * n ) ) * Math.cos(2 * a[i-1]) );
}
return a[n];
}
As far as I can tell, the code works fine and should be filling in the various parts of the array. But that's not happening, apart from a[0] = -1 that I have told the programme, it is treating all other entries as 0 as though it has not undergone the loop. Using a debug, that's the only problem I can really find. How can I fix that?
2 / 3 *n would give you zero, use all floats or doubles like 2.0f 3.0f
The "2 / ( 3 * n )" is being evaluated as int; and it works out as 0.
To fix, change it to "2.0 / (3.0 * n)"
As Pulkit said, 2/3 *n yields zero. Why?
Integer division will always round down your result to the nearest whole number. So:
2 / 3 = .666
floor(.666) = 0
To prevent this, you can add f to the end of 2 or 3. That'll cause the operation to evaluate as a float rather than an integer, avoiding the rounding.
2f / 3f
You can also add d to 2 or 3. That'll cause the operation to evaluate as a double rather than an integer.
2d / 3d
the expression ( 2 / ( 3 * n ) return an integer type. so for every number between 1 and 0, int type will be 0. what you can do is to let compiler treats 2 and 3 as float type or double type. you can use 2.0 instead of 2. or 3.0 instead of 3

How do math equations work in 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.

Java rounding up to an int using Math.ceil

int total = (int) Math.ceil(157/32);
Why does it still return 4? 157/32 = 4.90625, I need to round up, I've looked around and this seems to be the right method.
I tried total as double type, but get 4.0.
What am I doing wrong?
You are doing 157/32 which is dividing two integers with each other, which always result in a rounded down integer. Therefore the (int) Math.ceil(...) isn't doing anything. There are three possible solutions to achieve what you want. I recommend using either option 1 or option 2. Please do NOT use option 0.
Option 0
Convert a and b to a double, and you can use the division and Math.ceil as you wanted it to work. However I strongly discourage the use of this approach, because double division can be imprecise. To read more about imprecision of doubles see this question.
int n = (int) Math.ceil((double) a / b));
Option 1
int n = a / b + ((a % b == 0) ? 0 : 1);
You do a / b with always floor if a and b are both integers. Then you have an inline if-statement which checks whether or not you should ceil instead of floor. So +1 or +0, if there is a remainder with the division you need +1. a % b == 0 checks for the remainder.
Option 2
This option is very short, but maybe for some less intuitive. I think this less intuitive approach would be faster than the double division and comparison approach:
Please note that this doesn't work for b < 0.
int n = (a + b - 1) / b;
To reduce the chance of overflow you could use the following. However please note that it doesn't work for a = 0 and b < 1.
int n = (a - 1) / b + 1;
Explanation behind the "less intuitive approach"
Since dividing two integers in Java (and most other programming languages) will always floor the result. So:
int a, b;
int result = a/b (is the same as floor(a/b) )
But we don't want floor(a/b), but ceil(a/b), and using the definitions and plots from Wikipedia:
With these plots of the floor and ceil functions, you can see the relationship.
You can see that floor(x) <= ceil(x). We need floor(x + s) = ceil(x). So we need to find s. If we take 1/2 <= s < 1 it will be just right (try some numbers and you will see it does, I find it hard myself to prove this). And 1/2 <= (b-1) / b < 1, so
ceil(a/b) = floor(a/b + s)
= floor(a/b + (b-1)/b)
= floor( (a+b-1)/b) )
This is not a real proof, but I hope you're satisfied with it. If someone can explain it better I would appreciate it too. Maybe ask it on MathOverflow.
157/32 is int/int, which results in an int.
Try using the double literal - 157/32d, which is int/double, which results in a double.
157/32 is an integer division because all numerical literals are integers unless otherwise specified with a suffix (d for double l for long)
the division is rounded down (to 4) before it is converted to a double (4.0) which is then rounded up (to 4.0)
if you use a variables you can avoid that
double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);
int total = (int) Math.ceil((double)157/32);
Nobody has mentioned the most intuitive:
int x = (int) Math.round(Math.ceil((double) 157 / 32));
This solution fixes the double division imprecision.
In Java adding a .0 will make it a double...
int total = (int) Math.ceil(157.0 / 32.0);
When dividing two integers, e.g.,
int c = (int) a / (int) b;
the result is an int, the value of which is a divided by b, rounded toward zero. Because the result is already rounded, ceil() doesn't do anything. Note that this rounding is not the same as floor(), which rounds towards negative infinity. So, 3/2 equals 1 (and floor(1.5) equals 1.0, but (-3)/2 equals -1 (but floor(-1.5) equals -2.0).
This is significant because if a/b were always the same as floor(a / (double) b), then you could just implement ceil() of a/b as -( (-a) / b).
The suggestion of getting ceil(a/b) from
int n = (a + b - 1) / b;, which is equivalent to a / b + (b - 1) / b, or (a - 1) / b + 1
works because ceil(a/b) is always one greater than floor(a/b), except when a/b is a whole number. So, you want to bump it to (or past) the next whole number, unless a/b is a whole number. Adding 1 - 1 / b will do this. For whole numbers, it won't quite push them up to the next whole number. For everything else, it will.
Yikes. Hopefully that makes sense. I'm sure there's a more mathematically elegant way to explain it.
Also to convert a number from integer to real number you can add a dot:
int total = (int) Math.ceil(157/32.);
And the result of (157/32.) will be real too. ;)
int total = (int) Math.ceil( (double)157/ (double) 32);
Check the solution below for your question:
int total = (int) Math.ceil(157/32);
Here you should multiply Numerator with 1.0, then it will give your answer.
int total = (int) Math.ceil(157*1.0/32);
Use double to cast like
Math.ceil((double)value) or like
Math.ceil((double)value1/(double)value2);
Java provides only floor division / by default. But we can write ceiling in terms of floor. Let's see:
Any integer y can be written with the form y == q*k+r. According to the definition of floor division (here floor) which rounds off r,
floor(q*k+r, k) == q , where 0 ≤ r ≤ k-1
and of ceiling division (here ceil) which rounds up r₁,
ceil(q*k+r₁, k) == q+1 , where 1 ≤ r₁ ≤ k
where we can substitute r+1 for r₁:
ceil(q*k+r+1, k) == q+1 , where 0 ≤ r ≤ k-1
Then we substitute the first equation into the third for q getting
ceil(q*k+r+1, k) == floor(q*k+r, k) + 1 , where 0 ≤ r ≤ k-1
Finally, given any integer y where y = q*k+r+1 for some q,k,r, we have
ceil(y, k) == floor(y-1, k) + 1
And we are done. Hope this helps.
There are two methods by which you can round up your double value.
Math.ceil
Math.floor
If you want your answer 4.90625 as 4 then you should use Math.floor and if you want your answer 4.90625 as 5 then you can use Math.ceil
You can refer following code for that.
public class TestClass {
public static void main(String[] args) {
int floorValue = (int) Math.floor((double)157 / 32);
int ceilValue = (int) Math.ceil((double)157 / 32);
System.out.println("Floor: "+floorValue);
System.out.println("Ceil: "+ceilValue);
}
}
I know this is an old question but in my opinion, we have a better approach which is using BigDecimal to avoid precision loss. By the way, using this solution we have the possibility to use several rounding and scale strategies.
final var dividend = BigDecimal.valueOf(157);
final var divisor = BigDecimal.valueOf(32);
final var result = dividend.divide(divisor, RoundingMode.CEILING).intValue();
int total = (157-1)/32 + 1
or more general
(a-1)/b +1

Categories