Not Getting a Calculated Value of the Constant e - c

Not really sure what the problem is here. I know I have the factorial function correct because I tested it separately. But the function that calculates e is tripping me up. All I have to do is add all the values after each factorial has been calculated. But I am having trouble translating that into C code. The problem for sure is in my second function. Any help or pointers would be appreciated.
#include <stdio.h>
#include <math.h>
#define NOERROR 0
#define DECIMAL_PLACES 16
#define EXPECTED_E 2.7182818284590452L
long calcFactorial(int);
double calcE(int);
long calcFactorial(int n)
{
long sum = 0;
sum = n;
if(n == 0)
{
return 1;
}
else
{
while(n != 1)
{
sum = sum * (n - 1);
n = n - 1;
}
printf("factorial sum: %ld\n", sum);
return sum;
}
}
double calcE(int n)
{
double e = 0;
int counter = 0;
for (counter = 0; counter < DECIMAL_PLACES; counter++)
{
e = e + (1/calcFactorial(n));
n--;
}
printf("Expected e value: %0.16Lf\n", EXPECTED_E);
printf("Calculated e value: %0.16d\n", e);
return e;
}
int main()
{
calcE(10);
}

You have a lot of errors in your code:
using long to store floating point result. Use double
passing n but looping using a bigger value: n becomes negative after a while: infinite loop
e = e + (1/calcFactorial(counter)); adds 0 to e most of the time because calcFactorial returns an integer (long)
EXPECTED_E constant had L suffix, which means long. Not what you want.
Fixed version:
#include <stdio.h>
#include <math.h>
#define NOERROR 0
#define DECIMAL_PLACES 16
#define EXPECTED_E 2.7182818284590452
long calcFactorial(int);
void calcE(int);
long calcFactorial(int n)
{
long sum = 0;
sum = n;
if(n == 0)
{
return 1;
}
else
{
while(n != 1)
{
sum *= (n - 1);
n = n - 1;
}
return sum;
}
}
void calcE(int n)
{
double e = 0;
int counter = 0;
for (counter = 0; counter < n; counter++)
{
e = e + (1.0/calcFactorial(counter));
}
printf("Expected e value: %0.16lf\n", EXPECTED_E);
printf("Calculated e value: %0.16lf\n", e);
}
int main( )
{
calcE(10);
}
This code outputs:
Expected e value: 2.7182818284590451
Calculated e value: 2.7182815255731922
Note: you are limited to a given maximum for n because after that you'll overflow long. Maybe consider using long long or unsigned long long for the factorial part (and even with that you're severely limited).

Jean-François Fabre highlighted your formal errors quite well, but it is not so far fetched to calculate with integers up to the final division--which must be done with floats, of course. The trick can be done with a method called binary splitting and, to my own surprise, it works very well native doubles, only one decimal digit off. It is also very simple to implement (code below written with legibility in mind).
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define BS_AFU 0
#define BS_AOK 1
static int exp1_bin_split(uint64_t a, uint64_t b, uint64_t *P, uint64_t *Q){
int err = BS_AOK;
uint64_t p1, q1, p2, q2, t1, one;
one = 1UL;
t1 = b - a;
if(t1 == one){
*P = one;
*Q = b;
return err;
}
t1 = (a + b) >> 1;
err = exp1_bin_split(a, t1, &p1, &q1);
if(err != BS_AOK){
return err;
}
err = exp1_bin_split(t1, b, &p2, &q2);
if(err != BS_AOK){
return err;
}
*P = q2 * p1 + p2;
*Q = q1 * q2;
return err;
}
#include <float.h>
static int exp1(double *a){
int err = BS_AOK;
uint64_t p = 0UL, q = 0UL, zero = 0UL;
double dp, dq;
// DBL_DIG + 2 = 17 here on my machine
// had DBL_DIG + 1 first but found out via T&E that
// one more is still inside the precision of a binary64
err = exp1_bin_split(zero, DBL_DIG + 2, &p, &q);
if(err != BS_AOK){
return err;
}
p = p + q;
dp = (double) p;
dq = (double) q;
*a = dp/dq;
return err;
}
int main(void){
double e = 0.0;
int err = BS_AOK;
err = exp1(&e);
if(err != BS_AOK){
fprintf(stderr,"Something went wrong in computing e\n");
exit(EXIT_FAILURE);
}
printf("exp(1) ~ 2.7182818284590452353602874713526624978\nexp1 ~ %.20g\n",e);
exit(EXIT_SUCCESS);
}
It uses the same algorithm as you do but does not compute the individual fractions and sums them up as floats but does it all at once with integers such that we have a large fraction at the end to resemble the approximation of exp(1). That explanation is a bit over-simplified, please read the linked paper for the details.

