Convert Decimal number into Fraction - c

I am trying to convert decimal number into its fraction. Decimal numbers will be having a maximum 4 digits after the decimal place.
example:- 12.34 = 1234/100
12.3456 = 123456/10000
my code :-
#include <stdio.h>
int main(void) {
double a=12.34;
int c=10000;
double b=(a-floor(a))*c;
int d=(int)floor(a)*c+(int)b;
while(1) {
if(d%10==0) {
d=d/10;
c=c/10;
}
else break;
}
printf("%d/%d",d,c);
return 0;
}
but I am not getting correct output, Decimal numbers will be of double precision only.Please guide me what I should do.

If your floating point number is x, then the numerator of the fraction over 10000 will be the integral part of (x + 0.00005) * 10000. It's up to you whether you want to reduce the fraction to simplest terms (i.e. divide out by the gcd of the numerator and denominator).

#include <stdio.h>
int main(void) {
double a = 12.34;
int c = 10000;
double b = (a - floor(a)) * c;
int d = (int)floor(a) * c + (int)(b + .5f);
printf("%f %d\n", b, d);
while(1) {
if(d % 10 == 0) {
d = d / 10;
c = c / 10;
}
else break;
}
printf("%d/%d\n", d, c);
return 0;
}
The problem is that b was getting 3400.00 but when you do (int) b you are getting 3399, so you need to add 0.5 so the number can truncate to 3400.
Getting 3400.00 is different than having 3400, 3400.00 means that the number was round to 3400, that's why when you do (int) 3400.00 it assumes that the nearest integer (less than the number you are converting) is 3399, however, when you add 0.5 to that number the last the nearest integer is now 3400.
If you want to acquire a deeper understanding of floating point arithmetic read What Every Computer Scientist Should Know About Floating-Point Arithmetic

My solution is quite simple, "lazy", runs by iteration, nothing fancy.
In most languages that have a decent Math library, you'll need nothing more than the algo itself.
But in bc, you'll need to implement simple functions such as
int() to return integer part of a number ,
abs() to return absolute value ,
float() to return floating part of a number ,
round() to round to nearest integer.
If nothing is found after (1/eps) iterations, the loop breaks with the last result.
eps=10^-4 /*Tweak for more or less accuracy */
define int(x) {
auto s ;
s = scale ;
scale = 0 ;
x /= 1 ;
scale = s ;
return x ;
}
define round(x) { return int(x+.5-(x<0)) ; }
define abs(x) { if ( x < 0 ) x=-x ; return x ; }
define float(x) { return abs(x-int(x)) ; }
define void frac(x) {
auto f, j, n, z ;
f = float(x) ;
j = 1 / eps ;
z = .5 ;
if ( f != 0 ) {
while ( ( n++ < j ) && ( abs( z - round(z) ) > eps ) ) z = n / f ;
n -= 1 ;
if ( x < 0 ) n = -n ;
x = int(x)
z = round(z) ;
print n + x*z , "/" , z , " = "
if ( x != 0 ) print x , " + " , n , "/" , z , " = "
}
print x+n/z , "\n" ;
}
With standard accuracy (eps=.0001), you can get this :
frac(-.714285)
-5/7 = -.71428571428571428571
sqrt(2)
1.414213562373
frac(sqrt(2))
19601/13860 = 1 + 5741/13860 = 1.414213564213
6-7/pi
3.77183080
eps=.000001 ; frac(6-7/pi)
1314434/348487 = 3 + 268973/348487 = 3.77183080

Here is the algorithm that I use. It's an iterative process that works as follows:
The initial approximation for the numerator is 1 and the denominator is 1 divided by the fraction portion of the floating point value. For example, when converting 0.06 to a fraction, the denominator = 1/0.06 = 16.66666667 (rounded to 17), thus the initial approximation is 1/17.
The difference between the floating point value and the the current approximation is computed. For the example, the difference is 1/17 - 0.06 = 0.058824 - 0.06 = -0.001176.
If the absolute value of the difference is less than the defined tolerance (i.e. 0.000005), then the iteration is terminated.
Use the difference computed in step 2 to improve approximation of fraction. This is done by converting the difference into a fraction and adding (or subtracting) to the current approximation. In the example, a negative difference indicates a low approximation -- thus difference needs to be added to current approximation. The difference fraction is the numerator = 1 and denominator = 1/0.001176 = 850 -- difference in fraction from is 1/850. The new approximation will be (1/17) + (1/850) = (850*1 + 17*1)/(850*17) = 867/14450.
Repeat steps 2 to 4 until solution found.
After solution found, the fraction can be reduced. For example, 867/14450 is exactly 0.06 and the iteration process is terminated. 867/14450 can be reduced to 3/50.
Some features of this method are:
If the resulting fraction is 1/anything, the first approximation will be exact. For example, converting 0.25 to fraction, the first approximation will be 1/4. Thus further iterations are not needed.
In majority (> 80%) of 1,000,000 test cases, convergence occurs in 2 iteration or less.
For all test cases, the maximum number of iterations was 3.
I posted the code for this algorithm on github -- https://github.com/tnbezue/fraction

