LCM of two numbers - c

I am getting wrong result for my LCM program.
Ifirst find gcd of the numbers and then divide the product with gcd.
int gcd(int x, int y)
{
while(y != 0)
{
int save = y;
y = x % y;
x = save;
}
return y;
}
int lcm(int x, int y)
{
int prod = x * y;
int Gcd = gcd(x,y);
int lcm = prod / Gcd;
return lcm;
}
Any help much appreciated.

Your gcd function will always return 0. Change
return y;
to
return x;
Understand the Euclid's algorithm:
RULE 1: gcd(x,0) = x
RULE 2: gcd(x,y) = gcd(y,x % y)
consider x = 12 and y = 18
gcd (12, 18)
= gcd (18, 12) Using rule 2
= gcd (12,6) Using rule 2
= gcd (6, 0) Using rule 1
= 6
As you can see when y becomes zero x will be the gcd so you need to return x and not y.
Also while calculating lcm you are multiplying the numbers first which can cause overflow. Instead you can do:
lcm = x * (y / gcd(x,y))
but if lcm cannot fit in an int you'll have to make it long long

Problem 1) int gcd = gcd(x,y);
gcd is already defined to be a function. You cannot define a variable with the same name.
Problem 2) Change return y to return x in gcd() otherwise 0 will be returned everytime.
Problem 3) x * y may overflow if x and y are large.

You should return x instead of y in your gcd function.
Also, are you sure the product x*y will always fit into an int? Might be a good idea to use a long long for that as well.

#include <iostream>
using namespace std;
long long gcd(long long int a, long long int b){
if(b==0)
return a;
return gcd(b,a%b);
}
long long lcm(long long a,long long b){
if(a>b)
return (a/gcd(a,b))*b;
else
return (b/gcd(a,b))*a;
}
int main(){
long long int a ,b ;
cin>>a>>b;
cout<<lcm(a,b)<<endl;
return 0;
}

This C program is different approach towards finding LCM
#include<stdio.h>
int main()
{
int a,b,lcm=1,i=2;
printf("Enter two numbers to find LCM\n" );
scanf("%d %d",&a ,&b);
while(i <= a*b)
{
if(a%i==0 & b%i==0)
{
lcm=lcm*i;
a=a/i;
b=b/i;
i=i-1;
}
if( a%i==0 & b%i!=0)
{
lcm=lcm*i;
a=a/i;
i=i-1;
}
if( b%i==0 & a%i!=0)
{
lcm=lcm*i;
b=b/i;
i=i-1;
}
i++;
}
printf("The LCM of numbers is %d\n", lcm);
}

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);
}

How to handle negative numbers: getting quotient and remainder without the '/', '%', and '*' operators in C

