Directions: Fill in answers on the pages below. Don't spend
too much time on any one problem. All questions below ask for a
code segment, which does not need to be a complete program.
You never need any #include statements,
or the main function,
but you should declare the variables that you use.
Points for each problem: 1-15, 2-15, 3-15, 4-20, 5-35,
5i-10, 5ii-10, 5iii and iv-15.
For example, in case n == 6 it should print:
n: 6, n squared: 36
Similarly, in case n == 11 it should print:
n: 11, n squared: 121
And so forth for any n.
Answer inserted in red below.
| Problem 1: C source code | Single run |
|---|---|
#include <stdio.h>
int main() {
int n;
for (n = 1; n <= 16; n += 3)
printf("n: %i, n squared: %i\n", n, n*n);
}
| n: 1, n squared: 1 n: 4, n squared: 16 n: 7, n squared: 49 n: 10, n squared: 100 n: 13, n squared: 169 n: 16, n squared: 256 |
| IQ | What to print |
|---|---|
| > 120 | High |
| 90 - 120 | Normal |
| > 0 and < 90 | Low |
| < 0 | Invalid |
Two different answers are inserted in red below. The output is the same for each.
| Problem 2: C source code | Separate runs |
|---|---|
#include <stdio.h>
int main() {
int IQ;
scanf("%i", &IQ);
if (IQ > 120) printf("High");
else if (IQ >= 90) printf("Normal");
else if (IQ >= 0) printf("Low");
else printf("Invalid");
printf("\n");
}
-----------------------------------------------
#include <stdio.h>
int main() {
int IQ;
scanf("%i", &IQ);
if (IQ < 0) printf("Invalid");
else if (IQ >= 0 && IQ < 90) printf("Low");
else if (IQ >= 90 && IQ <= 120) printf("Normal");
else if (IQ > 120) printf("High");
printf("\n");
}
| 121 High 120 Normal 90 Normal 89 Low 0 Low -1 Invalid |
| Problem 3: C source code | Separate runs |
|---|---|
#include <stdio.h>
int main() {
int n, i;
scanf("%i", &n);
for (i = 1; i <= n; i++)
printf("%i ", i);
printf("\n");
}
| 0 (only a newline printed) 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 |
| Problem 4: C source code | Separate runs |
|---|---|
#include <stdio.h>
/* insert prototype for function ftoc here*/
double ftoc(double f);
int main() {
double f, c;
scanf("%lf", &f);
c = ftoc(f);
printf("Fahrenheit: %.2f = Centigrade: %.2f\n", f, c);
}
/* insert definition of ftoc here */
double ftoc(double f) {
return (5.0/9.0) * (f - 32.0);
}
| 212 Fahrenheit: 212.00 = Centigrade: 100.00 104 Fahrenheit: 104.00 = Centigrade: 40.00 98.6 Fahrenheit: 98.60 = Centigrade: 37.00 -40 Fahrenheit: -40.00 = Centigrade: -40.0 32 Fahrenheit: 32.00 = Centigrade: 0.00 |
double rand_double() {
return rand()/(double)RAND_MAX;
}
Each answer is given in red below.
| Problem 5 i: C source code | First run | Second run |
|---|---|---|
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double rand_double();
int main() {
int i;
srand((long)time(NULL));
for (i = 0; i < 10; i++)
printf("%20.15f\n", rand_double());
}
double rand_double() {
return rand()/(double)RAND_MAX;
}
| 0.311942531406853 0.923045916446972 0.038132391887779 0.130670174085847 0.122756679133864 0.967290503423331 0.302804329573551 0.378144093499586 0.169674427327548 0.835203382575514 | 0.304076678726858 0.400823272951331 0.089356198017186 0.612829898303761 0.069791023651972 0.881271054447289 0.424325234919938 0.857827221442865 0.844536928853270 0.767726750936232 |
| Problem 5 ii: C source code | Separate runs |
|---|---|
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double rand_double();
int main() {
srand((long)time(NULL));
if (rand_double() < 0.5) printf("HEADS\n");
else printf("TAILS\n");
}
double rand_double() {
return rand()/(double)RAND_MAX;
}
| HEADS HEADS TAILS HEADS TAILS HEADS TAILS HEADS HEADS TAILS |
It is interesting that the
following code does not work correctly:
Let's rewrite it with a final else to see
what happens. By rights "XXXXS" shouldn't be printed
at all.
if (rand_double() < 0.5) printf("HEADS\n");
else if (rand_double() >= 0.5) printf("TAILS\n");
if (rand_double() < 0.5) printf("HEADS\n");
else if (rand_double() >= 0.5) printf("TAILS\n");
else printf("XXXXS\n");
| Problem 5 ii (wrong): C source code | Separate runs |
|---|---|
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double rand_double();
int main() {
srand((long)time(NULL));
if (rand_double() < 0.5) printf("HEADS\n");
else if (rand_double() >= 0.5) printf("TAILS\n");
else printf("XXXXS\n");
}
double rand_double() {
return rand()/(double)RAND_MAX;
}
| HEADS HEADS XXXXS HEADS TAILS HEADS TAILS HEADS HEADS XXXXS |
To see what's going on here, let's flip many times and see how many times HEADS, TAILS and XXXXS come up. Why are we getting the answers below?
| Problem 5 ii (wrong): C source code | Separate runs |
|---|---|
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double rand_double();
int main() {
int heads = 0, tails = 0, xxxxs = 0;
int i;
srand((long)time(NULL));
for (i = 0; i < 1000000; i++) {
if (rand_double() < 0.5) heads++;
else if (rand_double() >= 0.5) tails++;
else xxxxs++;
}
printf("Heads: %i\n", heads);
printf("Tails: %i\n", tails);
printf("xxxxs: %i\n", xxxxs);
}
double rand_double() {
return rand()/(double)RAND_MAX;
}
| Heads: 499740 Tails: 250787 xxxxs: 249473 Heads: 500692 Tails: 249735 xxxxs: 249573 Heads: 500806 Tails: 249483 xxxxs: 249711 Heads: 50000554 Tails: 25002448 xxxxs: 24996998 Heads: 500025584 Tails: 249992600 xxxxs: 249981816 |
The answer is in red below, with extra code in black and 8 increasingly large runs.
| Problem 5 iii and iv: C source code | |||
|---|---|---|---|
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define N 1000
double rand_double();
int main() {
double x, y;
int i, count = 0;
srand((long)time(NULL));
for (i = 0; i < N; i++) {
x = rand_double() - 0.5;
y = rand_double() - 0.5;
if (x*x + y*y < 0.25) count++;
}
printf("N: %i\n", N);
printf("Count: %i\n", count);
printf("Ratio : %0.8f\n", (double)count/N);
printf("Pi Approx: %0.8f\n", 4.0*(double)count/N);
printf("Pi Exact : %0.8f\n", 4.0*atan(1.0));
printf("Error : %0.8f\n", 4.0*atan(1.0) - (double)count/N);
}
double rand_double() {
return rand()/(double)RAND_MAX;
}
| |||
| Separate Runs | |||
N: 1000 Count: 772 Ratio : 0.77200000 Pi Approx: 3.08800000 Pi Exact : 3.14159265 Error : 0.05359265 | N: 10000 Count: 7853 Ratio : 0.78530000 Pi Approx: 3.14120000 Pi Exact : 3.14159265 Error : 0.00039265 | N: 100000 Count: 78573 Ratio : 0.78573000 Pi Approx: 3.14292000 Pi Exact : 3.14159265 Error :-0.00132735 | N: 1000000 Count: 785150 Ratio : 0.78515000 Pi Approx: 3.14060000 Pi Exact : 3.14159265 Error : 0.00099265 |
N: 10000000 Count: 7853602 Ratio : 0.78536020 Pi Approx: 3.14144080 Pi Exact : 3.14159265 Error : 0.00015185 | N: 100000000 Count: 78541857 Ratio : 0.78541857 Pi Approx: 3.14167428 Pi Exact : 3.14159265 Error :-0.00008163 | N: 1000000000 Count: 785407434 Ratio : 0.78540743 Pi Approx: 3.14162974 Pi Exact : 3.14159265 Error :-0.00003709 | N: 1000000000 Count: 785346724 Ratio : 0.78534672 Pi Approx: 3.14138690 Pi Exact : 3.14159265 Error : 0.00020575 |
This simulation is just comparing the area of the square below (which is 1) with the area of the circle inside (which is pi*r2 = pi*(0.5)2 = pi/4 = 0.785398163). Thus points are chosen at random from the whole square, but only those inside the circle are "counted", and the result is to approximate the value of pi/4.

Another way to think about this example
is to consider a function f defined for two
variables x and y,
where we must have -0.5 < x < 0.5
and -0.5 < y < 0.5:
Then the program computes an approximation to the integral
of f over the region specified by the valid
values of x and y.
In other words, it is the volume trapped underneath
the "surface" z = f(x, y).
This same method would work for any such function, even
one for which the exact calculation was hard or impossible.
z = f(x, y) = 1, if x2 + y2 < 0.5
z = f(x, y) = 0, if x2 + y2 > 0.5