this is an interesting question.
I think you might be better off starting with reading about the multiples ways of calculating the "greatest common divisor" ( http://en.wikipedia.org/wiki/Greatest_common_divisor is a good source ).
Implement a quick&dirty algorithm that makes those calculations as you would do with a pen and paper then look into how doubles are represented (sign, exponent, mantissa) and improve your algorithm to take advantage of this representation.
sadly, there's not much more I can do without writing your piece of code.

An algorithm created with c++ that does decimal to fraction.
#include <iostream>
using namespace std;
// converts the string half of the inputed decimal number into numerical values
void converting (string decimalNumber, float& numerator, float& denominator )
{
float number;
string valueAfterPoint = decimalNumber.substr(decimalNumber.find(".") + 1,((decimalNumber.length() -1) )); // store the value after the decimal into a valueAfterPoint
cout << valueAfterPoint<< " "<< endl;
int length = valueAfterPoint.length(); //stores the length of the value after the decimal point into length
numerator = atof(valueAfterPoint.c_str()); // converts the string type decimal number into a float value and stores it into the numerator
// loop increases the decimal value of the numerator and the value of denominator by multiples of ten as long as the length is above zero of the decimal
cout << length<< endl;
for (; length > 0; length--)
{
numerator *= 10;
}
do
denominator *=10;
while (denominator < numerator);
}
// simplifies the the converted values of the numerator and denominator into simpler values for an easier to read output
void simplifying (float& numerator, float& denominator)
{
int maximumNumber = 9; //Numbers in the tenths place can only range from zero to nine so the maximum number for a position in a poisitino for the decimal number will be nine
bool isDivisble; // is used as a checker to verify whether the value of the numerator has the found the dividing number that will a value of zero
// Will check to see if the numerator divided denominator is will equal to zero
if(int(numerator) % int(denominator) == 0)
{
numerator /= denominator;
denominator = 1;
return;
}
//check to see if the maximum number is greater than the denominator to simplify to lowest form
while (maximumNumber < denominator)
{
maximumNumber *=10;
}
// the maximum number loops from nine to zero. This conditions stops if the function isDivisible is true
for(; maximumNumber > 0; maximumNumber --)
{
isDivisble = ((int(numerator) % maximumNumber == 0) && int(denominator)% maximumNumber == 0);
cout << numerator << denominator <<" " <<endl;
if(isDivisble)
{
numerator /= maximumNumber; // when is divisible true numerator be devided by the max number value for example 25/5 = numerator = 5
denominator /= maximumNumber; //// when is divisible true denominator be devided by the max number value for example 100/5 = denominator = 20
}
// stop value if numerator and denominator is lower than 17 than it is at the lowest value
int stop = numerator + denominator;
if (stop < 17)
{
return;
}
}
}
int main()
{
string decimalNumber;
float numerator = 0;
float denominator = 1;
cout << "Enter the decimal number";
cin >> decimalNumber;
//convert function
converting(decimalNumber, numerator, denominator);
//call simplyfication funcition
simplifying(numerator, denominator);
cout<< "Fraction: "<< numerator << "/" << denominator<< endl;
return 0;
}

Related

Power of nth number (table) in C

I'm making program that prints their nth power for numbers from 1 to 20, using recursive and non-recursive function. I would like to give an option for user to enter real numbers. How to do that? Can it be done without pow function? Thank you for your help!
If you want to raise a number to a real exponent x
a^x
you can compute it as
e^(x ln a)
so you can write a function like
double mypow( double base, double exponent )
{
return exp( exponent * log( base ) )
}
If you want to get deep into the weeds and create your own implementations of exp and log, you can use the Taylor series
e^x = 1 + x + ((x^2)/2!) + ((x^3)/3!) ...
and
ln x = 2( u + (u^3)/3 + (u^5)/5 ... ), u = (x+1)/(x-1)
Personally, I would just use the pow function.
In making double keiski_pow(double num, double exponent) consider different code for certain conditions.
// exponent == 0, num != 0
return 1
// exponent == 0, num == 0
Domain error
// num > 0
return exp(log(num)*exponent)
// or more accurately
return exp2(log2(num)*exponent)
// num == 0, exponent < 0
Infinity
// num < 0, exponent is an integer > 0.
// Integer test for `double`: trunc(exponent) == exponent
t = keiski_pow(num, exponent/2)
return t*t*(exponent%2 ? num : 1)
// or
t = keiski_pow(fabs(num), exponent)
return t*exponent%2 ? -1 : 1)
// num < 0, exponent is an integer < 0
return 1.0/keiski_pow(num, -exponent)
// num < 0, exponent is not an integer
Domain error
I think this covers most cases. (NaN are another story)
Note: recursion() is very very slow for large exponent. Try recursion(1.0, 1e15).
A much faster recursive solution:
double recursion_alt(double num, double exponent) {
// Code only valid when exponent has a whole number value
assert(exponent = trunc(exponent));
if (exponent > 0.0) {
double exponent_mod2 = fmod(exponent, 2.0);
double exponent_div2 = (exponent - exponent_mod2)/2.0;
double t = recursion_alt(num, exponent_div2);
return t*t*(exponent_mod2 ? num : 1.0);
}
if (exponent < 0.0) {
return 1.0/recursion_alt(num, -exponent);
}
return 1.0;
}

