why the result is x=1 y=3 res=1
int x = 7, y = 3;
int res;
res = (x = y < 2 || x != 1);
printf("x = %d y = %d res = %d\n", x, y, res);
and with this code the result is y<2 so False which is 0 so lvalue x = 0 so the res=0
res= (x = y < 2); //|| x != 1);
printf("x = %d y = %d res= %d\n", x, y, res);
res = (x = y < 2 || x != 1);
...is evaluated as...
res = (x = ((y < 2) || (x != 1)));
You can find the Operator Precendence for C++ here - C is similar for the operators you've used.
So for x = 7, y = 3...
res = (x = ((3 < 2) || (7 != 1)));
res = (x = (false || true)); // || is "logical-OR", tests if either true
res = (x = true);
res = (x = 1); // standard conversion from bool to int
res = 1;
For your second, simpler statement:
res = (x = y < 2);
res = (x = (y < 2));
res = (x = (3 < 2));
res = (x = false);
res = (x = 0); // standard conversion from bool false to int 0
res = 0;
In C, even if you #include <stdbool.h> the <, != and || operators will yield 1 immediately for "true" tests, and 0 for "false", and there's no separate "standard conversion" as in C++. Allan's answer describes the C evaluation steps nicely.
res = (x = y < 2 || x != 1);
In above statement y < 2 || x != 1 is a conditional expression whose result is true (1) which is loaded into x.
Now, (x = y < 2 || x != 1) evaluated as x = 1 and hence res = x = 1
This you get res and x equals to 1 and y unchanged.
The issue you seem to be having is operator precedence. The link is to an operator precedence chart which should help clear things up.
First you should know that comparisons result in either a 1 or a 0. For example, (5 < 10) returns 1 because it is true, and (5 > 10) returns 0 because it is false.
In your example, it's easier if we clarify it by adding parenthesis to show the order things are happening in.
res = (x = **(y < 2)** || **(x != 1)**)
This is the first set of operations that happens. After those resolve we are left with:
res = (x = **(0)** || **(1)**)
The next operation to take place is the OR:
res = (x = **(0 || 1)** )
This results in a 1:
res = (x = **1** )
then the assignment operation happens:
res = (**x = 1**)
then the next assignment happens:
**res = x**
Since x is equal to 1 from the previous assignment, res is also set to 1.
Not sure what you're asking in the second bit, so if you want to clarify that I'll answer for you.
< has higher precedence than = and therefore x = y < 2 is equivalent to x = (y < 2).
Since y is greater than 2 therefore y < 2 will give 0 and this value will be assigned to x. Now x is equal to 0 therefore x != 1 will be evaluated as true and the value of the whole expression x = y < 2 || x != will be 1 and this value is assigned to res.
In this case operator precedence will work.
res = (x = y < 2 || x != 1);
In this expression, first y < 2 is evaluated.
Then or(||) will work, because of first condition fails, so now the x is not equal to 1. so the condition will became true so the true value 1 is stored x and in the res variable.
(y < 2 || x != 1 ). // expression is true. So the value 1 is stored in the variable x and ret.
In second case,
y < 2; // this condition will become false. So the zero is stored in both the variable.
Related
I have a square matrix, 40 x 40, and a draw circle function that uses this formula.
I have another function that reads input from a file, the point itself (x0, y0) and the type of circle (0 or 1) and the radius.
void cerc(int x0, int y0, int r, int** matriceHarta, int tip, int n, int m)
{
if (r == 0)
return;
int x, y, xx, rr;
for (rr = r * r, x = -r; x <= r; x++)
for (xx = x * x, y = -r; y <= r; y++)
if (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0)
{
if (tip == 0)
matriceHarta[x0 + x][y0 + y] = -5;
else if (tip == 1)
matriceHarta[x0 + x][y0 + y] = -6;
}
}
N and M are the rows and columns, but right now they are both equal.
The matrix is allocated dynamically and is transmitted via the int** matriceHarta parameter.
If I put the point on (39, 39) and I give it the radius 5, the program returns a negative exit code, which I found out is an out of bounds related error. I looked over the for loops and it makes sense that that'd be the error and tried to create the condition if((x0 + x) < n && (y0 + y) < m) to check the bounds, but it still gives the error.
Question is, what am I doing wrong? For contrast, point(37, 4) with radius = 2 is OK, but point(38, 4) with radius = 2 is not OK
This is the attempted fix:
for (rr = r * r, x = -r; x <= r; x++)
for (xx = x * x, y = -r; y <= r; y++)
if (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0
&& (((x0+x) < n) && ((y0+y) < m)) )
//^^^^^ this is the condition i was talking about
{
if (tip == 0)
matriceHarta[x0 + x][y0 + y] = -5;
else if (tip == 1)
matriceHarta[x0 + x][y0 + y] = -6;
}
The issue is that you are testing for the out-of-bounds condition after you have already accessed potential out-of-bounds elements.
Let's break it down into separate lines:
if (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0
&& // <-- This binds the conditions
(((x0+x) < n) && ((y0+y) < m)))
The line above the && marked with <-- is evaluated before the line below the <--.
In summary, the logical && is always evaluated from left-to-right, where the right side will not be evaluated if the left side evaluates to false (short-circuit boolean evaluation).
Thus the fix is to test the bounds condition first (swap the lines in the code above).
However, to make this a little more clear, you could break up the statement into two if statements:
if (x0+x < n && y0+y < m)
{
if (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0)
{
...
}
}
Given the following code pattern, wherein I am trying to state a vector direction in increments of 45 degrees over the integers int x and int y, inside of a circle positioned at the origin
// x == 0 && y == 0 case is already taken cared of
if(x > 1) {
if(y == 0) {
// horizontal right
m_rotation = 0;
}else if(y < 1) {
// diagonal down right
m_rotation = 315;
} else if(y > 1) {
// diagonal up right
m_rotation = 45;
}
} else if(x == 0) {
if(y < 1) {
// vertical down
m_rotation = 270;
} else if(y > 1) {
// vertical up
m_rotation = 90;
}
} else if(x < 1){
if(y == 0) {
// horizontal left
m_rotation = 180;
}else if(y < 1) {
// diagonal down left
m_rotation = 225;
} else if(y > 1) {
// diagonal up left
m_rotation = 135;
}
}
I am looking for an elegant way to make this compact. I know there's the spaceship operator <=>, but I need to restrict myself to C++17.
Things I have tried
Nesting ternary operators with m_rotation = x > 1? (y < 1? (y == 0? 0: 315): 45): (x == 0? (y < 1? 270: 90): (y < 1? (y == 0? 180: 225): 135));, but this looks weird
I tried putting the x == 0 case inside x < 1 case and transform the later into else, but that does not simplify enough the code
Using absolute values to compare x and y, but I quickly get lost
Nothing else really, I don't know what else to try
Something like
constexpr int rotation[3][3] = {
{225, 180, 135},
{270, 0, 90},
{315, 0, 45},
};
if (x != 0 || y != 0) // if (!(x == 0 && y == 0))
m_rotation = rotation[1 + sign(x)][1 + sign(y)];
There is a closed form:
// standard sign functions
int xs = x < 0 ? -1 : x > 0;
int ys = y < 0 ? -1 : y > 0;
return 180 - 45 * (xs + 2) * ys + 90 * (xs * xs + xs) * (ys * ys - 1);
or shorter
return 180 * (x < 0 || y) - 45 * (xs + 2) * ys;
There seems to be some kind of misconception that this is for a contest.
I'm trying to work through an assignment and I've been stuck on this for an hour now.
/*
* isLessOrEqual - if x <= y then return 1, else return 0
* Example: isLessOrEqual(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isLessOrEqual(int x, int y)
{
int greater = (x + (~y + 1))>>31 & 1;
return !(greater)|(!(x^y));
}
I'm only able to use bitwise operators, as instructed in the comments.
I cannot figure out how to solve x <= y;
My thought process is that I can set x as its two's complement (~x +1) and add it with Y. If it is negative, X is greater than Y. Therefore, by negating that I can get the opposite effect.
Similarly, I know that !(x^y) is equivalent to x==y.
However,
doing !(greater)|(!(x^y)) does not return the proper value.
Where am I messing up? I feel like I'm missing a small bit of logic.
Those functions don't fully work because of the overflow, so that's how I solved the problem. Eh...
int isLessOrEqual(int x, int y) {
int diff_sgn = !(x>>31)^!(y>>31); //is 1 when signs are different
int a = diff_sgn & (x>>31); //diff signs and x is neg, gives 1
int b = !diff_sgn & !((y+(~x+1))>>31); //same signs and difference is pos or = 0, gives 1
int f = a | b;
return f;
}
If x > y, then y - x or (y + (~x + 1)) will be negative, hence the high bit will be 1, otherwise it will be 0. But we want x <= y, which is the negation of this.
/*
* isLessOrEqual - if x <= y then return 1, else return 0
* Example: isLessOrEqual(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isLessOrEqual(int x, int y)
{
return !(((y + (~x + 1)) >> 31) & 1);
}
Even better, drop the shift operator and use a bit mask on the high bit:
int isLessOrEqual(int x, int y)
{
return !((y + (~x + 1)) & 0x80000000);
}
EDIT:
As a commenter pointer out, the above version is susceptible to arithmetic overflow errors. Here is another version that covers the edge cases.
#include <limits>
int isLessOrEqual(int x, int y)
{
static int const vm = std::numeric_limits<int>::max();
static int const sm = ~vm;
return !! ((x & ~y | ~(x ^ y) & ~((y & vm) + ~(x & vm) + 1)) & sm);
}
Explanation: the overall strategy is to treat the sign bit of the inputs as logically distinct from the rest of the bits, the "value bits," and perform the subtraction as in the previous example on just the value bits. In this case, we need only perform the subtraction where the two inputs are either both negative or both non-negative. This avoids the arithmetic overflow condition.
Since the size of int strictly speaking is unknown at run time, we use std::numeric_limits<int>::max() as a convenient mask for the value bits. The mask of the sign bit is simply the bit-wise negation of the value bits.
Turning to the actual expression for <=, we factor out the bit-wise mask sm of the sign bit in each of the sub-expressions and push the operation to the outside of the expression. The first term of the logical expression x & ~y is true when x is negative and y is non-negative. The first factor of the next term ~(x ^ Y) is true when both are negative or both are non-negative. The second factor ~((y & vm) + ~(x & vm) + 1)) is true when y - x is non-negative, in other words x <= y, ignoring the sign bit. The two terms are or'd, so using c++ logical expression syntax we have:
x < 0 && y >= 0 || (x < 0 && y < 0 || x >= 0 && y >= 0) && y - x >= 0
The !! outermost operators convert the raised sign bit to a 1. Finally, here is the Modern C++ templated constexpr version:
template<typename T>
constexpr T isLessOrEqual(T x, T y)
{
using namespace std;
// compile time check that type T makes sense for this function
static_assert(is_integral<T>::value && is_signed<T>::value, "isLessOrEqual requires signed integral params");
T vm = numeric_limits<T>::max();
T sm = ~vm;
return !! ((x & ~y | ~(x ^ y) & ~((y & vm) + ~(x & vm) + 1)) & sm);
}
Really enjoyed Yanagar1's answer, which is very easy to understand.
Actually we can remove those shift operators and use De Morgan's laws, which reduce the number of operators from 15 to 11.
long isLessOrEqual(long x, long y) {
long sign = (x ^ y); // highest bit will be 1 if different sign
long diff = sign & x; // highest bit will be 1 if diff sign and neg x
long same = sign | (y + (~x + 1)); // De Morgan's Law with the following ~same
// highest bit will be 0 if same sign and y >= x
long result = !!((diff | ~same) & 0x8000000000000000L); // take highest bit(sign) here
return result;
}
Here is my implementation(spend around 3 hours...)
int
isLessOrEqual(int x, int y)
{
int a = y + ~x + 1;
int b = a & 1 << 31 & a; // !b => y >= x, but maybe overflow
int c = !!(x & (1 << 31)) & !(y & (1 << 31)); // y > 0, x < 0
int d = !(x & (1 << 31)) & !!(y & (1 << 31)); // x > 0, y < 0
int mask1 = !c + ~0;
// if y > 0 && x < 0, return 1. else return !b
int ans = ~mask1 & !b | mask1 & 1;
int mask2 = !d + ~0;
// if y < 0 && x > 0, return 0, else return ans
return ~mask2 & ans | mask2 & 0;
}
y - x == y + ~x + 1
a & 1 << 31 & a is simplify from !(!(a & (1 << 31)) | !a)
The logic is:
if `y > 0 && x < 0`
return true
if `x > 0 && y < 0`
return false
return y >= x
Why not just y >= x directly? because overflow may happen. So I have to early return to avoid overflow.
Inspired by Yanagar1's answer, here's my implementation:
int isLessOrEqual(int x, int y) {
int indicator = !((y + (~x + 1)) >> 31); // negation of the result of y - x, 0 when y < x, -1 when y >= x
int xsign = x >> 31; // -1 when x < 0, 0 when x >= 0
int ysign = y >> 31; // -1 when y < 0, 0 when y >= 0
int xbool = !xsign; // 0 when x < 0, 1 when x >= 0
int ybool = !ysign; // 0 when y < 0, 1 when y >= 0
int result = (!(xbool ^ ybool)) & indicator;
return result | (ybool & !xbool);
}
Explanation: Adding 2's complement negation of x (~x + 1) to y is essentially calculating y - x, then logical negate the sign bit of the result, we can have 0 when y < x, and 1 when y >= x. But there are potential overflow cases (overflow cannot happen when y and -x have opposite signs, that is, when y and x have same signs):
|-----------|------------------------|------------------------|
| | y > 0 | y < 0 |
|-----------|------------------------|------------------------|
| x > 0 | ok | overflow when y = TMin |
|-----------|------------------------|------------------------|
| x < 0 | overflow when x = TMin | ok |
|-----------|------------------------|------------------------|
so we need to be careful when the signs are different.
Might my solution is stupid.
int isLessOrEqual(int x, int y) {
/*
* A: sign bit of x B: sign bit of y C:A == B Result Rearrange the result(Expeced)
* 0 0 1 y - x >= 0 (y + (~x+1) >= 0) & 1 | 0 => (y + (~x+1) >= 0) & C | !(B | C)
* 0 1 0 0 (y + (~x+1) >= 0) & 0 | 0 => (y + (~x+1) >= 0) & C | !(B | C)
* 1 0 0 1 (y + (~x+1) >= 0) & 0 | 1 => (y + (~x+1) >= 0) & C | !(B | C)
* 1 1 1 y - x >= 0 (y + (~x+1) >= 0) & 1 | 0 => (y + (~x+1) >= 0) & C | !(B | C)
* But, minus operator is illegal. So (y - x) placed by (y + (-x)).
* You know -x == (~x + 1).
* If we know *x* and *y* have different sign bits, the answer is determinated and the (y-x >= 0) was useless.
* finally, the work like designing digital circuit. produce a final expression.
*/
int A = (x >> 31) & 1;
int B = (y >> 31) & 1;
int C = !(A ^ B);
int greatOrEqual0 = (!(((y + (~x + 1)) >> 31) ^ 0));
return (greatOrEqual0 & C) | !(B | C);
}
I am a beginner, and I created a slot machine simulator. The wheel is spun and x, y, and z are set to random numbers. I have an if statement that checks to see if x == y == z. When the program runs, and the numbers are in fact equal, it runs my code that says they are not equal. Why does this happen?
For example, the cout statement will say 2 -- 2 -- 2, then it goes to my if statement for when they are not equal, and I get the "you lose" code.
I should add, this does not happen every time. Sometimes it properly executes the if statement for when they are equal. It is very odd.
srand(time(0));
int x = (rand() % 2) + 1;
int y = (rand() % 2) + 1;
int z = (rand() % 2) + 1;
std::cout << "The spin results are... " << x << " -- " << y << " -- " << z << std::endl << std::endl;
if( x == y == z)
{
std::cout << "You win!\n\n";
playerCoins = playerCoins + (coinsBet * 2);
}
else
{
std::cout << "You lose!\n\n";
}
x == y may result in 0 or 1, depending on their true or false value. Then 0 or 1 is compared with z, this why the given result is false.
The correct method is to check if x equals z and y equals z, which of course also means that x equal y. (x == z) && (y == z)
x == y == z does not do what you think it does. Use x == y && y == z instead.
The expression if (x == y == z) is evaluated to false.
Pretend x, y, and z all hold the value 2:
Because (x == y) is then true / 1. And z is holding the value 2, the if statement will check:
if ((x == y) == z)
// 1 == 2
Which becomes:
if (1 == 2) {} // false
You can fix that by doing this:
if ((x == y) && (y == z)) { /* ... */ }
You should use Logical operators.
the expression, x == y == z is wrong.
it should be done this way.
if((x == y) && (y == z)) { //or... if ((x == y) == z)
//your code goes here...
}
More information about logic operators, Here.
I'm very new to C++ and was wondering if if there is a better way of doing this. It's going to run on an Arduino so I can't use ArrayLists or anything.
byte GetFreeCell(short x, short y)
{
byte possibleMoves[4] = {0,0,0,0};
if (y - 2 >= 0 && _grid[y - 2][x] == 0)
possibleMoves[0] = 1;
if (x + 2 < WIDTH && _grid[y][x + 2] == 0)
possibleMoves[1] = 2;
if (y + 2 < HEIGHT && _grid[y + 2][x] == 0)
possibleMoves[2] = 3;
if (x - 2 >= 0 && _grid[y][x - 2] == 0)
possibleMoves[3] = 4;
if (possibleMoves[0] == 0 && possibleMoves[1] == 0 && possibleMoves[2] == 0 && possibleMoves[3] == 0) {
return 0;
}
byte move = 0;
while(move == 0){
move = possibleMoves[random(4)];
}
return move;
}
Thanks,
Joe
byte GetFreeCell(short x, short y)
{
byte possibleMoves[4];
byte index = 0;
if (y - 2 >= 0 && _grid[y - 2][x] == 0)
possibleMoves[index++] = 1;
if (x + 2 < WIDTH && _grid[y][x + 2] == 0)
possibleMoves[index++] = 2;
if (y + 2 < HEIGHT && _grid[y + 2][x] == 0)
possibleMoves[index++] = 3;
if (x - 2 >= 0 && _grid[y][x - 2] == 0)
possibleMoves[index++] = 4;
return index ? possibleMoves[random(index)] : 0;
}
You can do yourself a favor and use this:
https://github.com/maniacbug/StandardCplusplus/#readme
Then you can sanitize your code by using standard containers.
Also, there's no ArrayList in C++. That's Java. With the above library, you can use std::vector instead.