Floating-point exception from fraction simplification program in C - c

When I run the following code, I always get a floating-point exception. How can I fix it?
#include <stdio.h>
//Global Variables
int num, denom, num1, denom1;
void simplify(int *numerator, int *denominator);
int main () {
//Prompt User as to what program is
printf("Fraction Simplifier\n");
printf("===================\n");
//Ask User for Numerator and Denominator
printf("Numerator: ");
scanf("%d", &num);
printf("Denominator: ");
scanf("%d", &denom);
//Call Function
simplify(&num1, &denom1);
//Display final output
printf("%d / %d = %d / %d", num, denom, num1, denom1);
return 0;
}
//Simplify function
void simplify(int *numerator, int *denominator)
{
num = num1;
denom = denom1;
num1 = num1 / num1;
denom1 = denom1 / num1;
num1 = *numerator;
denom1 = *denominator;
}

It looks as if num1 is never initialized. It will be zero, which will result in a division by zero.

Your simplify function is flawed. Here's what it means when you are calling simplify:
call simplify, passing the address of num1 and denom1
And here's what your code inside of simplify means:
num = num1; /* Assign the value of num1 to num, meaning set num to 0. */
denom = denom1; /* Assign the value of denom1 to denom, meaning set denom to 0. */
num1 = num1 / num1; /* Divide num1 (which is 0) by num1 (which is 0). Error! */
You can simplify your program and make it easier to understand by eliminating your global variables. This will also help you to correct your errors. Here's a rewrite:
#include <stdio.h>
void simplify(int numerator, int denominator, int* newNumerator, int* newDenominator);
int main () {
int num, denom, num1, denom1;
/* Do your input code */
//Call Function
simplify(num, denom, &num1, &denom1);
//Display final output
printf("%d / %d = %d / %d", num, denom, num1, denom1);
return 0;
}
//Simplify function
void simplify(int numerator, int denominator, int* newNumerator, int* newDenominator)
{
int simplifiedNumerator;
int simplifiedDenominator;
/* Calculate your results.. left out your original code, which calculates incorrectly */
/* You will refer to the ints numerator and denominator */
/* Assign your results */
*newNumerator = simplifiedNumerator;
*newDenominator = simplifiedDenominator;
}
Notice that simplify now has four parameters. The first two are the values you want to use in the calculation (we don't need pointers), and the pointers are only used to assign the results to the addresses passed in.

Related

Why am I getting a "Segmentation fault (core dumped)" with basic division function?

The program is supposed to do integer division and show the remainder. It should check the if the denominator is 0 and allow the user to correct it. However, when the denominator is 0 and a non-zero integer is re-entered, I get a segmentation fault. Could someone explain why and how I can rectify it. I also get a number of warnings. I am kind of new to using pointers.
Here is my code (C):
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
int n, d, den, rem;
int *dvd = &den;
int *rmn = &rem;
printf("Enter the numerator: "); //prompt a user to enter an integer numerator
scanf("%i", &n);
printf("%i\n", n);
printf("Enter the denominator: ");//prompt the user to enter an integer denominator
scanf("%i", &d);
printf("%i\n", d);
int division (int numerator, int denominator, int *dividend, int *remainder) {
while (denominator==0) {
printf("Number cannot be 0!\n");
printf("Enter another number ");
scanf("%i", denominator);
}
dividend = numerator/denominator;
remainder = numerator%denominator;
printf("%i/%i = %i with %i remainder\n",n, d, dividend, remainder);
}
division(n, d, *dvd, *rmn); // call the function division
return 0;
}
I have tried using the address of the denominator instead of the pointer which did not work. I also tried nesting the while loop in an if function.
Call the division function with division(n, d, dvd, rmn); and inside the function replace the uses of divident and remainder with *divident and *remainder.
void division (int numerator, int denominator, int *dividend, int *remainder) {
while (denominator==0) {
printf("Number cannot be 0!\n");
printf("Enter another number ");
scanf("%i", denominator);
}
*dividend = numerator/denominator;
*remainder = numerator%denominator;
printf("%i/%i = %i with %i remainder\n",n, d, *dividend, *remainder);
}