Error when concatenate square of a each digit of a number

I'm doing a Codewars Challenge. I must square every digit of a number and concatenate them.
So, if we run 9119 through the function, 811181 will come out, because 92 is 81 and 12 is 1.
My code is below:
#include <math.h>
unsigned long long square_digits (unsigned n)
{
// Count for digits
int digits = log10(n) + 1, i = 0;
// Array to store the split number
int numDivided[digits];
// Store concatenated numbers
unsigned long long result = 0;
if (n == 0)
{
return result;
}
// Split number and store their square
while (n > 0)
{
numDivided[i] = pow(n % 10, 2);
n /= 10;
i++;
}
// Concatenated square of numbers
for (i = digits - 1;i >= 0;i--)
{
if (numDivided[i] == 0)
{
result *= 10;
}
else
{
// Count digits of the current number
digits = log10(numDivided[i]) + 1;
// Multiply current result for 10^(digits)
result *= pow(10, digits);
// Add the current number to result
result += numDivided[i];
}
}
return result;
}
The test cases are below:
Test(test_suite, sample_tests)
{
do_test( 3212u, 9414ull);
do_test( 2112u, 4114ull);
do_test( 0u, 0ull);
do_test( 999u, 818181ull);
do_test( 10001u, 10001ull);
do_test(3210987654u, 9410816449362516ull);
do_test(3999999999u, 9818181818181818181ull); // :p
do_test( UINT_MAX, 164811681364948125ull);
}
The code works until the two last tests, so:
for n = 3999999999, expected 9818181818181818181, but got 9818181818181818449
I was think that the test case was wrong and check if the number was greater that ULLONG_MAX but it's less, so, all right.
What is my mistake at this point?
What problems could i have with pow function? There is any alternative?
pow() typically returns, at best, a 53 significant bit result yet we have at least a 64-bit problem. powl() does not certianly help either as it may be as limiting as pow(). Do not use floating point functions for an integer problem. Using a floating point funtion for an integer problem is the wrong approach.
digits = log10(n) + 1 are numDivided[i] = pow(n % 10, 2) are not specified to get the desired value (due to imprecision) and certainly fail when n == 0.
Simple extract the least significant decimal digit with %10. Scale by an integer type power-of-10.
unsigned long long square_digits(unsigned n) {
unsigned long long nn = 0;
unsigned long long pow10 = 1;
while (n) {
unsigned digit = n % 10;
unsigned square = digit * digit; // 0 to 81
nn += square * pow10;
if (square < 10) {
pow10 *= 10;
} else {
pow10 *= 100;
}
n /= 10;
}
return nn;
}
The main culprit is this line:
result *= pow(10, digits);
Given that result is an unsigned long long while the return value of pow is a double, result is first converted to a double, then multiplied by the power and finally the result is converted back to an unsigned long long.
The problem is that while a double type has a much greater range than an unsigned long long, its precision is limited and not all the possible integral values can be represented (stored) exactly.
In particular, you can check the result of the following line:
printf("%.0lf\n", 981818181818181ull * 100.0); // It won't print 98181818181818100
See #chux's answer for further details and a proper implementation of the solution.
I found two mistakes in your code.
log() is not defined for 0. So, you cannot run your code against Test case 3.
Use powl() instead of pow().
PS: One change you can do to pass test case 3 is check if N == 0 in the beginning of the function itself. The next script should calculate the number of digits in N.