This program works in handling positive integers, but not on negative integers. How can I fix this one? Thanks!
By the way, is my code good or not? Is there a better way on getting the quotient and remainder without using the '/', '%', and '*' operators?
#include <stdio.h>
int divide(int x, int y, int quotient);
int getRem(int x, int y, int quotient, int product, int count,
int remainder);
int main()
{
int dividend, divisor, quotient = 0, product = 0;
int remainder, count = 0;
scanf("%d %d", &dividend, &divisor);
printf("\nQuotient: %d", divide(dividend, divisor, quotient));
quotient = divide(dividend, divisor, quotient);
printf("\nRemainder: %d", getRem(dividend, divisor, quotient, product, count, remainder));
}
int divide(int x, int y, int quotient)
{
while (x > 0)
{
x -= y;
quotient++;
}
if (x != 0)
return quotient - 1;
else
return quotient;
}
int getRem(int x, int y, int quotient, int product, int count, int remainder)
{
while (count != y)
{
product += quotient;
count++;
remainder = x - product;
}
return remainder;
}
By the way, is my code good or not?
Well, there's room for improvements...
First of all - don't pass unnecessary variables to your function!
A function that shall divide x by y shall only take x and y as arguments. Whatever variables you need inside the function shall be defined inside the function.
So the first step is to change your divide function to be:
int divide(int x, int y)
{
int quotient = 0; // use a local variable
while (x > 0)
{
x -= y;
quotient++;
}
if (x != 0)
return quotient - 1;
else
return quotient;
}
Another (minor) issue is the two return statements. With a simple change of the while statement that can be avoided.
int divide(int x, int y)
{
int quotient = 0; // use a local variable
while (x >= y) // notice this change
{
x -= y;
quotient++;
}
return quotient;
}
Also notice that a call like divide(42, 0); will cause an infinite loop. So perhaps you should check for y being zero.
The algorithm can be improved - especially for large numbers - but I guess you want a simple approach so I stick to your basic algorithm.
... but not on negative integers. How can I fix this one?
A simple approach is to convert any negative input before entering the loop and maintain a counter to remember the number of negative numbers. Something like:
int divide(int x, int y)
{
int quotient = 0;
int negative = 0;
if (x < 0)
{
x = -x; // Make x positive
++negative;
}
if (y < 0)
{
y = -y; // Make y positive
++negative;
}
while (x >= y) // Both x and y are positive here
{
x -= y;
quotient++;
}
return (negative == 1) ? -quotient : quotient;
}
int main(void)
{
printf("%d\n", divide( 5, 2));
printf("%d\n", divide( 5,-2));
printf("%d\n", divide(-5, 2));
printf("%d\n", divide(-5,-2));
printf("%d\n", divide( 6, 2));
printf("%d\n", divide( 6,-2));
printf("%d\n", divide(-6, 2));
printf("%d\n", divide(-6,-2));
return 0;
}
Output:
2
-2
-2
2
3
-3
-3
3
You can apply the same kind of changes to the function getRem and I'll leave that part for you as an exercise...
However, notice that your current function uses quotient without any benefit. The function (only handling positive numbers) could simply be:
int getRem(int x, int y) // requires x >= 0 and y > 0
{
while (x >= y)
{
x -= y;
}
return x;
}
Is there a better way of getting the quotient and remainder without using the '/', '%', and '*' operators?
The majority of the time, I think, by far the best way of computing quotient and remainder is with the / and % operators. (It's their job, after all!)
If you need both quotient and remainder at the same time, there's also the div function, which does exactly that. (Its return value is a struct containing quot and rem members.) It's a bit cumbersome to use, but it might be more efficient if it means executing a single divide instruction (which tends to give you both quotient and remainder at the machine level anyway) instead of two. (Or, these days, with a modern optimizing compiler, I suspect it wouldn't make any difference anyway.)
But no matter how you do it, there's always a question when it comes to negative numbers. If the dividend or the divisor is negative, what sign(s) should the quotient and remainder be? There are basically two answers. (Actually, there are more than two, but these are the two I think about.)
In Euclidean division, the remainder is always positive, and is therefore always in the range [0,divisor) (that is, between 0 and divisor-1).
In many programming languages (including C), the remainder always has the sign of the dividend.
See the Wikipedia article on modulo operation for much, much more information on these and other alternatives.
If your programming language gives you the second definition (as C does), but you want a remainder that's never negative, one way to fix it is just to do a regular division, test whether the remainder is negative, and if it is, increment the remainder by the divisor and decrement the quotient by 1:
quotient = x / y;
remainder = x % y;
if(remainder < 0) {
reminder += y;
quotient--;
}
This works because of the formal definition of integer division with remainder:
div(x, y) → q, r such that y × q + r = x
If you subtract 1 from q and add y to r, you get the same result, and it's still x.
Here's a sample program demonstrating three different alternatives. I've encapsulated the little "adjust quotient for nonnegative remainder" algorithm as the function euclid(), which returns the same div_t type as div() does:
#include <stdio.h>
#include <stdlib.h>
div_t euclid(int, int);
int main()
{
int x = -7, y = 3;
printf("operators: q = %d, r = %d\n", x/y, x%y);
div_t qr = div(x, y);
printf("div: q = %d, r = %d\n", qr.quot, qr.rem);
qr = euclid(x, y);
printf("euclid: q = %d, r = %d\n", qr.quot, qr.rem);
}
div_t euclid(int x, int y)
{
div_t qr = div(x, y);
if(qr.rem < 0) {
qr.quot--;
qr.rem += y;
}
return qr;
}
To really explore this, you'll want to try things out for all four cases:
positive dividend, positive divisor (the normal case, no ambiguity)
negative dividend, positive divisor (the case I showed)
positive dividend, negative divisor
negative dividend, negative divisor
This program works in handling positive integers, but not on negative integers. How can I fix this one?
When you call :
divide(-10, 3) or divide(-10, -3) the while loop condition while(x > 0) will be false
divide(10, -3) the while loop will be infinite loop because of the statement x -= y. (x) will be increase by the value of (y)
is my code good or not?
Your code is need to be organized:
in the main function you need to pass only the necessary parameters. in the divide function why you pass the quotient. the quotient will be calculated inside the function. so that you should edit the prototype to int divide(int x, int y);.
the same thing with getRem function you should edit the prototype to int getRem(int x, int y);.
in the main function you are calling the divide function twice to print the quotient and to save the quotient in the variable quotient. instead you should call the function only one time and reuse the returned value.
After the previous points your main and functions prototypes should be as follow:
#include <stdio.h>
int divide(int x, int y);
int getRem(int x, int y);
int main()
{
int dividend, divisor, quotient = 0;
scanf("%d %d", &dividend, &divisor);
quotient = divide(dividend, divisor);
printf("\nQuotient: %d", quotient);
printf("\nRemainder: %d", getRem(dividend, divisor));
}
Now lets analyze the function divide. The first point, In math when multiplying or dividing, you actually do the operation on the sign as doing on the number. the following is the math rules for multiply or divide the sign.
negative * positive -> negative
positive * negative -> negative
negative * negative -> positive
negative / positive -> negative
positive / negative -> negative
negative / negative -> positive
The second point is the while loop. You should divide until (x) is less than (y).
As an example: suppose x = 7, y = 3 :
after first loop x -> 4 and y -> 3
after second loop x -> 1 and y -> 3 so that the condition should be while(x >= y)
so now you should first manipulate the sign division after that the numbers division. as follows.
int divide(int x, int y)
{
int quotient = 0;
//save the resulting sign in the sign variable
int sign = 1;
int temp = 0;
/* sign division */
// negative / positive -> negative
if((x < 0) && (y >= 0)){
sign = -1;
temp = x;
x -= temp;
x -= temp;
}// positive / negative -> negative
else if((x >= 0) && (y < 0)){
sign = -1;
temp = y;
y -= temp;
y -= temp;
}// negative / negative -> positive
else if((x < 0) && (y < 0)){
temp = x;
x -= temp;
x -= temp;
temp = y;
y -= temp;
y -= temp;
}
while (x >= y)
{
x -= y;
quotient++;
}
if(sign < 0){
temp = quotient;
quotient -= temp;
quotient -= temp;
}
return quotient;
}
Lets go into the getRem function. The remainder(%) operation rules is as follows:
negative % (negative or positive) -> negative
positive % (negative or positive) -> positive
note: the result follows the sign of the first operand
As an Example:
suppose x = -10 and y = 3, x / y = -3, to retrieve (x) multiply y and -3, so x = y * -3 = -9 the remainder is equal to -1
suppose x = 10 and y = -3, x / y = -3',x = y * -3 = 9` the remainder is equal to 1
now apply the previous points on the getRem function to get the following result:
int getRem(int x, int y)
{
int temp, remSign = 1;
if(x < 0){
remSign = -1;
temp = x;
x -= temp;
x -= temp;
}
if(y < 0){
temp = y;
y -= temp;
y -= temp;
}
while (x >= y)
{
x -= y;
}
if(remSign < 0){
x = -x;
}
return x;
}
You can to combine the two operation in one function using pointers for remainder as follows:
#include <stdio.h>
int divide(int x, int y,int * rem);
int getRem(int x, int y);
int main()
{
int dividend, divisor, quotient = 0;
int rem;
scanf("%d %d", &dividend, &divisor);
quotient = divide(dividend, divisor, &rem);
printf("\nQuotient: %d", quotient);
printf("\nRemainder: %d", rem);
}
int divide(int x, int y, int * rem)
{
int quotient = 0;
int sign = 1;
int remSign = 1;
int temp = 0;
if((x < 0) && (y >= 0)){
sign = -1;
remSign = -1;
temp = x;
x -= temp;
x -= temp;
}
else if((x >= 0) && (y < 0)){
sign = -1;
temp = y;
y -= temp;
y -= temp;
}
else if((x < 0) && (y < 0)){
temp = x;
x -= temp;
x -= temp;
temp = y;
y -= temp;
y -= temp;
}
while (x >= y)
{
x -= y;
quotient++;
}
if(remSign < 0){
*rem = -x;
}else{
*rem = x;
}
if(sign < 0){
temp = quotient;
quotient -= temp;
quotient -= temp;
}
return quotient;
}

How to implement natural logarithm with continued fraction in C?

Here I have a little problem. Create something from this formula:
This is what I have, but it doesn't work. Franky, I really don't understand how it should work.. I tried to code it with some bad instructions. N is number of iteration and parts of fraction. I think it leads somehow to recursion but don't know how.
Thanks for any help.
double contFragLog(double z, int n)
{
double cf = 2 * z;
double a, b;
for(int i = n; i >= 1; i--)
{
a = sq(i - 2) * sq(z);
b = i + i - 2;
cf = a / (b - cf);
}
return (1 + cf) / (1 - cf);
}
The central loop is messed. Reworked. Recursion not needed either. Just compute the deepest term first and work your way out.
double contFragLog(double z, int n) {
double zz = z*z;
double cf = 1.0; // Important this is not 0
for (int i = n; i >= 1; i--) {
cf = (2*i -1) - i*i*zz/cf;
}
return 2*z/cf;
}
void testln(double z) {
double y = log((1+z)/(1-z));
double y2 = contFragLog(z, 8);
printf("%e %e %e\n", z, y, y2);
}
int main() {
testln(0.2);
testln(0.5);
testln(0.8);
return 0;
}
Output
2.000000e-01 4.054651e-01 4.054651e-01
5.000000e-01 1.098612e+00 1.098612e+00
8.000000e-01 2.197225e+00 2.196987e+00
[Edit]
As prompted by #MicroVirus, I found double cf = 1.88*n - 0.95; to work better than double cf = 1.0;. As more terms are used, the value used makes less difference, yet a good initial cf requires fewer terms for a good answer, especially for |z| near 0.5. More work could be done here as I studied 0 < z <= 0.5. #MicroVirus suggestion of 2*n+1 may be close to my suggestion due to an off-by-one of what n is.
This is based on reverse computing and noting the value of CF[n] as n increased. I was surprised the "seed" value did not appear to be some nice integer equation.
Here's a solution to the problem that does use recursion (if anyone is interested):
#include <math.h>
#include <stdio.h>
/* `i` is the iteration of the recursion and `n` is
just for testing when we should end. 'zz' is z^2 */
double recursion (double zz, int i, int n) {
if (!n)
return 1;
return 2 * i - 1 - i * i * zz / recursion (zz, i + 1, --n);
}
double contFragLog (double z, int n) {
return 2 * z / recursion (z * z, 1, n);
}
void testln(double z) {
double y = log((1+z)/(1-z));
double y2 = contFragLog(z, 8);
printf("%e %e %e\n", z, y, y2);
}
int main() {
testln(0.2);
testln(0.5);
testln(0.8);
return 0;
}
The output is identical to the solution above:
2.000000e-01 4.054651e-01 4.054651e-01
5.000000e-01 1.098612e+00 1.098612e+00
8.000000e-01 2.197225e+00 2.196987e+00

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