I'm assuming this is impossible, but I've seen plenty of crazy preprocessor magic before so I thought I'd ask. Can the preprocessor insert code after every statement between two points?
For example, I have the following code:
// ...
dy2 = dy2 + (rand()%3) - 1; swapTask();
if (dy2 < D2Upper) dy2 = D2Upper; swapTask();
if (dy2 > D2Lower) dy2 = D2Lower; swapTask();
dy2 = (dy2+9) >= dy1 ? dy1-9 : dy2; swapTask();
if (direction2 > 0)
{
memcpy(&pk[dy2+0][direction2+7], "_", 1); swapTask();
memcpy(&pk[dy2+1][direction2+6], "/o\\", 3); swapTask();
memcpy(&pk[dy2+2][direction2+4], "</ _<", 5); swapTask();
memcpy(&pk[dy2+3][direction2+3], "</ /", 4); swapTask();
memcpy(&pk[dy2+4][direction2+2], "</ ==x", 6); swapTask();
memcpy(&pk[dy2+5][direction2+3], "/ \\", 4); swapTask();
memcpy(&pk[dy2+6][direction2+2], "//)__)", 6); swapTask();
memcpy(&pk[dy2+7][direction2+0], "<<< \\_ \\_", 9); swapTask();
if (++direction2 > D2Right)
direction2 = -direction2; swapTask();
}
// ...
I need to call swapTask(); after each statement. This becomes bothersome over time (especially if I want it to look nice and aligned).
Originally I thought of programmatically adding it to each line, but that obviously breaks block-less if statements. Then I thought of adding it after each semicolon, but that obviously breaks for statements. Is there any preprocessor, compiler, or other method of magic that can call this after each line? Thanks.
Related
I want to see if all surrounds of a cell in a 2d array are something , or do something with them.
if (mapmines[rndr][rndc] != 9) {
mapmines[rndr][rndc] = 9;
if (mapmines[rndr - 1][rndc - 1] != 9)
mapmines[rndr - 1][rndc - 1]++;
if (mapmines[rndr - 1][rndc] != 9)
mapmines[rndr - 1][rndc]++;
if (mapmines[rndr - 1][rndc + 1] != 9)
mapmines[rndr - 1][rndc + 1]++;
if (mapmines[rndr][rndc - 1] != 9)
mapmines[rndr][rndc - 1]++;
if (mapmines[rndr][rndc + 1] != 9)
mapmines[rndr][rndc + 1]++;
if (mapmines[rndr + 1][rndc - 1] != 9)
mapmines[rndr + 1][rndc - 1]++;
if (mapmines[rndr + 1][rndc] != 9)
mapmines[rndr + 1][rndc]++;
if (mapmines[rndr + 1][rndc + 1] != 9)
mapmines[rndr + 1][rndc + 1]++;
I have this similir code exept with diferent code between if
can i make a function or reduce? i feel like its posible .
if (mapmines[rndr][rndc] != 9)
{
// Do all elements in a 3x3 grid:
for (i = -1; i <= 1; ++i)
for (j = -1; j <= 1; ++j)
if (mapmines[rndr+i][rndc+j] != 9)
++mapmines[rndr+i][rndc+j];
/* Set the center element afterward so we do not care about the
loop above modifying it (gives brevity, not efficiency):
*/
mapmines[rndr][rndc] = 9;
}
That said, preferable code for this may be significantly affected by the context, including how frequently the condition occurs, interactions between the rows and columns, and more. There may be other data structures that are more useful. You would have to give more context.
Well, you could make it a bit smaller with a function like this:
void incrementIfNotNine(int *cell) {
if(*cell != 9) (*cell)++;
}
and then call it like this:
incrementIfNotNine(&mapmines[rndr - 1][rndc - 1]);
incrementIfNotNine(&mapmines[rndr - 1][rndc]);
incrementIfNotNine(&mapmines[rndr - 1][rndc + 1]);
...
You could also use loops, but for a 3x3 grid, it's hardly worth it.
It's just a super basic program that finds the roots of a quadratic function. After the calculations the output for the solutions shows "-nanloat" instead of the actual answer. Here's the problematic code:
/*If the polynomial has real solutions, calculate and print them */
if (nRSolutions > 0){
sol = ((-b + sqrt(pow(2.0,b) + 4 * a * c)) / (2.0 * a));
printf("La solución a la ecuación es %float", sol);
/*That means "the solution to the equation is (float)"*/
}
if (nRSolutions = 2){
sol2 = ((-b - sqrt(pow(2.0,b) + 4 * a * c)) / (2.0 * a));
printf("La segunda solución a la ecuación es %float", sol2);
/*That means "the second solution to the equation is (float)"*/
}
Here's the variable declaration in case that might be part of the problem, but I really don't think that's it.
/* d = discriminant value; sol = solution; sol2 = second solution*/
float a, b, c, d, sol, sol2;
int nRSolutions;
nRSolutions = 0;
They are all defined afterwards.
Here's your problem:
if (nRSolutions = 2){
You're not comparing but assigning, and since the value you're assigning is nonzero the condition will always be true. You instead want:
if (nRSolutions == 2){
Wrong equation (in addition to issue identified by#dbush). See Quadratic formula:
// sqrt(pow(2.0,b) + 4 * a * c))
sqrt(pow(b, 2.0) - 4 * a * c))
// ^^^^^^^^^^^ ^
Even better as
double discriminate = b*b - 4*a*c;
if (discriminate < 0.0) TBD_code();
else sol = (-b + sqrt(discriminate)) / (2.0 * a);
Tip for improve precision: minimize subtraction cancellation
double discriminate = b*b - 4*a*c;
if (discriminate < 0.0) TBD_code();
// Add or subtract such that the result is larger
if (b < 0) sol = (-b + sqrt(discriminate)) / (2.0 * a);
else sol = (-b - sqrt(discriminate)) / (2.0 * a);
// We know a*sol*sol2 == c
sol2 = sol ? 0.0 : c/a/sol;
My code is below :
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int* new = (int*)malloc(sizeof(int) * (nums1Size+nums2Size));
int i = 0;
int count1 = 0;
int count2 = 0;
if(nums1Size+nums2Size == 1){
if(nums1Size == 1)
return *nums1;
else
return *nums2;
}
else if(nums1Size == 0){
if((nums2Size & 0x1) == 0)
return (double)(nums2[nums2Size/2-1]+nums2[nums2Size/2])/2;
else
return (double)nums2[nums2Size/2];
}
else if(nums2Size == 0){
if((nums1Size & 0x1) == 0)
return (double)(nums1[nums1Size/2-1]+nums1[nums1Size/2])/2;
else
return (double)nums1[nums1Size/2];
}
while(i != (nums1Size+nums2Size))
{
if((nums1[count1 == nums1Size ? count1-1:count1] > nums2[count2 == nums2Size ? count2-1:count2]
&& (count2) != nums2Size)
|| (count1) == nums1Size)
{
*(new+i) = *(nums2+count2);
count2++;
}
else{
*(new+i) = *(nums1+count1);
count1++;
}
i++;
}
if(((nums1Size+nums2Size) & 0x1) == 0){
return (double)(new[(nums1Size+nums2Size)/2 - 1] + new[(nums1Size+nums2Size)/2]) / 2;
}
else
return (double)new[(nums1Size+nums2Size)/2];
}
And below is the submissions's runtime distribution on Leetcode :
The Question is, even if there are a lot of submitted codes with O(log (m+n)) in C but I think my code's Time complexity is O(m+n). so it doesn't make sense that my code is top 2% on Leetcode according to the distribution graph. of course linear is faster than log to a small amount of inputs but the test-cases are enough big to get beaten by O(log (m+n)). I don't know why my code get passed with that rate.
will greatly appreciate your comments!
From my top comment: You allocate new at the start of the function. If any of the "early escape" return statements are executed, you'll leak memory.
So do I have to put free() in every return statement? or how can i fix my code?
Don't do the malloc until after the top block of early escapes.
And, do the free at the bottom. To do this, you'll need an extra variable to hold the return value so you can safely do the free(new) (e.g. double retval;)
Side note: It's usually cleaner to replace (e.g.) *(new + i) with new[i]. Also, holding the code to <= 80 chars / line is also a good style.
Here's one way to fix your code [please pardon the gratuitous style cleanup]:
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
int *new;
int i;
int count1 = 0;
int count2 = 0;
double retval;
if (nums1Size + nums2Size == 1) {
if (nums1Size == 1)
return *nums1;
else
return *nums2;
}
if (nums1Size == 0) {
if ((nums2Size & 0x1) == 0)
return (double) (nums2[nums2Size / 2 - 1] +
nums2[nums2Size / 2]) / 2;
else
return nums2[nums2Size / 2];
}
if (nums2Size == 0) {
if ((nums1Size & 0x1) == 0)
return (double) (nums1[nums1Size / 2 - 1] +
nums1[nums1Size / 2]) / 2;
else
return (double) nums1[nums1Size / 2];
}
// allocate this only when you're sure you'll use it
new = malloc(sizeof(int) * (nums1Size + nums2Size));
for (i = 0; i != (nums1Size + nums2Size); ++i) {
if ((nums1[count1 == nums1Size ? count1 - 1 : count1] >
nums2[count2 == nums2Size ? count2 - 1 : count2] &&
(count2) != nums2Size)
|| (count1) == nums1Size) {
new[i] = nums2[count2];
count2++;
}
else {
new[i] = nums1[count1];
count1++;
}
}
if (((nums1Size + nums2Size) & 0x1) == 0) {
retval = (double) (new[(nums1Size + nums2Size) / 2 - 1] +
new[(nums1Size + nums2Size) / 2]) / 2;
}
else
retval = (double) new[(nums1Size + nums2Size) / 2];
free(new);
return retval;
}
But, personally, I dislike multiple return statements in a function. It's harder to debug [using gdb] because you'd have to set a breakpoint on each return.
Here's a version that uses a do { ... } while (0); as a "once through" loop that allows us to eliminate the if/else "ladder" logic [which I also personally dislike] and have only a single return at the bottom. YMMV ...
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
int *new = NULL;
int i = 0;
int count1 = 0;
int count2 = 0;
double retval;
do {
if (nums1Size + nums2Size == 1) {
if (nums1Size == 1)
retval = *nums1;
else
retval = *nums2;
break;
}
if (nums1Size == 0) {
if ((nums2Size & 0x1) == 0)
retval = (double) (nums2[nums2Size / 2 - 1] +
nums2[nums2Size / 2]) / 2;
else
retval = nums2[nums2Size / 2];
break;
}
if (nums2Size == 0) {
if ((nums1Size & 0x1) == 0)
retval = (double) (nums1[nums1Size / 2 - 1] +
nums1[nums1Size / 2]) / 2;
else
retval = (double) nums1[nums1Size / 2];
break;
}
// allocate this only when you're sure you'll use it
new = malloc(sizeof(int) * (nums1Size + nums2Size));
for (; i != (nums1Size + nums2Size); ++i) {
if ((nums1[count1 == nums1Size ? count1 - 1 : count1] >
nums2[count2 == nums2Size ? count2 - 1 : count2] &&
(count2) != nums2Size)
|| (count1) == nums1Size) {
new[i] = nums2[count2];
count2++;
}
else {
new[i] = nums1[count1];
count1++;
}
}
if (((nums1Size + nums2Size) & 0x1) == 0) {
retval = (double) (new[(nums1Size + nums2Size) / 2 - 1] +
new[(nums1Size + nums2Size) / 2]) / 2;
}
else
retval = (double) new[(nums1Size + nums2Size) / 2];
} while (0);
if (new != NULL)
free(new);
return retval;
}
UPDATE:
thanks! I understood. your code is more clear than mine for real!. but what do you think about the performance between them? ( if/else and do{...}while(0)). because if we assume the compiler would work as we generally expect, if/else is faster than if if which is in do{...} in the revised code. thanks a lot again!
Actually, if we disassemble both versions [compiled with -O2], the do/while version is 4 assembly instructions shorter.
But, in order to tune it, you have to measure it.
The optimizer will pretty much make them similar.
The main bulk of the time of the function is spent in the for loop, which is the same for both. The speed of the loop dwarfs any extra overhead of do/while which might be an assembler instruction or two [but, again the do/while has fewer instructions].
So, tuning/optimizing the prolog/epilog code of the function isn't [usually] worth it. Speeding up the loop is.
To tune/optimize, either do profiling to determine where the code spends the most amount of time [or for something this simple, it's obviously the loop], or add timestamping and get elapsed time on the function [or various subparts].
As I mentioned, it's hard to add a breakpoint for a function that has multiple return statements.
Also, sometimes you can't attach a debugger. Or, it's difficult to find a meaningful place to put a breakpoint. For example, if you have a program that runs fine for (e.g.) days, and then aborts after (e.g.) 63 hours, you may need to do internal benchmarking and printf style debugging:
#ifdef DEBUG
#define dbgprint(_fmt) \
do { \
printf(_fmt); \
} while (0)
#else
#define dbgprint(_fmt) \
do { \
} while (0)
#endif
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
double retval;
dbgprint("findMedianSortedArrays: ENTER nums1Size=%d nums2Size=%d\n",
nums1Size,nums2Size);
// ... the code
dbgprint("findMediaSortedArrays: EXIT retval=%g\n",retval);
return retval;
}
It's much easier to insert the debug print statements with the second version.
BTW, I do this sort of thing all the time. And, one of my fortes is fast code and performance improvement [as I do a lot of realtime coding].
I've a problem, i'm stuck with some underflow problem for my algorithm.
I'm basically dseisgning a path from a Bezier curve and to deal with this I had to work with some vector multiplication (cross and dot product) in order to have the angle between two vectors and the clock-counterclock direction from one to another one.
The problem is that when the path is a straight line one of the control variable has problem of underflow, basically blocking the execution and causing errors.
Here is the code:
void BezierInterp() {
NumOfSetpoints = 10;
float seqTH[11];
float orient[10];
float divider;
math.MatrixMult((float*) BCoeff, (float*) waypointX, 11, 4, 1,
(float*) setpoint0);
math.MatrixMult((float*) BCoeff, (float*) waypointY, 11, 4, 1,
(float*) setpoint1);
float dx1, dy1, dx2, dy2, dxy1, dxy2, dir;
dx1 = cos(state[2]);
dy1 = sin(state[2]);
dx2 = setpoint0[1] - setpoint0[0];
dy2 = setpoint1[1] - setpoint1[0];
dxy2 = sqrt(sq(dx2) + sq(dy2));
dir = dx1 * dy2 - dx2 * dy1;
if (dxy2<0.0001 && dxy2>-0.0001) {
seqTH[0] = 0.0;
}
else{
if (dir >= 0) {
seqTH[0] = acos((dx1 * dx2 + dy1 * dy2) / (dxy2));
} else {
seqTH[0] = -acos((dx1 * dx2 + dy1 * dy2) / (dxy2));
}}
for (uint8_t i = 1; i <= 9; i = i + 1) {
dx2 = setpoint0[i + 1] - setpoint0[i];
dy2 = setpoint1[i + 1] - setpoint1[i];
dxy2 = sqrt(sq(dx2) + sq(dy2));
dx1 = setpoint0[i] - setpoint0[i - 1];
dy1 = setpoint1[i] - setpoint1[i - 1];
dxy1 = sqrt(sq(dx1) + sq(dy1));
dir = dx1 * dy2 - dx2 * dy1;
divider= dxy1 * dxy2;
if (divider<0.0001 && divider>-0.0001) {
seqTH[0] = 0.0;
}
else {
if (dir >= 0) {
seqTH[i] = acos((dx1 * dx2 + dy1 * dy2) / (divider));
} else {
seqTH[i] = -acos((dx1 * dx2 + dy1 * dy2) / (divider));
}}
}
print_array("seqTh", seqTH, 11, 6);
orient[0] = state[2] + seqTH[0];
if (orient[0]<0.0001 && orient[0]>-0.0001){orient[0]=0.0001;}
for (uint8_t i = 1; i <= 9; i = i + 1) {
orient[i] = orient[i - 1] + seqTH[i];
if (orient[i]<0.0001 && orient[i]>-0.0001){orient[i]=0.0001;}
}
print_array("orient", orient, 10, 6);
for (uint8_t i = 1; i <= 9; i = i + 1) {
setpoint2[i] = orient[i - 1];
setpoint3[i] = Vref * cos(orient[i - 1]);
setpoint4[i] = Vref * sin(orient[i - 1]);
}
setpoint2[10] = orient[9];
setpoint3[10] = 0;
setpoint4[10] = 0;
setpoint5[10] = 0;
}
}
As you see in the attempt to avoid error I put several if conditions, but was not enough.
Actually the problem come probably from dir=dx1 * dy2 - dx2 * dy1;. that's when moving along x or y axis is too small to be a float.
A friend suggested to use a boolean value but I'm not sure how.
Maybe defining boolean dir; and then if the value is too small will be a 0 otherwise will be considered a 1 and in that case I could use the same procedure i'm using now for the detection of the direction.
Do you have any suggestion or maybe a different solution?
Thanks in advance
Ned
I'm not familiar with the method you're using, but when I've done this in the past I've detected the degenerate case of the Bezier (where the two end points and two control points fall on a straight line) as a special case.
This is also much faster to draw of course.
I have several equations that will return the binary value for each of the three bits in my number.
I am programing this in C which is a new language for me.
So let's say my equations return Y0 = 1 , Y1 = 0 and Y2 = 1 (101); I want to store that value as 5.
Is this possible in C if these values are returned by different equations?
I know how to do it by multiplying, but I am looking for a function or something which I imagine is already built into C.
No such luck. You have to multiply (or shift, which is the same)
unsigned Y0 = 1, Y1 = 0, Y2 = 1, val;
val = (Y0 * 4) + (Y1 * 2) + (Y2 * 1); /* parens */
val = (Y0 << 2) + (Y1 << 1) + (Y2 << 0); /* redundant */
Just bitshift:
Y0 | (Y1 << 1) | (Y2 << 2)
There is no such function in the C standard library.
You will need to do:
int x = (Y2 << 2) | (Y1 << 1) | (Y0 << 0);
Although not very popular, you do have an alternative, in that you can use bit fields to perform the type of operation you're talking about. So, on ideone, the following code would perform the action you've suggested.
union combine {
struct bits{
int x: 1;
int y: 1;
int z: 1;
int pad : 29;
} bitvalues;
int value;
};
int main() {
union combine test;
test.bitvalues.x = 1;
test.bitvalues.y = 0;
test.bitvalues.z = 1;
test.bitvalues.pad = 0;
printf("result: %d\n", test.value);
return 0;
}
It's important to note however, that because you're using a combination of a bitfields and a union, this is not a portable solution. It is dependent on the order that you define your bits in, matching the bit/byte order for integer on that machine. So, there is a way to do it without bit shifting, but you're almost certainly better off going with the bit shifting solution.