Dynamic Scope in C - c

I just have a problem with C dynamic scoping in the following code. I am aware that C only uses static (lexical) scoping, but the problem asks to pretend that we are using dynamic scoping.
#include <stdio.h>
int x = 25;
int y = 15;
int z = 5;
static void func1(int z) {
x += 20;
y += 30;
z += 40;
printf("func1: x=%4d y=%4d z=%4d x+y+z=%d\n",x,y,z,x+y+z);
}
static void func2(void) {
int z = 100;
y += 30;
z += 10;
func1(20);
printf("func2: x=%4d y=%4d z=%4d x+y+z=%d\n",x,y,z,x+y+z);
}
static void func3(int x) {
x += 40;
func2();
printf("func3: x=%4d y=%4d z=%4d x+y+z=%d\n",x,y,z,x+y+z);
}
static int func4() {
int y = 90;
func3(80);
printf("func4: x=%4d y=%4d z=%4d x+y+z=%d\n",x,y,z,x+y+z);
return 1000;
}
int main(int arc, char *argv[]) {
int y = func4();
z += 2000;
printf("main: x=%4d y=%4d z=%4d x+y+z=%d\n",x,y,z,x+y+z);
}
The following is the result of all 5:
func1: x = 140 y=? z =? x+y+z = 350
func2: x = ? y=? z =? x+y+z = 400
func3: x = ? y=? z =? x+y+z = 295
func4: x = ? y=? z =? x+y+z = 180
main: x = ? y=? z =? x+y+z = 3030
From my understanding, we go from main first and then to the next function called. So, in main, we have:
x = 25 (from global variable),
y = 1000 (from return 1000 from func4), and
z = 2005 (from global variable 5 + 2000)
x + y +z = 25 + 1000 + 2005 = 3030 -> correct.
But, in the other functions, such as in func4:
variable x = 25 (from main from global)
y = 90 (from local variable)
z = 5 (from global variable)
x + y + z = 25 + 90 + 5 = 120 -> incorrect.
This problem persists on the other functions, where I think I find the correct for 1 or 2 variables but have no idea for the last one.

Related

#29 expected expression - C compilation

I'm programing on Code Composer Studio a program that generate and show a sinusoid, this program should normally be implemented in a DSP, but since I don't have the DSK I'm just compiling it and trying to show the result in CCS.
I'm having a problem in the line 18 it shows that an expression is expected and I don't know why. I checked all comas and () {} and it seems correct.
#include <math.h>
#include <stdio.h>
const int sine_table[40] = { 0, 5125, 10125, 14876, 19260, 23170, 26509, 29196, 31163, 32364, 32767, 32364, 31163, 29196, 26509, 23170, 19260, 14876, 10125, 5125, 0, -5126, -10126, -14877, -19261, -23171, -26510, -29197, -31164, -32365, -32768, -32365, -31164, -29197, -26510, -23171, -19261, -14877, -10126, -5126 };
int i = 0;
int x1 = 0;
int x2 = 0;
float y = 0;
float sin1(float phase) {
x1 = (int) phase % 40; if (x1 < 0) x1 += 40; x2 = (x1 + 1) % 40;
y = (sine_table[x2] - sine_table[x1]) * ((float) ((int) (40 * 0.001 * i * 100) % 4100) / 100 - x1) + sine_table[x1];
return y;
}
int main(void) {
double pi = 3.1415926535897932384626433832795;
for (int i = 0; i < 1000; i++) {
float x = 40 * 0.001 * i;
float radians = x * 2 * pi / 40;
printf("%f %f %f\n", x, sin1(x) / 32768, sin(radians));
i = i + 1;
}
}

How do I implement a direct form II transfer function?

I need to implement a transfer function from direct form II. Here's a description of what direct form II is. I'm allowed to choose what coefficents are to be included.
So far my code looks like this:
int main(void)
{
int l, m;
l = dirii2(2); // l = -82;
//m = directii(2);
return l;
}
int dirii2(int x)
{
int y = 0; // output // 3 is constant of array size.
static int v[3] = {6,4,0};
int b[3] = {3,5,2}, a[2] = {3,6};
int q0, q1, q2;
for (int i = 0; i < 3 ; i++) {
q0 = x; // q0 = x = 2
q1 = a[2-2]*v[2-1]; // q1 = 3 * 6 = 18
q2 = a[2-1]*v[2-2]; // q2 = 6 * 4 = 24
v[2] = q0 - q1 - q2;// v(n) = x(n) - a1*v(n-1) - a2v(n-2); // v = 2 - 18 - 24 = -40
y =+ b[i]*v[2-i];// + b[1]*v[2-1]+b[2]*v[2-2];
v[0] = v[1];
v[1] = v[2];
}
return y;
}
When I run the code the result y gains or loses values rapidly like it's getting unstable:
First iteration y becomes -138.
Second iteration y becomes 230.
Third iteration y becomes -92.
Did I write the code right?

Find Mystery Nums M/N

