This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 3 years ago.
I have the following expression in my code
int n = ((int) Math.sqrt(4 * 4 + 5) - 1) / 2;
Can someone tell me the precedence in which the expression is evaluated?
Logically I would evaluate the expression in the following way:
4 * 4 + 5 = 16 + 5 = 21
Math.sqrt(21) ~ 4.58
4.58 - 1 = 3.58
(int) 3.58 = 3
3 / 2 = 1.5
However the code evaluates to 1.
You almost got it. The only difference (which doesn't matter for the result) is that the cast is evaluated
before the subtraction, and you're using integer division:
4 * 4 + 5 = 16 + 5 = 21
Math.sqrt(21) ~ 4.58
(int) 4.58 = 4 (cast first)
4 - 1 = 3
3 / 2 = 1 (integer division)
The order you suggest is correct.
The keypoint is the last operation: the result of an int divided by an int is an int as well.
To fix this, one of the two number should be a float (or a double):
float n = ((float)(int) (Math.sqrt(4 * 4 + 5) - 1)) / 2;
In this way you divide a float by an int, and the result will be a float.
Or better:
double n = (Math.sqrt(4 * 4 + 5) - 1) / 2;
Because the cast to int of Math.sqrt() isn't useful.
Please note that the first operation does exactly what you ask with the round of the Math.sqrt(), while the second one doesn't.
Here is the problem I am currently trying to solve.
There is a maximum value called T. There are then two subvalues, A and B, that are 1 <= A,B <= T. In each round, you can pick either A or B to add to your sum. You can also choose to half that sum entirely in only one of the rounds. You can never exceed T in any round. Given an infinite number of rounds, what is the maximum sum you can get.
Here's an example:
T = 8
A = 5, B = 6
Solution: We first take B, then half the sum getting 3. Then we add A and get 8. So the maximum possible is 8.
The iterative idea I have come up with is: it is basically a tree structure where you keep branching of and trying to build of older sums. I am having trouble trying to figure out a maximization formula.
Is there a brute force solution that will run fast or is there some elegant formula?
Limits: 1 <= A, B <= T. T <= 5,000,000.
EDIT: When you divide, you round down the sum (i.e. 5/2 becomes 2).
The problem can be viewed as a directed graph with T + 1 nodes. Imagine we have T + 1 nodes from 0 to T, and we have an edge from node x to node y if:
x + A = y
x + B = y
x/2 = y
So, in order to answer the question, we need to do a search in the graph, with stating point is node 0.
We can do either a breath first search or depth first search to solve the problem.
Update: as we can only do divided once, so we have to add another state to the graph, which is isDivided. However, the way to solve this problem is not changed.
I will demonstrate the solution with a BFS implementation, DFS is very similar.
class State{
int node, isDivided;
}
boolean[][]visited = new boolean[2][T + 1];
Queue<State> q = new LinkedList();
q.add(new State(0, 0));//Start at node 0, and haven't use division
visited[0][0] = true;
int result = 0;
while(!q.isEmpty()){
State state = q.deque();
result = max(state.node, result);
if(state.node + A <= T && !visited[state.isDivided][state.node + A]){
q.add(new State(node + A , state.isDivided));
visited[state.isDivided][node + A] = true;
}
if(node + B <= T && !visited[state.isDivided][node + B]){
q.add(new State(node + B, state.isDivided));
visited[state.isDivided][node + B] = true;
}
if(state.isDivided == 0 && !visited[state.isDivided][node/2]){
q.add(new State(node/2, 1));
visited[state.isDivided][node/2] = true;
}
}
return result;
Time complexity is O(n)
To summarize your problem setting as I understand it (under the constraint that you can divide by two no more than once):
Add A and B as many times as you want (including 0 each)
Divide by 2, rounding down
Add A and B as many times as you want
The goal is to obtain the largest possible sum, subject to the constraint that the sum is no more than T after any step of the algorithm.
This can be captured neatly in a 5-variable integer program. The five variables are:
a1: The number of times we add A before dividing by 2
b1: The number of times we add B before dividing by 2
s1: floor((A*a1+B*b1)/2), the total sum after the second step
a2: The number of times we add A after dividing by 2
b2: The number of times we add B after dividing by 2
The final sum is s1+A*a2+B*b2, which is constrained not to exceed T; this is what we seek to maximize. All five decision variables must be non-negative integers.
This integer program can be easily solved to optimality by an integer programming solver. For instance, here is how you would solve it with the lpSolve package in R:
library(lpSolve)
get.vals <- function(A, B, T) {
sol <- lp(direction = "max",
objective.in = c(0, 0, 1, A, B),
const.mat = rbind(c(A, B, 0, 0, 0), c(0, 0, 1, A, B), c(-A, -B, 2, 0, 0), c(-A, -B, 2, 0, 0)),
const.dir = c("<=", "<=", "<=", ">="),
const.rhs = c(T, T, 0, -1),
all.int = TRUE)$solution
print(paste("Add", A, "a total of", sol[1], "times and add", B, "a total of", sol[2], "times for sum", A*sol[1]+B*sol[2]))
print(paste("Divide by 2, yielding value", sol[3]))
print(paste("Add", A, "a total of", sol[4], "times and add", B, "a total of", sol[5], "times for sum", sol[3]+A*sol[4]+B*sol[5]))
}
Now we can compute how to get as high of a total sum as possible without exceeding T:
get.vals(5, 6, 8)
# [1] "Add 5 a total of 1 times and add 6 a total of 0 times for sum 5"
# [1] "Divide by 2, yielding value 2"
# [1] "Add 5 a total of 0 times and add 6 a total of 1 times for sum 8"
get.vals(17, 46, 5000000)
# [1] "Add 17 a total of 93 times and add 46 a total of 0 times for sum 1581"
# [1] "Divide by 2, yielding value 790"
# [1] "Add 17 a total of 294063 times and add 46 a total of 3 times for sum 4999999"
I'll use some mathematical approach.
Resume:
You should be able to calculate the max with A,B, T, without iterations (only to get A/B HCD), for T, not to small.
If A or B is an odd number, max = T (with a reserve, I'm not sure you never go over T: see below).
If A and B is even numbers, get C as highest common factor. Then max = round (T/C*2) *C/2 = highest multiple of C/2 below or equal to T
Some explanations:
With the rule: Ap+Bq (without dividing by 2)
1 suppose A and B are primes together, then you can get every integer you want, after the little ones. Then max=T
example: A=11, B=17
2 if A=Cx, and B=Cy, x,y primes together (like 10 and 21), you can get every C multiples, then max= biggest multiple of C below T: round(T/C)*C
example: A=33, B=51 (C=3)
With the rule : you can divide by 2
3 - If C is even number (that is A and B can be divided by 2): max= multiple of C/2 below T: round(T/C*2)*C/2
example: A=22, B=34 (C=2)
4 - Otherwise, you have to find the biggest dividor (highest common factor) of A, B, round(A/2), round (B/2), call it D, max= biggest multiple of D below T: round(T/D)*D
As A and round (A/2) are primes together (idem for B and round (B/2)), then you can get max = T as in case 1 - warning: I'm not sure if you never go past T. To check
We can describe the problem in this way aswell:
f(A , B) = (A * n + B * m) / 2 + (A * x + B * y)
= A * (n * 0.5 + x) + B * (m * 0.5 + y) =
= A * p + B * q
find N: N = f(A , B) and N <= T such that no M: M > N satisfying
the condition exists.
The case without any division by two can easily be represented by n = m = 0 and is thus aswell covered by f.
n and y can be any arbitrary values matching p = n * 0.5 + y (same for q and related values). Note that there are multiple valid solutions as shown in f.
T >= A * p + B * q
r = p * 2, s = q * 2
find integral numbers r, s satisfying the condition
T >= A * r / 2 + B * s / 2
simplify:
T * 2 / B >= A / B * r + s
Thus we know:
(T / B * 2) mod 1 - (A / B * r) mod 1 is minimal and >= 0 for the optimal solution
T * 2 / A >= r >= 0 are the upper and lower bounds for r
(A / B * r) mod 1 = 0, if r = B / gcd(A , B) * n, where n is an integral number
Finding r using these constraints now becomes a trivial task, using binary search. There might be more efficient approach to this, but O(log B) should do for this purpose:
Apply a simple binary-search to find the matching value
in the range [0 , min(T * 2 / A , B / gcd(A , B))
Finding s can easily be done for any corresponding r:
s = roundDown(T * 2 / B - A * r / B)
E.g.:
A = 5
B = 6
T = 8
gcd(A , B) = 1
search-range = [0 , 6)
(T / B * 2) mod 1 = 4 / 6
(A / B * r) mod 1 =
r = 3: 3 / 6 => too small --> decrease r
r = 1: 5 / 6 => too great --> increase r
r = 2: 4 / 6 => optimal solution, r is found
r = 2
s = roundDown(T * 2 / B - A * r / B) = roundDown(3.2 - 1.66) = 1
p = r / 2 = 1 = 1 + 0 = 2 * 0.5 --> n = 1 y = 0 or n = 2 y = 0
q = s / 2 = 0.5 --> n = 0.5 y = 0
8 >= 5 * 1 + 5 * 0.5 * 0 + 0 * 6 + 1 * 0.5 * 6 = 5 + 3
= 5 * 0 + 5 * 0.5 * 2 + 0 * 6 + 1 * 0.5 * 6 = 5 + 3
Advantage of this approach: We can find all solutions in O(log B):
If a value for r is found, all other values r' matching the constraints are as follows: r' = r + B / gcd(A , B) * n. A and B are exchangeable in this approach allowing to optimize even further by using the smaller input value as B.
The rounding of values when the variable is divided by two in your algorithm should only cause minor problems, which can easily be fixed.
Consider
int a = 20;
a = a + (a = 5); // a == 25, why not 10?
Don't parentheses trump all precedence rules? Are some variables on the RHS prepopulated before evaluation of certain expressions?
Because a is loaded first in the example you have, and then the bit in parenthesis is evaluated. If you reversed the order:
int a = 20;
a = (a = 5) + a;
System.out.println(a);
10
... you do indeed get 10. Expressions are evaluated from left to right.
Consider this:
f() + g()
f will be called before g. Imagine how unintuitive it would be, in
f() + (g())
to have g be called before f.
This is all detailed in JLS §15.7.1 (thanks to #paisanco for bringing it up in the comments).
From the JLS
The Java programming language guarantees that the operands of
operators appear to be evaluated in a specific evaluation order,
namely, from left to right.
and
The left-hand operand of a binary operator appears to be fully
evaluated before any part of the right-hand operand is evaluated.
Wrapping an expression in parentheses just helps grouping (and associativity), it doesn't force its evaluation to happen before anything to its left.
Generated bytecode:
BIPUSH 20
ISTORE 1
ILOAD 1
ICONST_5
DUP
ISTORE 1
IADD
ISTORE 1
RETURN
LOCALVARIABLE a I
First, you assign 20 to the first variable (a):
BIPUSH 20
ISTORE 1
Then, you load the contents of the first variable to stack (20 is put on stack):
ILOAD 1
Then, you push the constant '5' to the stack twice (20 5 5):
ICONST_5
DUP
Then, you store the top of the stack to the first variable (a):
ISTORE 1
a is now 5, stack is now (20 5). We add both operands and put their sum to the first variable (a):
IADD
ISTORE 1
As a consequence, a is now 20 + 5 = 25. We end:
RETURN
You asked why and the latest JLS provides a clearer explanation of what is happening in JLS 17:
In particular, the presence or absence of parentheses around an
expression does not affect whether a variable is definitely assigned,
definitely assigned when true, definitely assigned when false,
definitely unassigned, definitely unassigned when true, or definitely
unassigned when false.
In effect they are saying that parentheses do not prompt assignment, which explains why assignment occurs left-to-right, unlike evaluation, which occurs in innermost-to-outermost order.
But that still does not answer why.
It's not because of compatibility with Java's predecessor, at least not in its present form, because the behavior does not match C:
Java 17:
int j = 3, k = 4, l = 5, m = 6, n = 7;
System.out.println(((j = 3) + j) + j); // 3 + 3 + 3 = 9
System.out.println(k + (k + (k = 3))); // 4 + 4 + 3 = 11
System.out.println(l + ((l = 3) + l)); // 5 + 3 + 3 = 11
System.out.println((m + (m += 3)) + m); // 6 + 9 + 9 = 24
System.out.println(n + (n += n / 2) + ++n); // 7 + 11 + 12 = 28
GCC 7.5.0:
printf("%d\n",((j = 3) + j) + j); // 3 + 3 + 3 = 9
printf("%d\n",k + (k + (k = 3))); // 3 + 3 + 3 = 9
printf("%d\n",l + ((l = 3) + l)); // 3 + 3 + 3 = 9
printf("%d\n",(m + (m += 3)) + m); // 9 + 9 + 9 = 27
printf("%d\n",n + (n += n / 2) + ++n); // 10 + 10 + 11 = 31
This leaves us with the explanation used elsewhere for Java awkwardness: upgradeability. Java happened to do it this way at the time it was written; changing it to work in alignment with C would potentially break existing code. I'd be curious to know of any discussion that might have taken place when the initial design was decided.
We can divide a number by subtraction and stop at the remainder as shown here.
But how do we continue to divide the remainder by subtraction ? I looked on google and could not find such answers. They don't go beyond the remainder.
For example, lets say we have
7/3.
7-3 = 4
4-3 = 1
So, we have 2 & (1/3). How do we do the 1/3
division using only subtraction or addition ?
REPEAT -
Please note that I dont want to use multiplication or division operators to do this.
You can get additional "digits", up to any arbitrary precision (in any base you desire, I'll use base 10 for simplicity but if you're trying to implement an algorithm you'll probably choose base 2)
1) Perform division as you've illustrated, giving you a quotient (Q=2), a divisor (D=3), and a remainder (R=1)
2) If R=0, you're done
3) Multiply R by your base (10, R now =10)
4) Perform division by subtraction again to find R/D (10/3 = 3+1/3).
5) Divide the resulting quotient by your base (3/10 = 0.3) and add this to what you got from step 1 (now your result is 2.3)
6) Repeat from step 2, dividing the new remainder (1) by 10 again
While it sounds an awful lot like I just said division quite a few times, we're dividing by your base. I used 10 for simplicity, but you'd really use base 2, so step 3 is really a left shift (by 1 bit every time) and step 5 is really a right shift (by 1 bit the first time through, 2 bits the second, and so on).
7/3.
7-3 = 4
4-3 = 1
7/3 = 2 R 1
1*10 = 10
10-3 = 7
7-3 = 4
4-3 = 1
10/3 = 3 R 1
7/3 = 2 + 3/10 R 1
7/3 = 2.3 R 1
1*10 = 10
10-3 = 7
7-3 = 4
4-3 = 1
10/3 = 3 R 1
7/3 = 2.3 + 3/100 R 1
7/3 = 2.33 R 1
And so on until you reach any arbitrary precision.
If you want to keep going to get decimal digits, multiply the remainder by a power of 10.
E.g. if you want 2.333, then you can multiply remainder by 1000, and then repeat the algorithm.
It depends on what you are asking.
If you are asking how to get the end fraction and simply it, let's take a different example.
26 / 6.
26 - 6 = 20 count 1
20 - 6 = 14 count 2
14 - 6 = 8 count 3
8 - 6 = 2 count 4
(In code, this would be accomplished with a for loop)
Afterwards, we would have 4 2/6. To simplify, switch the dividend and divisor:
6 / 2.
6 - 2 = 4 count 1
4 - 2 = 2 count 2
2 - 2 = 0 count 3
If this finishes without a remainder, show as 1 over the count.
In pseudo-code:
int a = 26;
int b = 6;
int tempb = 6;
int left = 26;
int count = 0;
int count2 = 0;
left = a - b;
for(count; left > b; count++){
left -= b;
}
if(left > 0){
for(count2; tempb > left; count2++){
tempb -= left;
}
console.log("The answer is " + count + " and 1/" + count2);
I hope this answers your question!
Here is a complete program that uses only + and -, translate to your language of choice:
module Q where
infixl 14 `÷` `×`
a × 0 = 0
a × 1 = a
a × n = a + a×(n-1)
data Fraction = F Int [Int]
a ÷ 0 = error "division by zero"
a ÷ 1 = F a []
0 ÷ n = F 0 []
a ÷ n
| a >= n = case (a-n) ÷ n of
F r xs -> F (r+1) xs
| otherwise = F 0 (decimals a n)
where
decimals a n = case (a × 10) ÷ n of
F d rest = (d:rest)
instance Show Fraction where
show (F n []) = show n
show (F n xs) = show n ++ "." ++ concatMap show (take 10 xs)
main _ = println (100 ÷ 3)
It is easy to extend this in such a way that the periodic part of the fraction is detected, if any. For this, the decimals should be tuples, where not only the fractional digit itself but also the dividend that gave rise to it is kept.
The printing function could then be adjusted to print infinite fractions like 5.1(43), where 43 would be the periodic part.
I have the following variable decelrations, assignments and variable declerations
variable e is an expression statement which should return the value of the evaulated variables in the expression;
What is the order of precdence of the opperators in the e variable?
Computed it equals = 60;
With a calculator I get 422;
int a, b, c, d;
a = 10;
b = 2;
c = 1;
d = 20;
e = a + b * d / c + a + b / d;
e = 10 + 2 * 20 / 1 + 10 + 2 / 20;
e = 60;
Actually the answer is 60.1 but since variables are int its showing 60. It is happening as below
10 + (2 * (20 / 1)) + 10 + (int)(2 / 20) = 10 + (2 * 20) + 10 + (int)0.1
= 10 + 40 + 10 + 0 = 60
Here is a link outlining operator precedence. As for your result, this can also be attributed to integer division (which takes the floor of the result; for instance, 2/20 = 0).
Just like in school, multiplication and division have priority over addition. So you have:
10 + 2 * 20 / 1 + 10 + 2 / 20 = 10 + 40 + 10 + 0 = 60
* takes first precedence so first, 2*20 =40, 10 + 40 / 1 + 10 + 2 / 20;
/ takes precedence so , 10 + 40 + 10 + 0;
+ takes precedence so, 60
Here is link for operator precedence: Operator precedence