Related

Finding GCD using divison method in C

So I wanted to write a function to calculate the Gcd or HCF of two numbers using the Divison method.This is my code:
#include <stdio.h>
#include <stdlib.h>
void gcd(int x, int y)
{
int g,l;
if (x >= y)
{
g = x;
l = y;
}
else
{
g = y;
l = x;
}
while (g % l != 0)
{
g = l;
l = g % l;
}
printf("The GCD of %d and %d is %d", x, y, l);
}
int main(void)
{
gcd(8, 3);
return 0;
}
I am getting no output with this(error?): Process returned -1073741676 (0xC0000094)
Is there a problem with my loop?
In:
g = l;
l = g % l;
the assignment g = l loses the value of g before g % l is calculated. Change it to:
int t = g % l;
g = l;
l = t;
I use this loop while to find the gcd of two numbers like this:
void gcd(int x, int y)
{
int k=x,l=y;
if(x>0&&y>0)
{
while(x!=0&&y!=0)
{
if(x>y)
{
x=x-y;
}
else
{
y=y-x;
}
}
}
printf("\nThe GCD of %d and %d is %d", k, l, x);
}
int main(void)
{
gcd(758,306);
return 0;
}
Examples:
Input:
x=758 , y=306
x=27 , y=45
x=3 , y=8
Output:
printf("\nThe GCD of 758 and 306 is 2");
printf("\nThe GCD of 27 and 45 is 9");
printf("\nThe GCD of 3 and 8 is 1");
First of all, take into account that you are exchanging the numbers when x >= y which means that you try to put in x the smaller of the two. For GDC, there's no need to do
this, as the remainder of a division by a bigger number is always the original number, so if you have the sequence 3, 8, the first remainder will be 3, and the numbers switch positions automatically as part of the algorithm. So there's no need to operate with g (I guess for greater) and l (for lesser) so you can avoid that.
#include <stdio.h>
#include <stdlib.h>
void gcd(int x, int y)
{
int g,l;
if (x >= y)
{
g = x;
l = y;
}
else
{
g = y;
l = x;
}
Then, in this second part (the loop part) you have to take into account that you are calculating g % l twice in the same loop run (this is not the Euclides' algorithm).
while (g % l != 0)
{
g = l;
l = g % l;
}
You should better use a new variable r (for remainder, but I should recommend you to use longer, descriptive names) so you have always an idea of what the variable holds.
int r;
while ((r = g % l) != 0) {
g = l;
l = r;
}
you see? I just do one division per loop, but you make a l = g % l; which modifies the value of l, making you go through two iterations of the loop in one.
The final program is:
#include <stdio.h>
#include <stdlib.h>
int gcd(int greater, int lower)
{
int remainder;
while ((remainder = greater % lower) != 0) {
printf("g=%d, l=%d, r=%d\n", greater, lower, remainder);
greater = lower;
lower = remainder;
}
return lower; /* remember that remainder got 0 in the last loop */
}
int main(void)
{
int x = 6, y = 8;
printf("The GCD of %d and %d is %d\n",
x, y, gcd(x, y));
printf("The GCD of %d and %d is %d\n",
y, x, gcd(y, x));
return EXIT_SUCCESS;
}
(I have added a trace printf in the gcd() loop to show how the variables are changing, and both calculations ---changing the parameter values--- to show what I said above about the automatic change in order. Also, it's better to use the gcd() as a function that returns the value, and let main() decide if it wants to print results, or use the value for something else.
Enjoy it!! :)

How do I reverse the order of the digits of an integer using recursion in C programming?

Problem statement :
Given a 32-bit signed integer, reverse digits of an integer.
Note: Assume we are dealing with an environment that could only store
integers within the 32-bit signed integer range: [ −2^31, 2^31 − 1]. For
the purpose of this problem, assume that your function returns 0 when
the reversed integer overflows.
I'm trying to implement the recursive function reverseRec(), It's working for smaller values but it's a mess for the edge cases.
int reverseRec(int x)
{
if(abs(x)<=9)
{
return x;
}
else
{
return reverseRec(x/10) + ((x%10)*(pow(10, (floor(log10(abs(x)))))));
}
}
I've implemented non recursive function which is working just fine :
int reverse(int x)
{
long long val = 0;
do{
val = val*10 + (x%10);
x /= 10;
}while(x);
return (val < INT_MIN || val > INT_MAX) ? 0 : val;
}
Here I use variable val of long long type to check the result with MAX and MIN of signed int type but the description of the problem specifically mentioned that we need to deal within the range of 32-bit integer, although somehow it got accepted but I'm just curious If there is a way to implement a recursive function using only int datatype ?
One more thing even if I consider using long long I'm failing to implement it in the recursive function reverseRec().
If there is a way to implement a recursive function using only int datatype ?
(and) returns 0 when the reversed integer overflows
Yes.
For such +/- problems, I like to fold the int values to one side and negate as needed. The folding to one side (- or +) simplifies overflow detection as only a single side needs testing
I prefer folding to the negative side as there are more negatives, than positives. (With 32-bit int, really didn't make any difference for this problem.)
As code forms the reversed value, test if the following r * 10 + least_digit may overflow before doing it.
An int only recursive solution to reverse an int. Overflow returns 0.
#include <limits.h>
#include <stdio.h>
static int reverse_recurse(int i, int r) {
if (i) {
int least_digit = i % 10;
if (r <= INT_MIN / 10 && (r < INT_MIN / 10 || least_digit < INT_MIN % 10)) {
return 1; /// Overflow indication
}
r = reverse_recurse(i / 10, r * 10 + least_digit);
}
return r;
}
// Reverse an int, overflow returns 0
int reverse_int(int i) {
// Proceed with negative values, they have more range than + side
int r = reverse_recurse(i > 0 ? -i : i, 0);
if (r > 0) {
return 0;
}
if (i > 0) {
if (r < -INT_MAX) {
return 0;
}
r = -r;
}
return r;
}
Test
int main(void) {
int t[] = {0, 1, 42, 1234567890, 1234567892, INT_MAX, INT_MIN};
for (unsigned i = 0; i < sizeof t / sizeof t[0]; i++) {
printf("%11d %11d\n", t[i], reverse_int(t[i]));
if (t[i] != INT_MIN) {
printf("%11d %11d\n", -t[i], reverse_int(-t[i]));
}
}
}
Output
0 0
0 0
1 1
-1 -1
42 24
-42 -24
1234567890 987654321
-1234567890 -987654321
1234567892 0
-1234567892 0
2147483647 0
-2147483647 0
-2147483648 0
You could add a second parameter:
int reverseRec(int x, int reversed)
{
if(x == 0)
{
return reversed;
}
else
{
return reverseRec(x/10, reversed * 10 + x%10);
}
}
And call the function passing the 0 for the second parameter. If you want negative numbers you can check the sign before and pass the absolute value to this function.
In trying to learn C programming I programed this question and get some correct results and some incorrect. I don't see the reason for the difference.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h> // requires adding link to math -lm as in: gcc b.c -lm -o q11
int ReverseInt(int startValue, int decimalPlace)
{
if(decimalPlace == 0) // if done returns value
{
return startValue;
}
int temp = startValue % 10; // gets units digit
int newStart = (startValue -temp)/10; // computes new starting value after removing one digit
int newDecimal = decimalPlace -1;
int value = temp*pow(10,decimalPlace);
return value + ReverseInt(newStart,newDecimal); // calls itself recursively until done
}
int main()
{
int x, decimalP, startValue;
printf("Input number to be reversed \n Please note number must be less than 214748364 :");
scanf("%d", &x);
if (x > 214748364)
{
printf("Input number to be reversed \n Please note number must be less than 214748364 :");
scanf("%d", &x);
}
decimalP = round(log10(x)); // computes the number of powers of 10 - 0 being units etc.
startValue = ReverseInt(x, decimalP); // calls function with number to be reversed and powers of 10
printf("\n reverse of %d is %d \n", x, startValue);
}
Output is: reverse of 1234 is 4321 but then reverse of 4321 is 12340
It's late and nothing better does not come into my mind. No float calculations. Of course, integer has to be big enough to accommodate the result. Otherwise it is an UB.
int rev(int x, int partial, int *max)
{
int result;
if(x / partial < 10 && (int)(x / partial) > -10)
{
*max = partial;
return abs(x % 10) * partial;
}
result = rev(x, partial * 10, max) + abs(((x / (int)(*max / partial)) % 10) * partial);
return result;
}
int reverse(int x)
{
int max;
return rev(x, 1, &max) * ((x < 0) ? -1 : 1);
}
int main(void){
printf("%d", reverse(-456789));
}
https://godbolt.org/z/M1eezf
unsigned rev(unsigned x, unsigned partial, unsigned *max)
{
unsigned result;
if(x / partial < 10)
{
*max = partial;
return (x % 10) * partial;
}
result = rev(x, partial * 10, max) + (x / (*max / partial) % 10) * partial;
return result;
}
unsigned reverse(unsigned x)
{
unsigned max;
return rev(x, 1, &max);
}
int main(void){
printf("%u", reverse(123456));
}
when using long long to store the result all possible integers can be reversed
long long rev(int x, long long partial, long long *max)
{
long long result;
if(x / partial < 10 && (int)(x / partial) > -10)
{
*max = partial;
return abs(x % 10) * partial;
}
result = rev(x, partial * 10, max) + abs(((x / (int)(*max / partial)) % 10) * partial);
return result;
}
long long reverse(int x)
{
long long max;
return rev(x, 1, &max) * ((x < 0) ? -1 : 1);
}
int main(void){
printf("%d reversed %lld\n", INT_MIN, reverse(INT_MIN));
printf("%d reversed %lld\n", INT_MAX, reverse(INT_MAX));
}
https://godbolt.org/z/KMfbxz
I am assuming by reversing an integer you mean turning 129 to 921 or 120 to 21.
You need an initial method to initialize your recursive function.
Your recursive function must figure out how many decimal places your integer uses. This can be found by using log base 10 with the value and then converting the result to a integer.
log10 (103) approx. 2.04 => 2
Modulus the initial value by 10 to get the ones place and store it in a variable called temp
Subtract the ones place from the initial value and store that in a variable called newStart.
divide this value by 10
Subtract one from the decimal place and store in another variable called newDecimal.
Return the ones place times 10 to the power of the decimal place and add it to the function where the initial value is newStart and the decimalPlace is newDecimal.
#include <stdio.h>
#include <math.h>
int ReverseInt(int startValue, int decimalPlace);
int main()
{
int i = -54;
int positive = i < 0? i*-1 : i;
double d = log10(positive);
int output = ReverseInt(positive,(int)d);
int correctedOutput = i < 0? output*-1 : output;
printf("%d \n",correctedOutput);
return 0;
}
int ReverseInt(int startValue, int decimalPlace)
{
if(decimalPlace == 0)
{
return startValue;
}
int temp = startValue % 10;
int newStart = (startValue -temp)/10;
int newDecimal = decimalPlace -1;
int value = temp*pow(10,decimalPlace);
return value + ReverseInt(newStart,newDecimal);
}

Modular multiplicative inverse

I calculating ((A^B)/C)%M, but my code is not working when A,B,C,M are large in numbers. This code is giving right answer when A,B,C,D is small int.
What is wrong here?
Here C and M is co-prime
Sample input
2 3 4 5
Sample output
2
Code fails for these input
969109092 60139073 122541116 75884463
C program
#include <stdio.h>
int d,x,y;
Modular exponential (A^B)%M
int power(int A, int B, int M)
{
long long int result=1;
while(B>0)
{
if(B % 2 ==1)
{
result=(result * A)%M;
}
A=(A*A)%M;
B=B/2;
}
return result;
}
Modular multiplicative inverse
void extendedEuclid(int A, int B)
{
if(B == 0)
{
d = A;
x = 1;
y = 0;
}
else
{
extendedEuclid(B,A%B);
int temp = x;
x = y;
y = temp - (A/B)*y;
}
}
int modInv(int A, int M)
{
extendedEuclid(A,M);
return (x%M+M)%M;
}
main()
int main()
{
int A,B,C,M;
scanf("%d %d %d %d",&A,&B,&C,&M);
int inv = modInv(C,M)%M;
printf("%d\n",inv);
long long int p = (power(A,B,M))%M;
printf("%d\n",p);
long long int ans = (p * inv)%M;
//printf("%d",((modInv(C,M)*(power(A,B,M))))%M);
printf("%lld",ans);
return 0;
}
Code has at least the following issues:
int overflow in A*A. Code needs to calculate the product A*A using wider math. That is why code works with small values, but not large.
// A=(A*A)%M;
A = ((long long)A*A) % M;
// or
A = (1LL*A*A) % M;
Wrong print specifier. This implies compiler warnings are not fully enabled. Save time, Enable them all.
long long int p = (power(A,B,M))%M;
// printf("%d\n",p);
printf("%lld\n",p);
Code is amiss with negative values. Rather than patch that int hole, use unsigned types.
unsigned power(unsigned A, unsigned B, unsigned M) {
unsigned long long result = 1;
...
Failed corner case in power(A,0,1). result should be 0 when M==1.
// long long int result=1;
long long int result=1%M;
Test version with fixes noted in comments:
#include <stdio.h>
int d,x,y;
int power(int A, int B, int M)
{
long long int result=1;
long long int S = A; /* fix */
while(B>0)
{
if(B % 2 ==1)
{
result=(result * S)%M; /* fix */
}
S=(S*S)%M; /* fix */
B=B/2;
}
return (int)result;
}
void extendedEuclid(int A, int B)
{
int temp; /* C */
if(B == 0)
{
d = A;
x = 1;
y = 0;
}
else
{
extendedEuclid(B,A%B);
temp = x;
x = y;
y = temp - (A/B)*y;
}
}
int modInv(int A, int M)
{
extendedEuclid(A,M);
/* x = x%M; ** not needed */
if (x < 0) /* fix */
x += M; /* fix */
return (x); /* fix */
}
int main()
{
int A,B,C,M; /* C */
int inv, p, ans; /* C */
A = 969109092; /* 2^2 × 3^2 ×7 × 1249 × 3079 */
B = 60139073; /* 60139073 */
C = 122541116; /* 2^2 × 1621 × 18899 */
M = 75884463; /* 3^2 × 8431607 */
inv = modInv(C,M)%M; /* 15543920 */
printf("%d\n",inv);
p = power(A,B,M)%M; /* 6704397 */
printf("%d\n",p);
ans = (unsigned)(((unsigned long long)p * inv)%M); /* fix 22271562 */
printf("%d\n",ans);
return 0;
}
The value of int is probably not large enough, try with long, or double.
Be careful because power returns an int not long long int
You can try the mod_inv C function :
// return a modular multiplicative inverse of n with respect to the modulus.
// return 0 if the linear congruence has no solutions.
unsigned mod_inv(unsigned ra, unsigned rb) {
unsigned rc, sa = 1, sb = 0, sc, i = 0;
if (rb > 1) do {
rc = ra % rb;
sc = sa - (ra / rb) * sb;
sa = sb, sb = sc;
ra = rb, rb = rc;
} while (++i, rc);
sa *= (i *= ra == 1) != 0;
sa += (i & 1) * sb;
return sa;
}
This is basically the standard algorithm, to avoid overflows the signs are stored into the d variable, you could use a struct to do this. Also, when n = 1 and mod = 0 the output is 0, not 1, i think we have not many computations to execute modulo 0.
The modular multiplicative inverse of an integer N modulo m is an integer n such as the inverse of N modulo m equals n, if a modular inverse exists then it is unique. To calculate the value of the modulo inverse, use the extended euclidean algorithm which finds solutions to the Bezout identity.
Example of usage :
#include <assert.h>
int main(void) {
unsigned n, mod, res;
n = 52, mod = 107;
res = mod_inv(n, mod);
assert(res == 35); // 35 is a solution of the linear congruence.
n = 66, mod = 123;
res = mod_inv(n, mod);
assert(res == 0); // 66 does note have an inverse modulo 123.
}
/*
n = 7 and mod = 45 then res = 13 so 1 == ( 13 * 7 ) % 45
n = 52 and mod = 107 then res = 35 so 1 == ( 35 * 52 ) % 107
n = 213 and mod = 155 then res = 147 so 1 == ( 147 * 213 ) % 155
n = 392 and mod = 45 then res = 38 so 1 == ( 38 * 392 ) % 45
n = 687 and mod = 662 then res = 53 so 1 == ( 53 * 687 ) % 662
n = 451 and mod = 799 then res = 512 so 1 == ( 512 * 451 ) % 799
n = 1630 and mod = 259 then res = 167 so 1 == ( 167 * 1630 ) % 259
n = 4277 and mod = 4722 then res = 191 so 1 == ( 191 * 4277 ) % 4722
*/
Source

Exponential problems and their C representation

I came across well-known N-Queen problem and I was wondering how to write a program to calculate number of possibilities in this particular problem. My program can find solution fast for really small N's (since it's heuristic).
I'd also like to know how to represent such big numbers in C. Are there any algorithms for really big numbers? Anytime I write and implementation of my own arithmetic I get i. e. quadratic multiplication with tons of memory allocation what cannot be fast. Thank you in advance for exhaustive answer.
here is a nice solution, using recursion
(taken from: <http://rosettacode.org/wiki/N-queens_problem#C>)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint32_t uint;
uint full, *qs, count = 0, nn;
void solve(uint d, uint c, uint l, uint r)
{
uint b, a, *s;
if (!d) // exit condition
{
count++;
#if 0
printf("\nNo. %d\n===========\n", count);
for (a = 0; a < nn; a++, putchar('\n'))
{
for (b = 0; b < nn; b++, putchar(' '))
{
putchar(" -QQ"[((b == qs[a])<<1)|((a + b)&1)]);
} // end for
} // end for
#endif
return;
} // end if
a = (c | (l <<= 1) | (r >>= 1)) & full;
if (a != full)
{
for (*(s = qs + --d) = 0, b = 1; b <= full; (*s)++, b <<= 1)
{
if (!(b & a))
{
solve(d, b|c, b|l, b|r);
} // end if
} // end for
} // end if
} // end function: solve
int main(int n, char **argv)
{
if (n <= 1 || (nn = atoi(argv[1])) <= 0) nn = 8;
qs = calloc(nn, sizeof(int));
full = (1U << nn) - 1;
solve(nn, 0, 0, 0);
printf("\nSolutions: %d\n", count);
return 0;
} // end function: main

Optimizing a program for solving ax+by=c with positve integers

I am writing a program that for any given positive integers a < b < c will output YES if there is a solution to ax+by=c where x and y are also positive integers (x,y > 0), or NO if there isn't a solution. Keep in mind that I need to work with big numbers.
The approach I take for solving this problem is that I subtract b from c and I check if this number is divisable by a.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
int main(){
unsigned long long int a, b, c;
scanf("%I64u %I64u %I64u", &a, &b, &c);
while(c>=a+b){ //if c becomes less than a+b, than there's no sollution
c-=b;
if(c%a==0){
printf("YES");
return 0;
}
}
printf("NO");
return 0;
}
is there a more optimised way to find wether ax+by=c has positive sollutions? I tried reading about linear Diophantine equations, but all I found is a way to find integer sollutions (but not positive).
My approach so far.
Use Euclidean Algorithm to find GCD(a, b)
There are solutions (in integers) to ax + by = c if and only if GCD(a, b) divides c. No integer solutions means no positive solutions.
use Extended Euclidean Algorithm to solve the Diophantine equation and return NO if it gives non-positive solutions.
For comparisons it's hard to find examples that take longer than a second but in deciding on thousands of random equations the performance difference is noticeable. This Lecture has a solution for finding the number of positive
solutions to a Linear Diophantine Equation.
typedef unsigned long long int BigInt;
int pos_solvable(BigInt a, BigInt b, BigInt c) {
/* returns 1 if there exists x, y > 0 s.t. ax + by = c
* where 0 < a < b < c
* returns 0, otherwise
*/
BigInt gcd = a, bb = b, temp;
while (bb) { /* Euclidean Algorithm */
temp = bb;
bb = gcd % bb;
gcd = temp;
}
if (c % gcd) { /* no integer (or positive) solution */
return 0;
} else {
/* Extended Euclidean Algorithm */
BigInt s = 0, old_s = 1;
BigInt t = 1, old_t = 0;
BigInt r = b / gcd, old_r = a / gcd;
while (r > 0) {
BigInt quotient = old_r / r;
BigInt ds = quotient * s;
BigInt dt = quotient * t;
if (ds > old_s || dt > old_t)
return 0; /* will give non-positive solution */
temp = s;
s = old_s - ds;
old_s = temp;
temp = t;
t = old_t - dt;
old_t = temp;
temp = r;
r = old_r - quotient * r;
old_r = temp;
}
return 1;
}
}
The following is a comment but too big for the comment section.
This is posted to help others dig into this problem a little deeper.
OP: Incorporate any of in your post if you like.
What is still needed are some challenging a,b,c.
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//#define LLF "%I64u"
#define LLF "%llu"
int main(void) {
unsigned long long int a, b, c, x, y, sum, c0;
// scanf(LLF LLF LLF, &a, &b, &c);
c = c0 = ULLONG_MAX;
b = 10000223;
a = 10000169;
y = 0;
sum = a + b;
time_t t0 = time(NULL);
while (c >= sum) { //if c becomes less than a+b, than there's no solution
c -= b;
if (c % a == 0) {
break;
}
}
if (c % a == 0) {
y = (c0 - c) / b;
x = c / a;
printf("YES " LLF "*" LLF " + " LLF "*" LLF " = " LLF "\n", a, x, b, y, c);
} else {
printf("NO\n");
}
time_t t1 = time(NULL);
printf("time :" LLF "\n", (unsigned long long) (t1 - t0));
return 0;
}
Output
YES 10000169*1844638544065 + 10000223*4688810 = 18446697184563946985
time :0

Resources