So I was making a program that computes Pythagorean triples, as long as c is lower than the number entered by the user. So I used 3 while loops to accomplish this. What I also want to accomplish is print to the screen, the set of triples that has the thinnest interior angle, has to be a right-angled triangle. Basically, I calculated using the sine law the smallest angle for each of the triples, and then stored that smallest in an array, and right after it the three indexes of the array represent its corresponding triples. Then I made a method to compare each angle from the triples and if one was greater to store it in the initial four spots of the array. I am currently not worrying about the array size and have declared it as 9999. So the problem is that when I compare more than 1 set of triples, the program does not make the 1st set of indexes in the array equal to the triple with the smallest angle. I agree that the procedure that I have used is very inefficient and time consuming, but if you could give me some sort of solution or even guide me in the right direction I'd appreciate it. Thanks. Oh and here is my code,
#include <stdio.h>
#include <math.h>
#define PI 3.14159265
static int a[9999];
int main(void)
{
int side1, side2, hyp, num;
int i = 0;
int j;
side1 = 1;
hyp = 0;
printf("Please enter a number\n");
scanf("%d", &num);
while (side1 < num) {
side2 = 1;
while (side2 < num) {
hyp = 1;
while (hyp < num) {
if (side1 * side1 + side2 * side2 == hyp * hyp && side1 < side2) {
printf("The side lengths are %d,%d,%d\n", side1, side2, hyp);
float angle1 = (asin((float) side1 / hyp) * (180 / PI));
float angle2 = (asin((float) side2 / hyp) * (180 / PI));
if (angle1 > angle2) {
a[i] = (int)angle2;
a[i + 1] = side1;
a[i + 2] = side2;
a[i + 3] = hyp;
} else if (angle2 > angle1) {
a[i] = (int)angle1;
a[i + 1] = side1;
a[i + 2] = side2;
a[i + 3] = hyp;
} else {
a[i] = (int)angle1;
a[i + 1] = side1;
a[i + 2] = side2;
a[i + 3] = hyp;
}
i=i+4;
}
hyp++;
}
side2++;
}
side1++;
}
a[i+1]=99.99;
a[i+2]=99.99;
a[i+3]=99.99;
a[i+4]=99.99;
compare(i);
return (0);
}
void compare(int i)
{
int j;
for(j=0;j<i;j=j+4)
{
if (a[0]>a[j+4])
{
a[0]=a[j+4];
a[1]=a[j+5];
a[2]=a[j+6];
a[3]=a[j+7];
}
//printf("%d\n",a[0]);
}
printf("The thinnest triangle is formed by (%d , %d , %d)", a[1], a[2], a[3]);
}
Oh one more thing, the reason I have made some indexes 99.9 is so that when the loop is checking and it is not the last triple, I do not want an error,since the loop will have nothing further to compare the previous triples to. Ok I changed it to one equal sign, but now the output is always 99,99,99.
Perhaps the four statements starting with a[0]==a[j+4] should be using = instead of ==.
switch your assignments to single equal signs = instead of double ones ==.
void compare(int i)
{
int j;
for(j=0;j<i;j=j+4)
{
if (a[0]>a[j+4])
{
a[0] = a[j+4]; // <- here,
a[1] = a[j+5]; // <- here,
a[2] = a[j+6]; // <- here,
a[3] = a[j+7]; // <- and here
}
//printf("%d\n",a[0]);
}
printf("The thinnest triangle is formed by (%d , %d , %d)", a[1], a[2], a[3]);
}
Related
I took this example from a video in youtube, where a sen(x) is resolved using this approach, I just changed the formula to an arcsin(x).
I am trying to figure out why this code is not working as expected:
#include <stdio.h>
//#include <float.h>
#include <math.h>
int factorial(int x)
{
int fac = 1;
while (x!=0)
{
fac= fac*x;
x--;
}
return fac;
}
int main()
{
int i;
float x, sum, divisor = 1, dividendo = 1, temp;
printf("enter the value of X(in degrees): ");
scanf("%f", &x);
//x = x*3.141592/180;
sum = 0;
for(i=1; ; i++)
{
divisor = (factorial(2*i));
dividendo = (pow(4,(i)) * pow(factorial(i),2)*(2*i+1));
temp = (divisor/dividendo)*pow(x,(2*i+1));
if (temp < FLT_EPSILON)
break;
sum = sum + temp;
printf("our result = %f\n", sum);
}
printf("reference = %f\n", asin(x));
// printf("our result = %f\n", sum);
}
Below is the result, and as you may see the output I get is far below from what is expected. the result printed comes from every iteration, and the reference is just to make a comparison between both outcomes.
enter the value of X(in degrees): 1
our result = 0.166667
our result = 0.241667
our result = 0.286310
our result = 0.316691
our result = 0.339064
our result = 0.356416
our result = 0.356621
our result = 0.356622
our result = 0.356622
our result = 0.356622
**reference = 1.570796**
The Taylor series for arscin is
arcsin(x) = sum n = 0; inf; (2*n)! / (4**n * (n!)**2 * (2*n + 1)) * x**(2*n + 1)
where ** is the power operator and ! denotes a factorial. As was already noted in comments, an int can represent factorials up to 12! only; a 64-bit long can represent factorials up to 20!. Since you use (2*n)!, these limits will be reached quickly.
A better solution to this problem is not to calculate every term separately as given in the formula, but to evolve the term by calculating it from the previous term:
term(n + 1) = fact * term(n)
Since each term is one large factor, you can do that for each subfactor:
2*(n + 1))! = (2*n)! * (2*n + 1) * (2*n + 2)
4**(n + 1) = 4**n * 4
((n + 1)!)**2 = n!**2 * (n + 1)**2
2*(n + 1) + 1 = 2*(n + 1) * (2*n + 3) / (2*n + 1)
x**(2*(n + 1) + 1) = x**(2*n + 1) * x**2
Putting all this together:
float res = x; // first term ...
float fact = x; // ...equals the first factor
for (int n = 0; n < nMax; n++) {
float old = res;
// calculate term(n + 1) as per the formulas above
fact *= (2*n + 1) * (2*n + 2);
fact /= 4.0 * (n + 1)*(n + 1) * (2*n + 3);
fact *= x * x * (2*n + 1);
res += fact;
if (res == old) break;
printf("[%d] %f\n", n, res);
}
printf("ref %f\n", asin(x));
(FLT_EPSILON is the granularity of floating-point numbers near 1.0. The terms are converging to zero, where the granularity is finer. I've tested whether adding the new term doesn't change the sum as a convergence criterion with a fixed maximum number of iterations, nMax.)
This series does not converge well near ±1, where the slope of the function approaches infinity. By Stirling's approximation the nth term approximately equals 1/((2*n+1)*√(πn)), which converges very slowly. For the nth term to be less than FLT_EPSILON, n needs to be greater than 26000. Unfortunately, with that many summations, the finite precision of floating point numbers would prevent the series to converge to the correct answer.
I made this program in C where an object R is placed on a grid and it's supposed to move taking inputs from they keyboard. For example, thi is what happens if you press N.
0 1 2
0 - - - R - - - - -
1 R - - PRESS N -> GO UP -> - - - PRESS N AGAIN -> - - -
2 - - - - - - R - -
So R makes it go up. The object has to move around, so when it is at [A0][B0], for example, it needs to go all the way down [A2][B0]. See above.
It will move up, down, left and right.
Right now i'm creating the function to make it move up, but i'm having a lot of troubles: sometimes it randomly freezes to 2:0 and 0:0 without goind up, and when it's at A = 2, instead of going up of 1, it goes to 0, although i set it to do 2-1 (to go up it has to subtract 1).
I don't understand what's causing those troubles, any advice?
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define X 3
#define Y 3
struct coords{
int a;
int b;
};
typedef struct coords cord;
// Print the array
char printArray(char row[][Y], size_t one, size_t two, struct coords cord)
{
row[cord.a][cord.b] = 'X';
// output column heads
printf("%s", " [0] [1] [2]");
// output the row in tabular format
for (size_t i = 0; i < one; ++i) {
printf("\nrow[%lu] ", i);
for (size_t j = 0; j < two; ++j) {
printf("%-5c", row[i][j]);
}
}
}
int moveUp(struct coords * cord);
int main(void)
{
struct coords cord;
char row[X][Y] =
{ { '-', '-', '-'},
{ '-', '-', '-'},
{ '-', '-', '-'} };
srand(time(NULL));
cord.a = (rand() % 3);
cord.b = (rand() % 3);
printf("\nValori rand: A %d, B %d\n", cord.a, cord.b);
// output the row
//printf("\nrobot:%c\n", robot);
puts("The array is:");
printf("\n");
printArray(row, X, Y, cord);
row[cord.a][cord.b] = '-';
//printArray(row, X, Y, &m, &n);
char h;
while(h != '3'){
switch (h) {
case 'N':
moveUp(&cord);
printArray(row, X, Y, cord);
row[cord.a][cord.b] = '-';
break;
}
scanf("%s", &h);
}
printf("\n");
}
int moveUp(struct coords * cord)
{
cord->a - 1;
if (cord->a == 2){
cord->a - 1;
} else if (cord->a == 1){
cord->a - 1;
} else if (cord->a == 0){
cord->a + 2;
}
/*
if (cord->a == 0) {
cord-> a = 2;
} else {
cord->a - 1;
}
*/
printf("\n A = %d, B = %d\n", cord->a, cord->b);
}
In the below code, you are checking the value of h before having read anything into it. If the uninitialized value of h happens to be 3, then execution will not enter the while loop.
char h;
while(h != '3')
So read in a value into h and then do the check in the while loop.
In the moveUp function, you can use the ternary conditional operator to assign the next position or the object R.
cord->a = (cord->a)? (cord->a - 1): 2;
Could someone help me to look at the code I wrote in C? It can generate numbers, but the if condition looks like wrong, but I donot know how to fix it.
I need to get some n random values with distribution and these values are in a special intervals, so I use for loop like below:
n=10; mu=2; mu_plus=3; p=0.2;
for(i=1; i<=n; i++)
{
x1 = gasdev(&idum);
x2 = gasdev(&idum);
z = sqrt(1-p*p)*x1 + p*x2 + mu;
z_p= x2 + mu_plus;
if (z > 2.17 || z<-2.17)
{
Z[i]=z;
Z_plus[count]=z_p;
}
printf("%d %lf %lf\n", i, Z[i], Z_plus[i]);
}
Where gasdev() is a function for generating random value with a standard normal distribution, Z and Z_plus are 1*n vectors. The results are mess, so I think that the IF condition must be wrong. Could any one could help me? Thank you.
I also tried the While loop.
while(count < n)
{
x1 = gasdev(&idum);
x2 = gasdev(&idum);
z = sqrt(1-p*p)*x1 + p*x2 + mu;
z_p= x2 + mu_plus;
if (z > 2.17 || z<-2.17)
{
count++;
Z[count]=z;
Z_plus[count]=z_p;
}
printf("%d %lf\n",count, Z[count]);
if (count >n) break;
}
It can print out normally, but occurs an error at the end.
Thank you!
The error here is that you always increment i as part of the for loop so that if z is outside the range of the bracket set, you do not put any value into the Z array. You do not specify count so was that supposed to be i or not?
n=10; mu=2; mu_plus=3; p=0.2;
for(i=1; i<=n; i++)
{
x1 = gasdev(&idum);
x2 = gasdev(&idum);
z = sqrt(1-p*p)*x1 + p*x2 + mu;
z_p= x2 + mu_plus;
if (z > 2.17 || z<-2.17)
{
Z[i]=z;
Z_plus[count]=z_p; // Should this be Z_plus[i] ??
}
// Note that if outside of bracket no value put in Z[i]
// This makes Z[i] and Z_plus[i] garbage
printf("%d %lf %lf\n", i, Z[i], Z_plus[i]);
}
Your while loop is not correct either as it increments count when it is n-1 and tries to process Z[n] when it appears that you must have defined it as an array of size n (max index is n-1). Also the print needs to be inside the if not outside.
while(count < n)
{
x1 = gasdev(&idum);
x2 = gasdev(&idum);
z = sqrt(1-p*p)*x1 + p*x2 + mu;
z_p= x2 + mu_plus;
if (z > 2.17 || z<-2.17)
{
// This allows count == n which overflows the buffer.
count++;
Z[count]=z;
Z_plus[count]=z_p;
}
// This should be inside the bracket not outside
printf("%d %lf\n",count, Z[count]);
// This is not needed since it will exit the while at count == n
if (count >n) break;
}
correct code would be
count = 0;
while(count < n)
{
x1 = gasdev(&idum);
x2 = gasdev(&idum);
z = sqrt(1-p*p)*x1 + p*x2 + mu;
z_p= x2 + mu_plus;
if (z > 2.17 || z<-2.17)
{
Z[count]=z;
Z_plus[count]=z_p;
printf("%d %lf\n",count, Z[count]);
count++;
}
}
I have been using Ubuntu 12.04 LTS with GCC to compile my the codes for my assignment for a while. However, recently I have run into two issues as follows:
The following code calculates zero for a nonzero value with the second formula is used.
There is a large amount of error in the calculation of the integral of the standard normal distribution from 0 to 5 or larger standard deviations.
How can I remedy these issues? I am especially obsessed with the first one. Any help or suggestion is appreciated. thanks in advance.
The code is as follows:
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#define N 599
long double
factorial(long double n)
{
//Here s is the free parameter which is increased by one in each step and
//pro is the initial product and by setting pro to be 0 we also cover the
//case of zero factorial.
int s = 1;
long double pro = 1;
//Here pro stands for product.
if (n < 0)
printf("Factorial is not defined for a negative number \n");
else {
while (n >= s) {
pro *= s;
s++;
}
return pro;
}
}
int main()
{
// Since the function given is the standard normal distribution
// probability density function we have mean = 0 and variance = 1.
// Hence we also have z = x; while dealing with only positive values of
// x and keeping in mind that the PDF is symmetric around the mean.
long double * summand1 = malloc(N * sizeof(long double));
long double * summand2 = malloc(N * sizeof(long double));
int p = 0, k, z[5] = {0, 3, 5, 10, 20};
long double sum1[5] = {0}, sum2[5] = {0} , factor = 1.0;
for (p = 0; p <= 4; p++)
{
for (k = 0; k <= N; k++)
{
summand1[k] = (1 / sqrtl(M_PI * 2) )* powl(-1, k) * powl(z[p], 2 * k + 1) / ( factorial(k) * (2 * k + 1) * powl(2, k));
sum1[p] += summand1[k];
}
//Wolfamalpha site gives the same value here
for (k = 0; k <= N; k++)
{
factor *= (2 * k + 1);
summand2[k] = ((1 / sqrtl(M_PI * 2) ) * powl(z[p], 2 * k + 1) / factor);
//printf("%Le \n", factor);
sum2[p] += summand2[k];
}
sum2[p] = sum2[p] * expl((-powl(z[p],2)) / 2);
}
for (p = 0; p < 4; p++)
{
printf("The sum obtained for z between %d - %d \
\nusing the first formula is %Lf \n", z[p], z[p+1], sum1[p+1]);
printf("The sum obtained for z between %d - %d \
\nusing the second formula is %Lf \n", z[p], z[p+1], sum2[p+1]);
}
return 0;
}
The working code without the outermost for loop is
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#define N 1200
long double
factorial(long double n)
{
//Here s is the free parameter which is increased by one in each step and
//pro is the initial product and by setting pro to be 0 we also cover the
//case of zero factorial.
int s = 1;
long double pro = 1;
//Here pro stands for product.
if (n < 0)
printf("Factorial is not defined for a negative number \n");
else {
while (n >= s) {
pro *= s;
s++;
}
return pro;
}
}
int main()
{
// Since the function given is the standard normal distribution
// probability density function we have mean = 0 and variance = 1.
// Hence we also have z = x; while dealing with only positive values of
// x and keeping in mind that the PDF is symmetric around the mean.
long double * summand1 = malloc(N * sizeof(long double));
long double * summand2 = malloc(N * sizeof(long double));
int k, z = 3;
long double sum1 = 0, sum2 = 0, pro = 1.0;
for (k = 0; k <= N; k++)
{
summand1[k] = (1 / sqrtl(M_PI * 2) )* powl(-1, k) * powl(z, 2 * k + 1) / ( factorial(k) * (2 * k + 1) * powl(2, k));
sum1 += summand1[k];
}
//Wolfamalpha site gives the same value here
printf("The sum obtained for z between 0-3 using the first formula is %Lf \n", sum1);
for (k = 0; k <= N; k++)
{
pro *= (2 * k + 1);
summand2[k] = ((1 / sqrtl(M_PI * 2) * powl(z, 2 * k + 1) / pro));
//printf("%Le \n", pro);
sum2 += summand2[k];
}
sum2 = sum2 * expl((-powl(z,2)) / 2);
printf("The sum obtained for z between 0-3 using the second formula is %Lf \n", sum2);
return 0;
}
I'm quite certain that the problem is in factor not being set back to 1 in the outer loop..
factor *= (2 * k + 1); (in the loop that calculates sum2.)
In the second version provided the one that works it starts with z=3
However in the first loop since you do not clear it between iterations on p by the time you reach z[2] it already is a huge number.
EDIT: Possible help with precision..
Basically you have a huge number powl(z[p], 2 * k + 1) divided by another huge number factor. huge floating point numbers lose their precision. The way to avoid that is to perform the division as soon as possible..
Instead of first calculating powl(z[p], 2 * k + 1) and dividing by factor :
- (z[p]z[p] ... . * z[p]) / (1*3*5*...(2*k+1))`
rearrange the calculation: (z[p]/1) * (z[p]^2/3) * (z[p]^2/5) ... (z[p]^2/(2*k+1))
You can do this in sumand2 calculation and a similar trick in summand1
I am trying to write a program to perform point operations on a elliptic curve in a prime field I am using the standard formulaes for point additions and doubling in my code and these operations are performed by functions that are called but I am getting output for certain points but not all so please help me to fix the problem that are present in this code.
structure point_multiply(int x, int y, int k )
{
int xk;
int yk,m;
xk=x;
yk=y;
m=1;
int xL,yL,s,e;
e=findInverse((2*yk),211);
if((((3*(xk*xk))*e)% 211)>0)
{s = (((3*(xk*xk))*e)% 211);
}
else
s=(((3*(xk*xk))*e)% 211)+ 211;
if((((s*s)- (2*xk)) % 211)>0)
{xL=(((s*s)- (2*xk)) % 211);
}
else
xL=(((s*s)- (2*xk)) % 211) + 211;
if(((-yk+ s*(xk-xL)) % 211) > 0)
yL=(-yk+ s*(xk-xL)) % 211;
else
yL=(-yk+ s*(xk-xL)) % 211 + 211;
xk=xL;
yk=yL;
m=m+1;
while(k>m)
{
sn=point_addition(xk,yk,x,y);
xk=sn.a;
yk=sn.b;
m++;
}
s1.a=xk;
s1.b=yk;
return s1;
}
structure point_addition(int x1, int y1, int x2, int y2)
{
int s,xL,yL;
if((x1-x2)!=0)
{
if ( x1 == 0 && y1 == 0 )
{
xL = x2;
yL = y2;
s7.a=xL;
s7.b=yL;
return s7;
}
if ( x2 == 0 && y2 == 0 )
{
xL = x1;
yL = y1;
s7.a=xL;
s7.b=yL;
return s7;
}
if ( y1 == -y2 )
{
xL = yL = 0;
s7.a=xL;
s7.b=yL;
return s7;
}
l=findInverse((x1-x2),211);
if ((((y1-y2)*l) % 211)>=0)
s=((((y1-y2)*l) % 211));
else
s=(((y1-y2)*l) % 211) + 211;
if ((((s*s)-(x1+x2)) % 211)>0)
xL= (((s*s)-(x1+x2)) % 211) ;
else
xL= (((s*s)-(x1+x2)) % 211) + 211;
if(((-y1+s*(x1-xL)))>=0)
yL= ((-y1+s*(x1-xL)) % 211);
else
yL= ((-y1+s*(x1-xL)) % 211) + 211;
}
else
{
xL= 0 ;
yL= 0;
}
s7.a= xL;
s7.b= yL;
return s7 ;
}
int findInverse(int a, int b)
{
int x[3];
int y[3];
int quotient = a / b;
int remainder = a % b;
x[0] = 0;
y[0] = 1;
x[1] = 1;
y[1] = quotient * -1;
int i = 2;
for (; (b % (a%b)) != 0; i++)
{
a = b;
b = remainder;
quotient = a / b;
remainder = a % b;
x[i % 3] = (quotient * -1 * x[(i - 1) % 3]) + x[(i - 2) % 3];
y[i % 3] = (quotient * -1 * y[(i - 1) % 3]) + y[(i - 2) % 3];
}
//x[i — 1 % 3] is inverse of a
//y[i — 1 % 3] is inverse of b
if(x[(i - 1) % 3]<0)
return x[(i - 1) % 3]+211;
else
//x[i — 1 % 3] is inverse of a
//y[i — 1 % 3] is inverse of b
return x[(i - 1) % 3];
}
Edited and added main c code which uses these function to perform elliptic curve cryptography
int main()
{
int y,z=0,x=2,i[200],j[200],h=0,g,k;
while(x<200)
{
y=sqrt((x*x*x)-4);
z=modulo(y,211);
if(z!=0)
{
i[h]=x;
j[h]=z;
s[h].a=i[h];
s[h].b=j[h];
s[h+1].a=i[h];
s[h+1].b=(211 - j[h]);
printf("\nh=%d X= %d Y= %d \nh=%d X= %d Y= %d",h,s[h].a,s[h].b,h+1,s[h+1].a,s[h+1].b);
h=h+2;
}
x++;
}
printf("The total no of points we have on our elliptic curve for cryptography is %d",h-1);
x=5;
y=11;
printf("\n %d %d\n",x,y );
printf("\nEnter A number between 0 and the private key");
scanf("%d",&k);
s2=point_multiply(x,y,k);
printf("\n The public key is \n %d %d \n ",s2.a,s2.b );
printf("Enter a RANDOM number to generate the cipher texts");
scanf("\n%d",&g);
s3= point_multiply(x,y,g);
s4=point_multiply(s2.a,s2.b,g );
label:
printf("\n Enter a number to send");
scanf("%d",&h);
s6=point_addition(s4.a,s4.b,s[h].a,s[h].b);
printf("The points to be sent are X= %d Y=%d",s[h].a,s[h].b);
printf(" \n X= %d Y=%d\n X = %d Y= %d ",s3.a,s3.b,s6.a,s6.b);
//RECIEVER
s8=point_multiply(s3.a,s3.b,k);
s9=point_addition((s8.a) ,-((s8.b)%211),s6.a,s6.b);
printf(" The decrypted points are \n %d %d",s9.a,s9.b);
printf("\n If you have more no to send press 1 else press 0");
scanf("\n %d", &x1);
if(x1==1)
goto label;
else
return 0;
}
s1, s2, s3 etc are structures which hold a 2 integers which act as x and y co-ordinates
I am getting output by entering k=3,g=4, h=5 and many other cases mostly with small numbers but not for larger numbers. What could be wrong with the code?
Further edit: I guess that normal square root method is not applicable to find square roots of a modular no?.. Please tell me how to find the modular square root of a no?