The following is the problem to which I am attempting a solution (in fact I have found the solution, there's a small doubt in a concept):-
Q4) Given a floating point number, write a program to convert it into its lowest irreducible
fractional form.
Note that the total number of digits before and after the decimal are less than 4, but greater than
0 (i.e there is at least one digit before the decimal and at least one digit after the decimal).
Sample Input:
3
2.4
2.5
3.2
Sample Output:
12/5
5/2
16/5 |
under the following constraints:-
General Instructions:
1) Every input starts with a number ‘n’, where ‘n’ are the total number of test cases that will be
followed, for eg. in Q1) n = 5, means that there are n test cases for this question, those are, 3,
60, 100, 1024, 23456.
2) Use of Arrays or any other advanced data structure isn’t allowed
3) Don’t use any pre-defined function in C library. |
My first attempt for the solution was this:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
include<stdio.h>
int main()
{
double p;
int n,i,j,denominator=1;
long int numerator;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%lf",&p);
numerator=p*10000;
denominator=10000;
for(j=5000;j>0;j--)
{
if(numerator%j==0 && denominator%j==0)
{
numerator/=j;
denominator/=j;
}
}
printf("%ld/%d\n",numerator,denominator);
}
return 0;
}
|
This one produced disastrous results as the code had absolutely no regards for data types.
When I put the input as "3.4", it produced the output of:- "33999/10000".
Though when I put the input as "2.5", it produced the correct output of:- "5/2".
Why this biased behaviour? I mean shouldn't the output have been "51999/10000".
Anyways, for my second attempt I tried this:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
#include<stdio.h>
int main()
{
double p,numerator;
int n,i,j,denominator=1;
long int numerator1;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%lf",&p);
numerator=p*10000;
printf("numerator=%lf\n",numerator); //for debugging purposes
numerator1= (long int) numerator;
printf("numerator1=%ld\n",numerator1);// for debugging purposes
denominator=10000;
for(j=5000;j>0;j--)
{
if(numerator1%j==0 && denominator%j==0)
{
numerator1/=j;
denominator/=j;
}
}
printf("%ld / %d",numerator1,denominator);
}
return 0;
}
|
Now outputs for this one was even weirder. I tried quite a lot of inputs, and the output seemed perfectly fine until I randomly tried "1.2972". IT produced the output:- " 12971/10000".
This program was correctly printing the outputs for larger numbers than 1.2972 like 8976.7642 whose output was:- "44883821 / 5000".
What's the problem with the conversion? Why is the program working for some numbers and not for the others?
Anyways, this is my final attempt which hasn't presented any incorrect outputs so far.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
#include<stdio.h>
int main()
{
long double p,numerator;
int n,i,j,denominator=1;
long int numerator1;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%Lf",&p);
numerator=p*10000;
numerator1= (long int) numerator;
denominator=10000;
for(j=5000;j>0;j--)
{
if(numerator1%j==0 && denominator%j==0)
{
numerator1/=j;
denominator/=j;
}
}
printf("%ld/%d\n",numerator1,denominator);
}
return 0;
}
|
The only change I made in this program was changing the data type of numerator from "double" to "long double". NOw, though I havent encountered any incorrect outputs doesnt necessarily mean that it wont produce incorrect output for any other input as well. And I guess the only way I can be sure of my program is if I can understand this weird behaviour by data types and their aversion to conversion.
If anyone could help me, I'd be really really really obliged.