How to run a c program using loops to find the remainder of two numbers without using multiplication, division and modulo operators?

#include <stdio.h>
int main()
{
int num1, num2;
printf ("Input value for num1: ");
scanf ("%d", &num1);
printf ("Input value for num2: ");
scanf ("%d", &num2);
int prod =0, i;
for(i = 1; i <= num1; i++){
prod += num2;
}
int quo = 0 , rem = 0;
for(rem = num1 - num2; rem >= 0; rem = rem-num2) {
if(rem < 0)
break;
else
quo++;
}
//The last part is that i need to find the remainder without using multiplication, division and the modulo itself.
printf ("The product of %d and %d is: %d\n", num1, num2, prod);
printf ("The integer quotient of %d and %d is: %d\n", num1, num2, quo);
return 0;
}
The simplest solution for calculating a mod b for positive integers a and b with only subtraction and addition is to subtract b from a until the result is smaller than a. However, this takes many iterations if b is much smaller than a.
A method with better worst-case performance is the following:
#include <stdio.h>
unsigned rem(unsigned a, unsigned b)
{
if(b == 0) return 0; // Error
while(a >= b)
{
unsigned s = b;
do
{
a = a - s;
s = s + s;
} while(a >= s);
}
return a;
}
int main(void)
{
unsigned example = rem(32453, 3);
printf("%u\n", example);
}
This method is based on the fact that to get closer to the result, we can subtract any multiple of b as long as it is smaller than a, so in each inner iteration we try to subtract twice the multiples of the last iteration until the subtractor becomes too large and we start over again with a single multiple of b.
Be aware that this will give wrong results if s = s + s; overflows the unsigned range. Hence, a should not be larger than half the upper limit of unsigned.
If you want a slow calculation of num1 % num2 (i.e. without multiplication/division) you can do:
// Calculate num1 % num2
unsigned rem(unsigned num1, unsigned num2)
{
if (num2 == 0) {.... error handling ....}
while (num1 >= num2) num1 -= num2;
return num1;
}
int main(void)
{
unsigned num1 = 42;
unsigned num1 = 3;
unsigned rem = rem(num1, num2);
printf("%u", rem);
return 0;
}

Square root not diving properly

I've created a program which takes an integer x input, then loops until x is met while also taking other integer inputs. I then do various calculations, and then find a square root of a certain value. When I divide by square root however I get a 0 when I know I should be getting a different value as the maths doesn't add up.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main(void) {
int multiply1, multiply2, add, squareRoot;
int i;
int n;
int x;
int s;
double divide, test = 0;
scanf("%d", &x);
for (s = 0; s < x; s++) {
scanf("%d %d", &i ,&n);
}
multiply1 = i * i;
multiply2 = n * n;
add = multiply1 + multiply2;
squareRoot = sqrt(add);
printf("%d", i);
test = (i / squareRoot);
printf("Multiplication = %d\n", multiply1);
printf("Multiplication = %d\n", multiply2);
printf("Added together = %d\n", add);
printf("square root = %d\n", squareRoot);
printf("First output = %.3f\n", test);
return 0;
}
You are dividing two integers so the actual division returns the result rounded down. You should instead cast to double and then divide.
test = ((double)i/squareRoot);
There are two things you can do,
Without changing your program, simply cast the i and squareRoot variables to double
test = (double) i / (double) squareRoot;
Change your program and make i and squareRoot a double.
I, would choose 2 because sqrt() returns a double and that might cause an integer overflow.

My program prints 0 instead of the expected number

