For my Intro. to programming exam review I was asked to write a program which uses a function to calculate the gcd of a set of numbers. I wrote the following code, which sometimes seems to work fine, but others returns Floating Point Exception 8. I was hoping someone could shed some light.
I complied it using clang gcd.c -o gcd on the mac terminal using macOS High Sierra and the numbers that return the FP error were 5372 18960 -230048 1185 16486
This is the code:
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b){
if((a==0) || (b==0)){
return 0;
}else{
if( a % b == 0 ){
return b;
}else{
if ( b % a == 0 ){
return a;
}
}
}
while( (a != 0) && (b != 0) ){
if (abs(a)>abs(b)){
a = abs(a) % abs(b);
}
if(b>a){
b = abs(b) % abs(a);
}
}
if (a == 0){
return b;
}else{
return a;
}
}
int main(void){
int n;
printf("Please enter the number of integers in your array:\n");
scanf("%d", &n);
int a[n];
printf("Please enter the numbers in your arrray:\n");
for (int i = 0; i < n; ++i){
scanf("%d", &a[i]);
}
for (int i = 0; i < (n-1); ++i){
a[i] = gcd(a[i], a[i+1]);
}
printf("The gcd of the %d numbers is %d .\n", n, a[n-2]);
return 0;
}
Looks like couple of mistakes in your code for finding GCD.
You should update the value of a[i+1] in your for loop instead of a[i]. And the GCD will be a[n-1]th element after this change. As you iterate over the loop a[i] and a[i+1] will be original (input) values in your case. So if everything else works fine, your result will be GCD of last two elements of the array (a[n-2], a[n-1]).
for (int i = 0; i < (n-1); ++i) {
a[i+1] = gcd(a[i], a[i+1]);
}
In the while loop of gcd(), you need to make the following changes. Check for a==b conditionality and change the two if conditions to if-else conditions. In case b is a factor of a, a becomes 0 in your first if condition. Then in the second condition, you are doing % 0 which is throwing the error.
while( (a != 0) && (b != 0) ){
if (abs(a)>=abs(b){
a = abs(a) % abs(b);
}
else if(abs(b)>abs(a)){
b = abs(b) % abs(a);
}
}
first impression in the while loop below
while( (a != 0) && (b != 0) ){
if (abs(a)>abs(b)){
a = abs(a) % abs(b); // value of a is altered and reused
}
if(b>a){
b = abs(b) % abs(a); // here <-- and could very well be a 0
}
}
on a completely different note your could remove else {} blocks, if you could take a moment and see that else blocks are not really adding any value because there is a return in if
int gcd(int a, int b){
/** sanity checks */
if((a==0) || (b==0))
return 0;
/* few more obvious checks */
if( a % b == 0 )
return b;
if( b % a == 0 )
return a;
/* Real Logic */
while( (a != 0) && (b != 0) ){
if (abs(a)>abs(b)){
a = abs(a) % abs(b);
}
else if(abs(b) > abs(a) ){
b = abs(b) % abs(a);
}
}
/* Final results */
return (a == 0) ? b : a;
}
Related
I tried to program to add the previous three numbers of an nth number recursively until attaining
the nth value
for example ;
func(n) = {return a if n = 1 ; return b if n= 2 ;return c if n = 3 ;return func(n - 1) + func( n - 2) + func( n - 3) if n > 3}
}
int find_nth_term(int n , int a ,int b,int c)
{
if (n == 2)
{
return b;
}
else if (n == 1)
{
return a;
}
else if (n == 3)
{
return c;
}
else if (n > 3)
{
int temp = a + b +c;
a= b;
b = c;
c = temp;
return find_nth_term(n-1, a ,b,c);
}
}
int main() {
int n, a, b, c;
scanf("%d %d %d %d", &n, &a, &b, &c);
int ans = find_nth_term(n, a, b, c);
printf("%d", ans);
return 0;
If none of the conditions on n hold, e.g. when n is negative, the execution of the function will reach the final curly brace without having returned any value.
The most important observation here, is that there is no need to use else in combination with return. The function either returns or continues. An example with some random numbers:
int some_function(int n)
{
if (n == 1)
return 5;
if (n > 3)
return 11;
if (n < 100)
return 41;
return -1;
}
The function must return an int
Look at your code and focus on if, else-if blocks. Those blocks matches if n is 1,2,3 or greater and return something. But, what if n is 0 or less than 0? What does it return? Which if block caches it? This is why the compiler is complaining. In all cases the function must return something.
So, you'll have to add an else block after the last else-if or you can add a return expression at the bottom of function block. Like return -1;
else if (n > 3)
{
int temp = a + b +c;
a= b;
b = c;
c = temp;
return find_nth_term(n-1, a ,b,c);
} else {
return -1;
}
I am coding in C in a university course and we got a project to take equations from the user and give solutions for matrices etc...
My problem is that I am trying to use atof() function and for a reason I can't find in the same loop once it works and the other times it doesn't.
I have tried already other functions to replace atof like strtod but it doesn't work as well.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdbool>
void main()
{
int num, check = 0,i,j,k=0,len1=0;
char equ[80],tempx[20],tempy[20], tempz[20], tempd[20];
double *x, *y, *z, *d;
printf_s("Number of equations (1-3): ");
scanf_s("%d", &num);
getchar();
while (check == 0) //a check to see if we got a number between 1-3.
{
if (num > 0 && num < 4)
check = 1;
else
{
printf_s("Please enter a number between 1-3.\n");
printf_s("Number of equations (1-3): ");
scanf_s("%d", &num);
}
}
x = malloc(sizeof(double)*num);
if (!x) exit(1);
y = malloc(sizeof(double)*num);
if (!y) exit(1);
z = malloc(sizeof(double)*num);
if (!z) exit(1);
d = malloc(sizeof(double)*num);
if (!d) exit(1);
for (i = 0; i < num; i++) //getting the equations and putting them into the matrix
{
printf_s("Enter equation %d: ", i + 1);
gets_s(equ, sizeof(equ));
len1 = strlen(equ);
for (j = 0; j <len1 ; j++)
{
if (equ[j] == 'x')
{
k = 0;
while ((equ[j-k] != '+' || equ[j-k] != '-') && j-k>=0)
{
tempx[j-k] = equ[j-k];
k++;
}
x[i] = atof(tempx);
}
else if (equ[j] == 'y')
{
k = 0;
while ((equ[j-k] != '+' || equ[j-k] != '-') && j - k >= 0)
{
tempy[j-k] = equ[j-k];
k++;
}
y[i] = atof(tempy);
}
else if (equ[j] == 'z')
{
k = 0;
while ((equ[j - k] != '+' || equ[j - k] != '-') && j - k >= 0)
{
tempz[j-k] = equ[j - k];
k++;
}
z[i] = atof(tempz);
}
else if (equ[j] == '=')
{
k = 0;
while (equ[j+k])
{
tempd[k] = equ[j + k];
k++;
}
d[i] = atof(tempd);
}
}
}
free(x);
free(y);
free(z);
free(d);
}
I expected to get the same result in d[i] as I did in x[i] but every time I try to print d[i] I get 0.0000. When I tried the function _strrev on tempd inside atof I got the reverse result inside d[i].
So the problem was that in the last loop i inserted a string that start with "=" and not a number. Apparently atof() doesn't work when the first char is not a number.
#include<stdio.h>
#include <stdlib.h>
int main()
{
long long int a;
int flag = 0;
scanf("%lld", &a);
if (a > 0)
{
while (a > 0)
{
if (a % 2 == 0 || a == 1)
{
a = a / 2;
flag = 1;
}
else
{
flag = 0;
break;
}
}
}
if (a < 0)
{
while (a <= -1)
{
if (a % 2 == 0 || a == -1)
{
a = a / 2;
flag = 1;
}
else
{
flag = 0;
break;
}
}
}
if (flag == 1)
{
printf("yes");
}
else
{
printf("no");
}
}
click this for output image
Given an integer N, the program must determine if it is a power of 2 or -2. If N is a power of 2 or -2, the program must print yes. Else the program must print no.
Boundary Condition(s):
-10^17 <= N <= 10^17
Input Format:
The first line contains the value of N.
Output Format:
The first line contains either yes or no
For the input -4503599627370496 it should print no but it prints yes. Solution, please
In case of negative numbers, you should also count which power of 2 is it. If it is even it won't work. -2 to the power 52 gives 4503599627370496 instead of -4503599627370496.
The code below solves this puzzle using bitwise shift operator:
#include <stdio.h>
#include <stdlib.h>
int main()
{
long long int a, aPositive, l = 1;
scanf("%lld", &a);
aPositive = a > 0 ? a : -a;
int count = 0;
while (l < aPositive)
{
l = l << 1;
count++;
//printf("%d\t%lld\n", count, l);
}
if (l == aPositive && (a > 0 || count % 2 == 1))
{
printf("yes");
}
else
{
printf("no");
}
return 0;
}
Very similar problem has been solved here: how-to-check-if-a-number-is-a-power-of-2
bool IsPowerOfTwo(long long x)
{
return (x != 0) && ((x & (x - 1)) == 0);
}
int main()
{
bool result = IsPowerOfTwo(256);
if (result )
{
printf("yes");
}
else
{
printf("no");
}
return 0;
}
This code fails on certain primes (7, 13, 19..) but works on different ones (5, 11, 17..). Without the prime condition it works everytime, as well as does the is_prime function. Did I write the condition badly? It should return next prime if input number is prime and return -1 when it is not.
int next_prime(int prime) {
int c;
if(is_prime(prime) == 0)
return -1;
if(prime < 2)
c = 2;
else if (prime == 2)
c = 3;
else if(prime & 1){
prime += 2;
c = is_prime(prime) ? prime : next_prime(prime);
} else
c = next_prime(prime-1);
return c;
}
Edit: is_prime worked on all tried numbers, I believe it is correct.
int is_prime(int num){
if(num == 1)
return 0;
if((num & 1)==0)
return num == 2;
else {
int i, limit = sqrt(num);
for (i = 3; i <= limit; i+=2){
if (num % i == 0)
return 0;
}
}
return 1;
}
Your next_prime function is somewhat weird and overly complicated, why don't you just use this:
int next_prime(int prime) {
while (!is_prime(++prime))
{
}
return prime;
}
This happens in your next_prime function:
Let's suppose you call next_prime(7):
int next_prime(int prime) {
int c;
if (is_prime(prime) == 0)
return -1;
if (prime < 2)
c = 2;
else if (prime == 2)
c = 3;
else if (prime & 1) {
prime += 2;
c = is_prime(prime) ? prime : next_prime(prime);
}
else
c = next_prime(prime - 1);
return c;
}
None of the first three tests is true, to we end up at else if (prime & 1). This test is true, so following lines will be executed:
prime += 2; // prime becomes 9 (7 + 2)
is_prime(9) is false so you execute next_prime(9)
c = is_prime(prime) ? prime : next_prime(prime);
and next_prime(9) will obviously return -1.
You could have found out that yourself by using a debugger.
i'm newbie in C programming .
i have written this code for adding two numbers with 100 digits , but i don't know why the code does not work correctly , it suppose to move the carry but it doesn't .
and the other problem is its just ignoring the first digit (most significant digit) .
can anybody help me please ?
#include <stdio.h>
#include <ctype.h>
int sum[101] = {0};
int add(int a, int b);
void main()
{
static int a[100];
static int b[100];
char ch;
int i = 0;
int t;
for (t = 0; t != 100; ++t)
{
a[t] = 0;
}
for (t = 0; t != 100; ++t)
{
b[t] = 0;
}
do
{
ch = fgetc(stdin);
if ( isdigit(ch) )
{
a[i] = ch - 48;
++i;
}
else
break;
}
while (ch != '\n' || i == 100 || i != '\0');
i = 0;
do
{
ch = fgetc(stdin);
if ( isdigit(ch) )
{
b[i] = ch - 48;
++i;
}
else
break;
}
while (ch != '\n' || i == 100 || i != '\0');
for (;i!=0; --i)
{
add(a[i], b[i]);
}
for (i==0;i != 101; ++i)
{
printf("%d", sum[i]);
}
}
int add( int a , int b)
{
static int carry = 0;
float s = 0;
static int p = 101;
if (0 <= a+b+carry <= 9)
{
sum[p] = (a + b + carry);
carry = 0;
--p;
return 0;
}
else
{
if (10 <= a+b+carry < 20)
{
s = (((a+b+carry)/10.0 ) - 1) * 10 ;
carry = ((a+b+carry)/10.0) - (s/10);
}
else
{
s = (((a+b+carry)/10 ) - 2) * 10;
carry = ((a+b+carry)/10.0) - (s/10);
}
sum[p] = s;
--p;
return 0;
}
}
Your input loops have serious problem. Also you use i to count the length of both a and b, but you don't store the length of a. So if they type two numbers that are not equal length then you will get strange results.
The losing of the first digit is because of the loop:
for (;i!=0; --i)
This will execute for values i, i-1, i-2, ..., 1. It never executes with i == 0. The order of operations at the end of each iteration of a for loop is:
apply the third condition --i
test the second condition i != 0
if test succeeded, enter loop body
Here is some fixed up code:
int a_len;
for (a_len = 0; a_len != 100; ++a_len)
{
int ch = fgetc(stdin); // IMPORTANT: int, not char
if ( ch == '\n' || ch == EOF )
break;
a[a_len] = ch;
}
Similarly for b. In fact it would be a smart idea to make this code be a function, instead of copy-pasting it and changing a to b.
Once the input is complete, then you could write:
if ( a_len != b_len )
{
fprintf(stderr, "My program doesn't support numbers of different length yet\n");
exit(EXIT_FAILURE);
}
for (int i = a_len - 1; i >= 0; --i)
{
add(a[i], b[i]);
}
Moving onto the add function there are more serious problems here:
It's not even possible to hit the case of sum being 20
Do not use floating point, it introduces inaccuracies. Instead, doing s = a+b+carry - 10; carry = 1; achieves what you want.
You write out of bounds of sum: an array of size [101] has valid indices 0 through 100. But p starts at 101.
NB. The way that large-number code normally tackles the problems of different size input, and some other problems, is to have a[0] be the least-significant digit; then you can just expand into the unused places as far as you need to go when you are adding or multiplying.