C: Round signed integer to nearest multiple

This feels like a basic question but I couldn't find a definitive answer so far.
I would like to implement an efficient function round_to_nearest(int x, int multiple), that rounds a signed integer x to the nearest multiple of multiple, avoiding using floating point arithmetic if possible.
Example output:
round_to_nearest(14, 5);
15
round_to_nearest(16, 5);
15
round_to_nearest(23, 5);
25
round_to_nearest(22, 5);
20
round_to_nearest(-23, 5);
-25
round_to_nearest(-22, 5);
-20
In integer arithmetic, if n is positive, add m/2, else subtract m/2, then divide by m (truncating integer divide), then multiply by m:
int round_to_nearest( int n, int m )
{
return (( n + ((n < 0) ? -m : m) / 2) / m ) * m ;
}
int main()
{
int test[] = {16, 23, 22, -23, -22} ;
int m = 5 ;
for( int i = 0; i < sizeof(test) / sizeof(*test); i++ )
{
printf(" round_to_nearest( %d, %d ) = %d\n", test[i], m,
round_to_nearest( test[i], m ) ) ;
}
return 0;
}
Output of test:
round_to_nearest( 16, 5 ) = 15
round_to_nearest( 23, 5 ) = 25
round_to_nearest( 22, 5 ) = 20
round_to_nearest( -23, 5 ) = -25
round_to_nearest( -22, 5 ) = -20
One caveat is that m must be > 0 - which in this context makes sense, I would accept that as a precondition for correct operation; checking for it as a runtime error is probably unnecessary, but you might include an assert to protect against programmer semantic error:
assert( m > 0 ) ;
Standard library asserts are removed when NDEBUG is defined - normally when debug support is disabled.
For positive numbers:
add half of the multiple to x
then perform integer division, which drops the fractional part
then multiply by the multiple to get the final answer
For negative numbers, the first step is a subtraction, instead of addition.
int round_to_nearest(int x, int multiple)
{
if (x >= 0)
return ((x + multiple / 2) / multiple) * multiple;
else
return ((x - multiple / 2) / multiple) * multiple;
}
In order to round to the next multiple in the direction of zero (i.e. down for positive numbers and up for negative numbers), all you have to do is to divide by that multiple and then multiply the result with the multiple. The rounding towards zero will be accomplished by the truncation in the division.
int round_toward_zero( int num, int multiple )
{
int quotient;
quotient = num / multiple;
return quotient * multiple;
}
However, since you stated that you wanted to round to the nearest multiple instead of the next multiple in the direction of zero, we must do the same thing, but we must add a small correction in cases in which we want to round in the other direction:
For positive numbers, if the remainder of the division is at least half of the multiple, then we must add 1 to the quotient before multiplying with the multiple, so that it is rounded away from zero.
For negative numbers, if the remainder of the devision is not more than half of the multiple we must add -1 to the quotient before multiplying with the multiple, so that it is rounded away from zero.
Therefore, in the following code, the variable correction can have the value -1, 0 or +1. For positive numbers, it will be either 0 or +1, and for negative numbers, it will be either -1 or 0.
#include <stdio.h>
int round_to_nearest( int num, int multiple )
{
int quotient, remainder, correction;
quotient = num / multiple;
remainder = num % multiple;
correction = remainder / ( (multiple + 1 ) / 2 );
return (quotient + correction) * multiple;
}
int main( void )
{
printf( "%d\n", round_to_nearest(14, 5) );
printf( "%d\n", round_to_nearest(16, 5) );
printf( "%d\n", round_to_nearest(23, 5) );
printf( "%d\n", round_to_nearest(22, 5) );
printf( "%d\n", round_to_nearest(-23, 5) );
printf( "%d\n", round_to_nearest(-22, 5) );
}
Output:
15
15
25
20
-25
-20
Integer division truncates towards zero; which is 0.5 smaller (in magnitude, on average) than a rounded to nearest result.
If you add the magnitude of 0.5 * divisor to the magnitude of the numerator, then the result will be 0.5 larger.
In other words, for unsigned integers:
result = (numerator + divisor/2) / divisor;
..or alternatively (with less rounding error when the divisor is odd, and higher risk of overflow - e.g. if numerator is INT_MAX):
result = (numerator*2 + divisor) / (divisor * 2);
For signed integers "magnitude" isn't "value"; and it becomes a mess when the numerator and divisor have a different sign. To fix that:
if( (numerator < 0) && (divisor < 0) ||
(numerator >= 0) && (divisor |= 0) ) {
/* Numerator and divisor have same sign */
result = (numerator*2 + divisor) / (divisor * 2);
} else {
/* Numerator and divisor have different sign */
result = (numerator*2 - divisor) / (divisor * 2);
}
To round to the nearest multiple, you just multiply by the divisor after the "round to nearest". The code becomes:
if( (numerator < 0) && (multiple < 0) ||
(numerator >= 0) && (multiple |= 0) ) {
/* Numerator and multiple have same sign */
result = (numerator*2 + multiple) / (multiple * 2);
} else {
/* Numerator and multiple have different sign */
result = (numerator*2 - multiple) / (multiple * 2);
}
result *= multiple;

