I have a square rotating in the console, but I get some holes. How can I fill it correctly?
#include <stdio.h>
#include <Windows.h>
#include <math.h>
void moveTo (int x, int y)
{
COORD coord = { x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
double round (double number)
{
return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5);
}
double deg2rad (double a)
{
double pi = 3.14159265358979323846;
return a * pi / 180.0;
}
int main ()
{
int w = 8;
int h = 8;
int cx = 20;
int cy = 10;
double a = 0;
while (1)
{
system("cls");
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
double xx = x - 4;
double yy = y - 4;
double fx = xx * cos(a) - yy * sin(a);
double fy = xx * sin(a) + yy * cos(a);
int ix = cx + round(fx);
int iy = cy + round(fy);
moveTo(ix, iy);
printf("X");
}
}
a += deg2rad(15.0);
Sleep(100);
}
return 0;
}
Not an actual answer
Aparently your code will always print the same number of X in the screen, even though this might not be always the case.
I think you shouldn't be recalculating the positions of each predefinedX but instead calculate the geometry of the lines around the square and fill the space between with Xs, as many as necessary until it hit the opposite border or something.
An alternative solution could be doubling the "density" of your square:
int w = 8*2;
int h = 8*2;
int cx = 20*2;
int cy = 10*2;
...
moveTo(ix/2, iy/2);
This should double print some dots, but should also fill gaps.
Related
EDIT: I've added the main, factorial, and trapGamma function to give the full picture but I am specifically talking about the for loop for iSum in the I function.
Basically I've run out of ideas and exhausted everywhere I know of to find an answer to this. I need to code a program that will compute a complex function which represents an M/M/1 queue.
The function includes sub functions such as calculating the integral of a gamma function and computing factorials. I've written all the code for the computations but my sum is giving me huge numbers when I would expect nothing higher than about .35
#include <math.h>
#include <stdio.h>
double I(int k, double t);
double trapGamma(double z);
unsigned long long int factorial(unsigned int n);
int main()
{
int k;
int i = 0;
double dt = 0.1;
printf("Ikx = [ \n");
for (t = 14.0 ; t <= 15.0; t += dt)
{
printf("%f " , t);
for (k = 1 ; k <= 10 ; k++)
{
I(k, t);
printf("%f " , I(k, t));
}
printf("\n");
}
printf(" ];\n");
return (0);
}
double I(int k, double t)
{
unsigned long long int x;
unsigned int n = 20;
double numerator, y, pow1, c;
double iSum;
double Ix;
int i = 0;
iSum = 0.0;
Ix = 0.0;
a = .25 * pow(t , 2);
b = pow(a, i);
x = factorial(n);
y = trapGamma(k + i + 1);
iSum = (b / (x * y));
//This is the sum loop that I'm having trouble with, I've broke the iSum equation down for my own readability while coding right above this comment
for (i = 0; i <= 100 ; i++)
{
iSum += i;
}
Ix = (pow((.5 * t), k) ) * iSum;
return Ix;
}
/*
I've checked both the factorial and trapGamma functions and they are giving me the expected results.
*/
unsigned long long int factorial(unsigned int n)
{
if(n <= 1)
return 1;
else
return (n * factorial(n - 1));
}
double trapGamma (double z)
{
int i , N = 100;
double gamma;
double a = 0.0;
double b = 15.0;
double x1, x2, y1, y2;
double areai;
double w = (b - a) / N;
gamma = 0.0;
for (i = 1; i < N; i++)
{
x1 = a + ((i - 1) * w); //the left bound point
x2 = a + (i*w); //the right bound point
y1 = pow(x1,z - 1)*exp(-x1); //the height of our left bound
y2 = pow(x2, z - 1)*exp(-x2); //the height of our right bound
areai = ((y1 + y2) / 2.0) * (x2 - x1);
gamma += areai;
}
return gamma;
}
This is building upon another project where I used a bessel function to create the M/M/1 queue over a 60 second span so I can see what this one is supposed to be. I've checked both my trapGamma and factorial functions results on there own and they are both working as expected.
How are summations supposed to be coded?
If the intent of the posted code is to calculate the modified Bessel function I, there are some pitfalls and useful semplifications to be aware of. Given
Trying to calculate the factorial, the value of the Gamma function, their product and the powers separately for each term of the sum leads to integer overflow sooner than later.
It's better to update the value of each addend of the sum instead.
Also, given that k is a whole, we have Γ(n) = (n - 1)!
The addends are increasingly smaller and, after some iterations, too small to be added to the sum, given the limited precision of type double.
// Evaluates x^k / k! trying not to overflow
double power_over_factorial(double x, int k)
{
double result = 1.0;
for ( int i = 1; i <= k; ++i )
{
result *= x / i;
}
return result;
}
#define MAX_ITERS 20
double modified_Bessel_I(int k, double x)
{
x /= 2;
const double xx = x * x;
double partial = power_over_factorial(x, k);
double old_sum, sum = partial;
int m = 1;
do
{
old_sum = sum;
partial *= xx / ((m + k) * m);
sum += partial;
}
while ( old_sum != sum && ++m < MAX_ITERS );
return sum;
}
Testable here.
I have an assignment to code a program to calculate cos(x) through the Maclaurin approximation. However I must use a function for the cos(x) and another one to calculate the exponentials that go on the denominators inside the cos(x) function. I think most of this is right, but I'm probably missing on something and I can't figure out what.
#include<stdio.h>
#include <stdlib.h>
#include <math.h>
int fat(int);
float cosx(float);
int main()
{
float x1;
/* Original code: **x1 = x1 * 3.14159 / 180;** `transforms the value to radians` */
x1 = x1 * 3.14159 / 180; /* transforms the value to radians */
printf("Insert number:\n");
scanf("%f", &x1);
printf("Cosine of %f = %f", x1, cosx(x1));
return 0;
}
int fat(int y)
{
int n, fat = 1;
for(n = 1; n <= y; n++)
{
fat = fat * n;
}
return fat;
}
float cosx(float x)
{
int i=1, a = 2, b, c = 1, e;
float cos;
while(i < 20)
{
b = c * (pow(x,a)) / e;
cos = 1 - b;
a += 2;
e = fat(a);
c *= -1;
i++;
}
return cos;
}
If I input 0 it returns -2147483648.000000, which is clearly wrong.
First error is uninitialized variable x1, and right after that you have use:
int x1; // <<< uninitiated variable;
**x1 = x1 * 3.14159 / 180;** `transforms the value to radians
this will produce random value, you should put
int x = 0; // or some other value of your choice
In my opinion you should move x1 = x1 * 3.14159/100; after scanf("%d", x1).
Than again uninitiated value e before use.
int i=1, a = 2, b, c = 1, e;
...
b = c * (pow(x,a)) / e;
...
than you have in the line b = c * pow(x,a) where you go out of range of int variable potentially. If e = 1, x = 2 and a > 31 you are out of range for b. Another problem is pow(x,a) is rising much faster than `e. thus you get bigger and bigger values thus you are getting another overflow. And here is the code that works:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
long double fact(int);
long double cosx(double);
long double my_pow (double b, int e);
int main()
{
double x1 = 45.00;
printf("Insert number:\n");
scanf("%lf", &x1);
x1 = x1 * 3.14159 / 180; // ** `transforms the value to radians`
printf("Cosine of %f = %.10LF", x1, cosx(x1));
return 0;
}
long double fact(int y)
{
int n;
double fact = 1;
for(n = 1; n <= y; n++)
{
fact *= n;
}
return fact;
}
long double cosx(double x)
{
int a = 2, c = -1;
long i = 0, lim = 500;
long double cos = 1;
long double b = 0, e = 0;
while(i < lim) {
e = fact(a);
b = c * my_pow(x,a);
cos += b/e;
// printf ("%le %le %le\n", e, b, cos);
a += 2;
c *= -1;
i++;
}
return cos;
}
long double my_pow (double b, int e) {
long double pow = 1;
for (;e > 0; --e, pow *= b)
;
return pow;
}
I have to parallelize using openMP the serial version of a program in C to visualize a Mandelbrot set. I tried to do it but I obtain something really strange.
#include <stdlib.h>
#include <stdio.h>
#include <omp.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include "pngwriter.h"
#include "consts.h"
unsigned long get_time()
{
struct timeval tp;
gettimeofday(&tp, NULL);
return tp.tv_sec * 1000000 + tp.tv_usec;
}
int main(int argc, char** argv)
{
png_data* pPng = png_create(IMAGE_WIDTH, IMAGE_HEIGHT);
double x, y, x2, y2, cx, cy;
cy = MIN_Y;
double fDeltaX = (MAX_X - MIN_X) / (double)IMAGE_WIDTH;
double fDeltaY = (MAX_Y - MIN_Y) / (double)IMAGE_HEIGHT;
long nTotalIterationsCount = 0;
unsigned long nTimeStart = get_time();
long i, j, n;
n = 0;
int c;
#pragma omp parallel
{
#pragma omp for private(i, c) reduction(+ : cx, cy)
for (j = 0; j < IMAGE_HEIGHT; j++) {
cx = MIN_X;
for (i = 0; i < IMAGE_WIDTH; i++) {
x = cx;
y = cy;
x2 = x * x;
y2 = y * y;
for (n = 0; (n < MAX_ITERS) && (x2 + y2 < 4); n++) {
y = 2 * x * y + cy;
x = x2 - y2 + cx;
x2 = x * x;
y2 = y * y;
}
int c = ((long)n * 255) / MAX_ITERS;
png_plot(pPng, i, j, c, c, c);
cx += fDeltaX;
nTotalIterationsCount++;
}
cy += fDeltaY;
}
}
unsigned long nTimeEnd = get_time();
png_write(pPng, "mandel.png");
return 0;
}
I obtain this:
https://usi365-my.sharepoint.com/personal/fabbrl_usi_ch/_layouts/15/guestaccess.aspx?guestaccesstoken=d83LRC8EG1Kec%2f%2f6zwCbiHkO7%2bsuGv7JyWR%2flalvPvA%3d&docid=128ed81bef8b244d680d5651ad1afea2f&rev=1
Since this is an assignment, I am not here to ask for code. Just an explanation. Thanks.
I have to write a programm to calculate a sine loop. The first task was, to create arrays for which puts the sine loop into several intervals, like [0.0 to 0.1], [0.1 to 0.2], ... and there should be a maximal input form the Operator
After that i should calculate the area for each interval.
Everything goes fine, but after the 14th interval my program breaks and i have no idea why..
maybe you can help me, here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ARR_MAX 1000
float f(float x) {
float sinus = (float)sin((float)x);
return(sinus);
}
float max(float a, float b) {
if (a < b)
return(b);
else
return(a);
}
float min(float a, float b) {
if (a < b)
return(a);
else
return(b);
}
int main(void) {
printf("Dieses Programm berechnet Ober und Untersummen einer Sinuskurve\n");
float x; int xmax; float result;
int arr[ARR_MAX];
printf("Geben Sie die Zahl xmax ein: "); // put in the max amount of numbers
scanf("%d\n", & xmax);
if (ARR_MAX > xmax) {
xmax = xmax*10;
for (int i = 0; i <= xmax; i += 1) { // here i create arrays for my intervals
x = i;
arr[i] = i;
x = x/10;
float a = x - 0.1;
//left interval is always 0.1 lower than variable for example you get x = 0.3 --> 0.3 - 0.1 = 0.2; so interval is a = 0.2, b = 0.3
float b = x;
float T = 0.1; //accuracy
float uppersum;
float lowersum;
long numberintervals = 10;
do {
// i use this do while operation to get the result for each interval
float lengthintervals = b/numberintervals;
uppersum = 0.0;
lowersum = 0.0;
int i;
for (i = 0; i < numberintervals;i++) {
float x = a + i*lengthintervals;
float y1 = f(x);
float y2 = f(x + lengthintervals);
float upperamount = max(y1, y2);
float loweramount = min(y1, y2);
uppersum += upperamount*lengthintervals;
lowersum += loweramount*lengthintervals;
}
} while (uppersum - lowersum > T);
result = result + lowersum;
printf("arr[%d] = %f - ", arr[i], x);
printf("Flächensumme = %f - ", lowersum);
printf("neues Ergebnis = %f\n", result);
}
} else {
return EXIT_SUCCESS;
}
}
The i used in arr[i] can be out of the array bounds, because i can be greater than ARR_MAX
int arr[ARR_MAX];
...
if (ARR_MAX > xmax) {
xmax = xmax*10;
for (int i = 0; i <= xmax; i += 1) {
...
arr[i] = i;
I have written following code in order to produce simple list of double pairs to import in plot program.
#include <stdio.h>
#include <math.h>
int main(void)
{
int i;
double x=2,y=3;
for(i = 0; i < 1000; i++){
x = y- x/fabs(x)*sqrt(fabs(x+0.7));
y = 0.3-x;
printf("%5.4f , %5.4f\n" ,x,y);
}
return 0;
}
I don't get what I expect from this functions. Instead of hopalong fractal I get linear progression graph. Is this only syntax error?
When you assign y, you use the new value of x, which has just been updated. The calculation requires the x value from the last step. Make a copy and use that:
int main(void)
{
double x = 2;
double y = 3;
int i;
for(i = 0; i < 1000; i++) {
double xx = x;
x = y - x/fabs(x)*sqrt(fabs(x + 0.7));
y = 0.3 - xx;
printf("%5.4f , %5.4f\n" ,x,y);
}
return 0;
}