I'm trying to code a mouse drag function in C. Basically, i want X to reach targetX, and Y to reach targetY at the same time. For example:
x = 0, y = 0;
targetX = 10, targetY = 20;
I want to make x reach targetX by the time y reaches targetY. I want it to loop until both x and y reach their target number, incrementing them by 1 each time to actually achieve that. So, at one point, x would be 9, and y would be 19, then it would increment them each by 1, causing them to both equal their target numbers, instead of x reaching targetX first, then y getting incremented solo (which is what my current code does). Also, i need it to be able to decrement (instead of increment) x or y (or both), as well.
Here is what i have now:
for (x; x < targetX || x > targetX;) {
x = (x < targetX) ? x + 1 : x - 1;
y = (y < targetY) ? y + 1 : y - 1;
mouse_move(x, y);
}
for (y; y < targetY || y > targetY;) {
y = (y < targetY) ? y + 1 : y - 1;
mouse_move(x, y);
}
It doesn't have to be in C, i'm just looking for a way to make x and y reach their target numbers at the same time.
Save the initial x.
Save the initial y.
delta x = target x - initial x
delta y = target y - initial y
num steps = max of the deltas (or whatever you want)
For step = 1 .. num steps,
fraction = step / num steps
x = initial x + ( fraction * delta x )
y = initial y + ( fraction * delta y )
Move the mouse
Related
Okay, I know the output for the expression (x *= y = z = 4;) is 40; but how exactly did we get 40? Can you please show me step by step.
I thought the precedence is from right to left so (2 * 4) = (z =4), I don't understand
#include <stdio.h>
#define PRINTX printf("%d\n",x)
int main (void){
int x = 2, y, z;
x *= 3 + 2;
PRINTX;
x *= y = z = 4;
PRINTX;
x = y == z;
PRINTX;
x == ( y = z );
PRINTX;
return 0;
}
No, the only way that assignment can be evaluated here is right to left.
First, note that x *= 99, for example, is shorthand for x = x * 99.
With that said,
x *= y = z = 4;
is equivalent to
z = 4;
y = z;
x *= y; // This is shorthand for x = x * 4
Consider what would happen if you tried to evaluate it the other way around:
// y is unininitialized
x *= y;
y = z;
z = 4;
It would fail.
So really,
// x = 2
int x = 2, y, z;
// x = x * (3 + 2) = x * 5 = 2 * 5 = 10
x *= 3 + 2;
// x = x * 4 = 10 * 4 = 40
x *= y = z = 4;
This can be rewritten as
int x, y, z;
x = 2; // x = 2
x = x * (3 + 2); // This is 2 * 5, so x = 10 after this
z = 4; // z = 4
y = z; // y = 4
x = x * y; // x = 10 * 4 = 40
And that's how you end up with 40.
All of the assignment operators have equal precedence, and right-to-left associativity (which affects what happens when multiple operators of equal precedence are present in an expression).
This means x *= y = z = 4 is equivalent to x *= (y = (z = 4)). z = 4 must be evaluated first (which assigns z to 4, and gives a result of 4). The assignment y = ... then gives the value y the value of 4, and also produces a result of 4. The assignment x *= ... then multiples x (which has a value 10) by 4, giving a result of 40.
(The reason x *= 3 + 2 gives x the value 10 is that addition has higher precedence than assignment, so x *= 3+2 is equivalent to x *= (3 + 2) rather than (x *= 3) + 2.)
If the assignment operators were instead left-to-right associative, x *= y = z = 4 would be equivalent to (((x *= y) = y) = z) = 4 which would not compile.
You have:
int x = 2, y, z;
x *= 3 + 2;
This is a shorthand for x = x * (3 + 2), which evaluates to 10 given that x starts at 2.
PRINTX;
x *= y = z = 4;
After this, y == z and both are set to 4; and x is 4 times its previous value of 10, hence 40.
PRINTX;
x = y == z;
This compares y and z; they're equal, so x is assigned 1 (comparisons always evaluate to 0 or 1).
PRINTX;
x == ( y = z );
This assigns z to y (leaving the value unchanged at 4); nominally, this is compared with x but the compiler can ignore the comparison. Therefore, x is unchanged and still 1.
I'm trying to understand the implementation of the Shamir's Secret Sharing Scheme from this (old) implementation on github, and I'm struggling with Horner's rule in extended fields GF(p^n):
void horner(int n, mpz_t y, const mpz_t x, const mpz_t coeff[])
{
int i;
mpz_set(y, x);
for(i = n - 1; i; i--) {
field_add(y, y, coeff[i]);
field_mult(y, y, x);
}
field_add(y, y, coeff[0]);
}
Why does add come first and only then mult? What's the algorithm? Why not something like:
mpz_set(y,coeff[n-1]);
for(i = n - 2; i!=-1; i--) {
field_mult(y, y, x);
field_add(y,y,coeff[i]);
}
Translating this horner function with normal addition and multiplication symbols, we get:
y = x; // mpz_set(y, x);
for(i = n - 1; i; i--) {
y = y + coeff[i]; // field_add(y, y, coeff[i]);
y = y * x // field_mult(y, y, x);
}
y = y + coeff[0] // field_add(y, y, coeff[0]);
Hence this computes the following:
You can see it does not compute any polynomial, but it is a variant of Horner's algorithm to compute a monic polynomial.
Now what you propose:
y = coeff[n-1]; // mpz_set(y,coeff[n-1]);
for(i = n - 2; i!=-1; i--) {
y = y * x; // field_mult(y, y, x);
y = y + coeff[i]; // field_add(y,y,coeff[i]);
}
Thus you compute the following:
You can see the highest-order term is missing.
If you want to have all the operations inside the body of the loop, you can.
After all, it's only two ways of decomposing a series of alternating instructions differently:
operation value of y loop iteration
add-mult loop mult-add loop
x initialization n-1
add x + coeff[n-1] n-1 n-1
mult (x + coeff[n-1]) * x n-1 n-2
add (x + coeff[n-1]) * x + coeff[n-2] n-2 n-2
mult ((x + coeff[n-1]) * x + coeff[n-2]) * x n-2 n-3
...etc...
But you need to explicitly initialize y to the value 1 (which is the implicit coeff[n]) so that you can start by multiplying by x and get the correct highest-order term.
y = 1; // mpz_set(y,1);
for(i = n - 1; i!=-1; i--) { // NOTICE n - 1 NOT n - 2
y = y * x; // field_mult(y, y, x);
y = y + coeff[i]; // field_add(y,y,coeff[i]);
}
You can count that you now perform one more multiplication, and it is multiplying 1 * x. On a finite field this is typically done with log and antilog tables, so you might as well avoid such a useless multiplication, especially if you're going to evaluate polynomials a lot.
TL;DR: This way of writing Horner's algorithm puts the last addition and the first multiplication outside of the loop's body. Because the highest-order coefficient is 1 this multiplication is then completely removed.
To clarify: the highest-order term is kept, but is then x^n instead of being 1 * x^n. You spare one multiplication for the exact same result.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Can anyone explain to me how this code is being calculated using operators.
#include <stdio.h>
int main(void)
{
int x = 2, y , z;
x *= 3;
printf("%d\n", x);
x = x * (3 + 2);
printf("%d\n", x);
x *= y = z = 4;
printf("%d\n", x);
x *= y += z;
printf("%d %d %d\n", x, y, z);
return 0;
}
As a result, I got the following output:
6,
30,
120,
960, 8, 4,
The operator followed by an equal sign means that the operator is applied to the variable on the left and the variable on the right, followed by an assignment to the variable on the left. You also follow the precedence operations. I have expanded the meaning below.
x *= 3;
is the same as
x = x * 3; // 6 = 2*3
The parentheses shows order of precedence
x = x * (3+2) // x was 6 from the previous line
this is
x = x * 5 // which gives 30
next
x *= y = z = 4;
means
z = 4;
y = z; //which is 4
x = x *y; // which is 120 = 30 *4
next
x *= y += z;
means
y = y + z ; // y = 4 + 4 (8)
x = x * y; // x = 120 * 8 (960)
*= multiplies left operand by right operand and assigns result to left.
x *= y = z = 4;
Works right to left, assigning 4 to z and y then multiplying x by 4.
x *= y += z;
z is added to y and result is assigned to y, then x is multiplied by y and result is assigned to x.
x*=3 means x=x*3 => x=2*3=6
x*=(3+2) means x=x*(3+2) => x=6*5=30
x*=y=z=4 means z=4, then y=4, then x=x*y => x=30*4=120
x*=y+=z means y=y+z then x=x*y => y=4+4=8 then x=120*8=960.
The first two assignments are straightforward: multiplying x by 3 gives you 6, and then by (3+2) gives you 30.
The third assignment features a chain of assignments, with 4 assigned to y and z. Since the value of an assignment is always the value of its left side after the assignment, the final multiplication x *= y multiplies x by 4, giving you 120.
The last line is the trickiest, because it features two side effects. First, y += z is evaluated, producing 8. After that x is multiplied by 8, producing its final value of 960.
Note that in the last line x is multiplied by 8, which may or may not be the value of y at the time the multiplication is performed.
Hopefully somebody can point out why this isnt working or where i may be going wrong. Im producing a sine wave by way of for loops in c. The ultimate aim is to produce a .ppm file displaying this. Im working on a 1 to 1 pixel ratio. My box is 128H*256W. The sine wave is displaying but due to the answer being produced in rads the result is a very small two pixel high "wave". I assume this is due to the rad values being between 1 and -1. This is my code. I tried just simply timesing by a greater number to increase the size of the y values in the hopes it would plot correctly but this does little or worse causes the applicattion to stop running. Any ideas very welcome.
for (x = 0; x < H; x++)
{
y =(int) H/2+ sin(x*(2*PI));
y = y * 50;
image[y][x][1] = 0;
image[y][x][2] = 255;
image[y][x][3] = 0;
}
EDIT: This is what is being produced in the .ppm file when opened via infraview. Also im #defining PI 3.141592653589793. Again is this possibly an area of issue.
first sine wave .ppm
I conject that y is an int.
Your sin value will be truncated to an integer; 0 for most cases, but very occasionally -1 or +1.
The fix is simple: use a floating point for y, and cast once you want to use it as an array index.
As y is commented to be an int and H appears to be an int constant, perform calculations as double first, then convert to int.
Use round to avoid truncations effect of simply casting a double to int.
y = (int) round(50*(sin(x*(2*PI)) + H/2.0));
Original code also scaled H/2 by 50. I think code may only want to scale the sin() and not the offset.
#define XOffset 0
#define YOffset (H/2.0)
#define XScale (2*PI)
#define YScale 50
y = (int) round(YScale*sin(x*XScale + XOffset) + YOffset);
Defensive programming tip: since y is calculated, insure it is in the valid index range before using it as an index.
// Assuming image` is a fixed sized array
#define Y_MAX (sizeof image/sizeof image[0] - 1)
if (y >= 0 && y <= Y_MAX) {
image[y][x][1] = 0;
image[y][x][2] = 255;
image[y][x][3] = 0;
}
y = y * 50, where y = H/2 (+ or - 1) gives you y around 25*H, which is out of bounds.
A closer approximation is this:
y = (int) ( H/2 + H/2 * sin(x*2*PI) )
which gives the extremes H/2 - H/2 = 0 and H/2 + H/2 = H, which is one too high. So, we scale not by H/2 but by (H-1)/2:
y = (int) ( H/2 + (H-1)/2 * sin(x*2*PI) )
which gives us an y-range 0 to H-1.
To have a bit more control over the period of the sine wave, let's write it like this:
sin( x/W * 2*PI )
Here, we divide x by W so that x/W itself will range from 0 to 1.
It is then scaled by 2*PI to produce a range from 0 to 2π. This will plot one period of the sine wave across the entire width. If we introduce a frequency factor f:
sin( f * x/W * 2*PI )
we can now say how many periods to draw, even fractions. For f=1 it will draw one period, f=2 two periods, and f=1 half a period.
Here's a small JS demo showing three values for f: 0.5 is red, 1 is green and 2 is white:
var c = document.getElementById('c'),
W = c.width,
H = c.height,
ctx = c.getContext('2d'),
image = ctx.getImageData(0,0,W,H);
for ( var i = 0; i < image.data.length; i +=4) {
image.data[i+0]=0;
image.data[i+1]=0;
image.data[i+2]=0;
image.data[i+3]=255;
}
function render(image,colidx,f) {
for ( var x = 0; x < W; x++ )
{
var y = H/2 - Math.round( H/2 * Math.sin(f*x/W*Math.PI*2) );
if ( y >=0 && y < H ) {
if ( colidx & 1 ) image.data[ 4*( W*y + x ) + 0] = 255;
if ( colidx & 2 ) image.data[ 4*( W*y + x ) + 1] = 255;
if ( colidx & 4 ) image.data[ 4*( W*y + x ) + 2] = 255;
}
}
}
render(image,1,0.5);
render(image,2,1);
render(image,7,2);
ctx.putImageData(image, 0,0);
canvas{ border: 1px solid red;}
<canvas id='c' width='256' height='128'></canvas>
The code then becomes:
float f = 1;
for (x = 0; x < W; x++)
{
y = (int) ( (H-1)/2 + (H-1)/2 * sin(f * x/W * 2*PI) );
image[y][x][0] = 0;
image[y][x][1] = 255;
image[y][x][2] = 0;
}
Given the following code fragment, where x is a number.
{ y >= 0 }
z = 0
n = y
while (n > 0) begin
z = z + x
n = n – 1
end
What does it compute? Prove it, showing how you derive the loop invariant.
How can I do that please?
This example is known like most correct program, because it is proved in every software verification course. Here is listing of the program with invariants on every step:
{ y >= 0 }
z = 0 // invariant: z = 0
n = y // invariant: n = y and z = 0
while (n > 0) begin // loop invariant: y * x - n * x = z
z = z + x
n = n – 1
end
// Final invariant: n = 0 and y * x = z
All theoretical details for this example are provided in my paper page 118.
For given X and Y it computes X * Y.
at the beginning, value of the Z is zero, and the N = Y (loop's variable which will countdown in our loop).
the loop executes Y times and in every time that it executes, it accumulates the X to the Z.
finally, when the N reached to 0 the loop will terminate, then the value of Z should be X * Y.