Comparing fractions with struct

The function is supposed to compare two fractions that are stored in two structs.
If fraction L = fraction R return 0
If L > R return 1
If R > L return -1
Here is the code I have now:
int compare_fractions(Fraction L, Fraction R)
{
double z = (L.numer/L.denom) - (R.numer/R.denom);
// THIS CODE IS INCORRECT - FIX IT!
if(z == 0)
return 0;
else if(z < 0)
return -1;
else if(z
return 1;
}
However when I run the following tests I receive 0's with the following comparisons:
(1,3) ? (2,3)
(5,6) ? (3,4)
(2,4) ? (1,4)
where (1,3) is fraction L and (2,3) is fraction R
If the numerator and denominator are ints (or another integer type) then the division is integer division, you'll never get the correct fractional part
Casting it to double can correct most of the problem but you'll face the slow divisions and sometimes errors due to floating-point roundings.
You should use multiplication instead. It'll be much faster and you don't need a floating-point division which is very slow on some architectures. This way you don't need to worry about floating-point comparisons either
int compare_fractions(Fraction L, Fraction R)
{
int z = L.numer*R.denom - L.denom*R.numer;
if (z == 0)
return 0;
else if (z > 0)
return 1;
else
return -1;
}
Of course you need to make sure that all the denominators are positive, otherwise you need to normalize it (you can use chux's suggestion below). You also need to account for overflow if you values can be large by doing the math in a wider type like
long long z = (long long)L.numer*R.denom - L.denom*R.numer
If you can lax the requirements a bit to return negative, 0 or positive values for less than, equal or more than case just like strcmp() then you can remove the checks for z's value altogether and return L.numer*R.denom - L.denom*R.numer directly instead
If you still need to return -1, 0 and 1 then there are several ways to shorten/optimize it like
return (z > 0) - (z < 0);
return (z == 0) ? 0 : (z < 0 ? -1 : 1);
return (z >> 31) | (!!z);
Is there a standard sign function (signum, sgn) in C/C++?
Fast sign of integer in C
Branchless code that maps zero, negative, and positive to 0, 1, 2
When you divide an int by another int, it will first divide them and (because the result must be an int as well) rounds the result towards zero. First at this point is it cast into a double:
int a = 7;
int b = 3;
double c = a / b; // = 2, because 2.333... rounded down is 2, which is
// then cast to a double
The solution is to cast either the numerator or the denominator to a double before dividing:
int a = 7;
int b = 3;
double c = (double)a / b; // = 2.333... because it's cast to a double before
// dividing
//double c = a / (double)b; // this will also work
More specifically, if you change one line in your code to this, it should work:
double z = ((double)L.numer/L.denom) - ((double)R.numer/R.denom);

Correct algorithm to convert binary floating point "1101.11" into decimal (13.75)?

I have written a program in C to convert a floating point number represented in binary (1101.11) into a decimal (13.75).
However, I cannot seem to get the correct value out of the algorithm.
What is the correct method for converting a binary floating point number into a decimal?
I am using Dev CPP compiler (32 bit). The algorithm is defined below:
void b2d(double p, double q )
{
double rem, dec=0, main, f, i, t=0;
/* integer part operation */
while ( p >= 1 )
{
rem = (int)fmod(p, 10);
p = (int)(p / 10);
dec = dec + rem * pow(2, t);
t++;
}
/* fractional part operation */
t = 1; //assigning '1' to use 't' in new operation
while( q > 0 )
{
main = q * 10;
q = modf(main, &i); //extration of frational part(q) and integer part(i)
dec = dec+i*pow(2, -t);
t++;
}
printf("\nthe decimal value=%lf\n",dec); //prints the final output
}
int main()
{
double bin, a, f;
printf("Enter binary number to convert:\n");
scanf("%lf",&bin);
/* separation of integer part and decimal part */
a = (int)bin;
f = bin - a;
b2d(a, f); // function calling for conversion
getch();
return 0;
}
You are not, as you believe, reading "1101.11" as a floating point number represented in binary. You are reading it as a base-10 floating point number converted into an IEEE double-precision floating-point value, and then trying to change the base.
The inherent imprecision of this intermediate step is the reason for your problem.
A better approach, as suggested by Vicky, is to:
read "1101.11" as a string or line of text
convert the whole and fractional parts (whole=b1101=13 and numerator=b11=3, denominator=4)
re-combine these into whole + numerator/denominator = 13.75
Solution
The following will work as expected:
Output:
➤ gcc bin2dec.c -lm -o bin2dec && bin2dec
1101.11 -> 13.750000
1101 -> 13.000000
1101. -> 13.000000
.11 -> 0.750000
Code (bin2dec.c):
#include <stdio.h>
#include <math.h>
double convert(const char binary[]){
int bi,i;
int len = 0;
int dot = -1;
double result = 0;
for(bi = 0; binary[bi] != '\0'; bi++){
if(binary[bi] == '.'){
dot = bi;
}
len++;
}
if(dot == -1)
dot=len;
for(i = dot; i >= 0 ; i--){
if (binary[i] == '1'){
result += (double) pow(2,(dot-i-1));
}
}
for(i=dot; binary[i] != '\0'; i++){
if (binary[i] == '1'){
result += 1.0/(double) pow(2.0,(double)(i-dot));
}
}
return result;
}
int main()
{
char bin[] = "1101.11";
char bin1[] = "1101";
char bin2[] = "1101.";
char bin3[] = ".11";
printf("%s -> %f\n",bin, convert(bin));
printf("%s -> %f\n",bin1, convert(bin1));
printf("%s -> %f\n",bin2, convert(bin2));
printf("%s -> %f\n",bin3, convert(bin3));
return 0;
}
Explanation
The above code works by first finding the index of the decimal point in the number.
Once that is known, it walks the string both backwards and forwards from this index, adding the appropriate value to the result variable.
The first loop walks backwards from the decimal point and accumulates the powers of 2 if the character is 1. It takes the distance from the decimal point as the power of two, minus one for the indexing to be correct. Ie, it accumulates :
pow(2,<distance-from-decimal-point>)
The loop stops when the index reaches the beginning of the string.
The second loop walks forward until the end of the string, and deals with the fractional part as expected it also uses the distance from the index, but this time accumulates fractional parts:
1/pow(2,<distance-from-decimal-point>)
Worked out example:
1101.11 = 1101 + 0.11
1101 = 1*2^3 + 1*2^2 + 0*2^1 + 1*2^0 = 8 + 4 + 0 + 1 = 13
0.11 = 1/(2^1) + 1/(2^2) = 0.5 + 0.25 = 0.75
1101.11 = 13.75
Beware of malformed input. "10gsh.9701072.67812" will give you a result. It won't mean much :)
This piece of code behaves abnormally: I added some simple print statement
while(q>0)
{
double i;
main=q*10.0;
q=modf(main, &i); //extration of frational part(q) and integer part(i)
cout << "main = " << main << " frac part " << q << " int part " << i << endl;
cin.get();
dec=dec+i*pow(2,-t);
t++;
}
When you input 1101.11, the following output shown:
Enter binary number to convert(e.g: 1101.11 which will be 13.75 in decimal):
1101.11
bin in main 1101.11
p 1101 q 0.11
//inside the above while loop code
main = 1.1 frac part 0.1 int part 1
main = 1 frac part 1 int part 0 //^^^^^Error, given main=1, it should output integer part 1, fraction part 0
main = 10 frac part 1 int part 9 //^^^^^same strange error here, it should exit while already
So you got wrong result. I tested modf separately with input 1, it gave correct result.
So my guess is that you are reading the binary number as double, then tries to convert this double to binary back. There might be something going on under the hood for the precision of number though it shows that it is 1101.11. As suggested by #Useless, You may need to read the number as a string, figure out the substring before and after the decimal point . Then convert this two part into decimal separately.

Resources