So I made a function that returns a value which is the connection (sum) of 2 numbers that the user gives. But everytime I enter these 2 numbers, the result is somehow always 0.
float connection(int num1, int num2, float result)
{
result= num1 + num2;
return (result);
}
int main()
{
int num1= 0;
int num2= 0;
float result= 0.0;
printf("\nChoose the first number you'd like to connect: ");
scanf("%d", &num1);
getchar();
printf("choose the second number you'd like to connect: ");
scanf("%d", &num2);
connection(num1, num2, result);
printf("The result is: %f", result);
}
The problem here is (I believe) that you expect the argument result you pass to the function to change value. That's not how C works, instead all arguments are passed by value and the variable result inside the called function is a local variable which has no connection to the result variable in the calling function. Changing one variable will not affect the other.
Instead use the value the function returns:
result = connection(num1, num2, result);
Of course, this means passing result as an argument is totally meaningless, and you don't even need it in the function:
int connection(int num1, int num2)
{
return num1 + num2;
}
Also note that I changed the return-type, as adding two integers will never result in a floating-point number.
On a side-note to modify the argument means you have to pass it by reference, which is not supported by C. It can be emulated though, by using pointers:
void connection(int num1, int num2, int *result)
{
*result = num1 + num2;
}
Then call it as
int result;
connection(num1, num2, &result);
You are mixing up two possibilities: returning a value and changing a variable by passing it to a method as a reference.
This is how to return a value (in this case, you don't need the result parameter):
float connection(int num1, int num2)
{
float result= num1 + num2;
return result;
}
...
result = connection(num1, num2);
This is how to pass a variable as a reference (in this case you don't need a return value):
void connection(int num1, int num2, float *result)
{
*result= num1 + num2;
}
...
connection(num1, num2, &result);
I think forgot to assign your result back to your variable:
connection(num1, num2, result); // returned value is missed
result = connection(num1, num2, result); // returned value saved
If, instead, you want your function to modify the variable, C is passed by value so you need some pointers:
void connection(int num1, int num2, float *result)
{
*result = num1 + num2;
}
connection(num1, num2, &result);
Simply make your function call pass by reference
#include<stdio.h>
float connection(int *num1, int *num2, float *result)
{
*result= *num1 + *num2;
return (*result);
}
int main()
{
int num1= 0;
int num2= 0;
float result= 0.0;
printf("\nChoose the first number you'd like to connect: ");
scanf("%d", &num1);
getchar();
printf("choose the second number you'd like to connect: ");
scanf("%d", &num2);
connection(&num1, &num2, &result); //Function Called by reference
printf("The result is: %f", result);
}
For further details on function calls Read It

How to carry a value through scanf to a function

I have a quick question in the program I'm trying to create. I can't seem to figure out how I can carry through the value that someone inputs for my variable of "denom" so that it can be successfully used in the function I've created. Help would be much appreciated.
#include <stdio.h>
//Global Variables
int num, denom;
void simplify(int *numerator, int *denominator);
int main () {
int num1, denom1;
//Prompt User as to what program is
printf("Fraction Simplifier\n");
printf("===================\n");
//Ask User for Numerator and Denominator
printf("Numerator: ");
scanf("%d", &num);
printf("Denominator: ");
scanf("%d", &denom);
//Call Function
simplify(&num1, &denom1);
//Display final output
printf("%d / %d = %d / %d\n", num, denom, num1, denom1);
return 0;
}
//Simplify function
void simplify(int *numerator, int *denominator)
{
int num1, denom1;
num1 = 1;
num = num1;
denom = denom1;
num1 = num1 / num1;
denom1 = denom1 / num1;
*numerator = num1 ;
*denominator = denom1;
}
Your simplify() method doesn't even try to use the passed values.
It boils down to *numerator = 1 and *denominator = is undefined (since denom1 is never initialized). i.e. it sets "out values" to "constants". You probably meant to do something like:
int num1 = *numerator;
int denom1 = *denominator;
In Simplify() function:
*int num1, denom1;
denom = denom1;* (1)
denom1 = denom1 / num1; (2)
*denominator = denom1;* (3)
in (1) denom1 has undefined values. So when you use:
(2)denom1 still has an undefined value
and in (3)
denominator has an undefined value

Resources