I am pretty sure I got this right just want to make sure though... In the following code, we have omitted the definitions of constants M and N
here are the two functions in question arith and optarith:
#define M /* Mystery number 1 */
#define N /* Mystery number 2 */
unsigned int arith(unsigned int x, unsigned int y){
unsigned int result = 0;
result = x * M + y/N;
return result;
}
We compiled this code for particular values of M and N. The compiler optimized the multiplication and
division. The following is a translation of the generated machine code back into C:
unsigned int optarith(unsigned int x, unsigned int y){
unsigned int t = 3 * x;
x <<= 6;
x -= 2 * t;
y >>= 4;
y = y/3;
return x + y;
}
so here's my work
so to find value M for the operation M * x
x <<= 6; // same as x = x * 64
x-= 2 * t; //same as x = x - 2 * (3 * x)
so basically x = 64x - 6x which is just 58x therefore M = 58
and to find the value N for operation y/N
y >>= 4; same as y = y/16;
y = y/3; same as y = (y/16)/3;
that makes y/48 so N = 48
Did I do this correctly?

C loop with steps smaller than 1

So I'm wondering, how do I make sure that all steps in a loop are performed if the step size is smaller than 1? Take this loop for instance:
for (float y, x = -1.0; x <= 1.0; x += 0.1) {
y = (4*x*x*x) + (3*x*x) + (5*x) - 10;
printf("x = %.2f, y = %.2f\n", x, y);
}
Output:
x = -1.00, y = -16.00
x = -0.90, y = -14.99
x = -0.80, y = -14.13
x = -0.70, y = -13.40
x = -0.60, y = -12.78
x = -0.50, y = -12.25
x = -0.40, y = -11.78
x = -0.30, y = -11.34
x = -0.20, y = -10.91
x = -0.10, y = -10.47
x = 0.00, y = -10.00
x = 0.10, y = -9.47
x = 0.20, y = -8.85
x = 0.30, y = -8.12
x = 0.40, y = -7.26
x = 0.50, y = -6.25
x = 0.60, y = -5.06
x = 0.70, y = -3.66
x = 0.80, y = -2.03
x = 0.90, y = -0.15
I intend the loop to also run for x = 1, but as you can see it doesn't do that. I've heard that it's not safe to use floats as loop counters, as the float precision isn't exact. The fact that I'm using a float variable as the loop counter is probably the cause of my problem. So what solutions are there to my problem? Thanks in advance for your kind responses!
The problem, as you noted, is that you shouldn't use floats as loop counters. So multiply everything by 10 and use integers:
for (int x = -10; x <= 10; ++x) {
float y = (0.004*x*x*x) + (0.03*x*x) + (0.5*x) - 10;
printf("x = %.2f, y = %.2f\n", 0.1*x, y);
}
Produces:
x = -1.00, y = -16.00
x = -0.90, y = -14.99
x = -0.80, y = -14.13
...
x = 0.90, y = -0.15
x = 1.00, y = 2.00
as expected.
Perhaps even better: logically separate your loop variable from the meaningful stuff.
for(int i = -10; i <= 10; ++i) {
float x = 0.1 * i;
float y = (4*x*x*x) + (3*x*x) + (5*x) - 10;
printf("x = %.2f, y = %.2f\n", x, y);
}

Need help finding the complexity of this algorithm

Hi I need help finding the complexity of this algorithm.
Could you please answer the complexity line by line not just the final result?
The algorithm is the following one:
int algorithm(int x)
{
int y = 1;
while (y <= x-1)
{
int z = y*2;
while (z <= x)
{
int w = 1;
while (w <= z)
{
w++;
}
z++;
}
y++;
}
}
Any help would be appreciated!
Thanks
int algorithm(int x)
{
int y = 1;
while (y <= x-1) // <<< loop 1
{
int z = y*2;
while (z <= x) // <<< loop 2
int w = 1;
while (w <= z) // <<< loop 3
{
w++;
}
z++;
}
y++;
}
}
Let's break it down.
Loop 1: you go around (x-1) times: we call this O(x). Easy.
Loop 2: We start Z with 2*y, so 2, 4, 6, ... From there we go until x. Let's add them up:
sum((x-2) + (x-4) + (x-6) + ... + (x - x)) =
x * x / 2 - 2 * (1+2+3+...+x/2) =
x * x / 2 - 2 * (x/2)*(x/2+1) / 2 ~
x * x / 2 - x * x / 4 =
x * x / 4
= O(x^2)
Now the innermost loop: it goes from w = 1 to w = z; so it loops z times. And we know that
z = 2, 4, 6, ... x
So the innermost loop adds something of the order of x (x/2... same thing).
Combining the O(x) of loop 3 with the O(x^2) of loop 2 (which included the effect of the first loop) we conclude the "algorithm" is of order x^3. To verify, we can modify your code:
#include <stdio.h>
int algorithm(int x)
{
int c = 0;
int y = 1;
while (y <= x-1)
{
int z = y*2;
while (z <= x)
{
int w = 1;
while (w <= z)
{
c++; // count complexity
w++;
}
z++;
}
y++;
}
return c;
}
int main(void) {
int ii;
for(ii = 200; ii <= 400; ii+=10) {
printf("%d %d\n", ii, algorithm(ii));
}
}
The output is:
200 1338350
210 1549030
220 1780735
230 2034465
240 2311220
250 2612000
260 2937805
270 3289635
280 3668490
290 4075370
300 4511275
310 4977205
320 5474160
330 6003140
340 6565145
350 7161175
360 7792230
370 8459310
380 9163415
390 9905545
400 10686700
Plotting this on a lin-log plot, you get a pretty straight line.
When you take the ratio of algorithm(400) / algorithm(300), you get 2.369. And when you take (400/300)^3, the answer is 2.370. I think that is close enough to be convincing.
Following the formal steps below (I hope you're comfortable with Sigma Notation), you'll be able to obtain the exact order of growth of your algorithm:

Resources