Computing.Net > Forums > Programming > C++, issues converting decimal to f

C++, issues converting decimal to f

Reply to Message Icon

Original Message
Name: alpha_gamma
Date: June 2, 2007 at 08:32:33 Pacific
Subject: C++, issues converting decimal to f
OS: Ubuntu Fiesty Fawn
CPU/Ram: 1.7Ghz, 768 Mb RAM
Model/Manufacturer: Self Made
Comment:

Hi all,

I am working on a C++ program that converts a decimal to a fraction, finds the lowest common multiple, multiplies the numerator by the denominator, then reduces the fraction again so the fraction will be 'numerator/1'.

I am using this code in a larger program to change a floating point slope value to a whole value for slope-intercept equations and standard form equations.

The program will run but I tested almost 500 numbers and 20 numbers made the program crash (it stalled and did not finish the equation, I had to close the terminal and open it up again... )

These 20 numbers I had problems with:

2.36, 7.36, 1.11, 1.001, 1.66, 1.88, 2.22, 2.13, 3.24, 3,26, 3.32, 3.43, 3.49, 3.51, 3.57, 3.68, 3.74, 3.76, 3.82

(I am sure there are more...)

I have tried c-style casting and dynamic and static casting to try to resolve this issue. Can someone help me out and point out why these certain numbers make the program crash and offer a possible sloution?

I tried debugging this program on gdb and keep on getting this frustrating message..

(gdb) break 16
No line 16 in file "init.c".
(gdb)


Here is the program's code:

[code]

//example.cc
#include <iostream>
#include "reduce.h"
#include "decimal-to-fraction.h"
using namespace std;

int main()
{
double deci;
double n, d;

while(1) {
cout << "Enter a decimal to convert to a fraction ('0' to quit): ";
cin >> deci;
cin.ignore(INT_MAX, '\n');
if(!deci) exit(0);

dec_to_frac(deci, n, d);

if (n * d != n){
cout << '\n' << deci << " = " << n << '/' << d << "\n\n";
cout<<'\n' << d << " x " << n;
n = d * n;
cout<< " = " << n << "\n\n";
cout<<'\n' << n << '/' << d;
reduce(n, d);

cout << " = " << n << '/' << d << "\n\n";

cout<<'\n' << n << "\n\n";
}

else
cout<<'\n' << deci<< "\n\n";

}

return 0;
}

#ifndef _REDUCE_H_

#error You must include "reduce.h" before this file

#endif /* def _REDUCE_H_ */

#ifndef _DECIMAL_TO_FRACTION_H_

#define _DECIMAL_TO_FRACTION_H_

void dec_to_frac(double decimal, double &numerator, double &denominator)

{

//numerator = static_cast<int >(decimal);
//numerator = (int )decimal;
numerator = decimal;

denominator = 1;


while(numerator != (int)numerator) {

numerator *= 10;

denominator *= 10;

}

reduce(numerator, denominator);

}

#endif /* def _DECIMAL_TO_FRACTION_H_ */

#ifndef _REDUCE_H_

#define _REDUCE_H_

void reduce(double &numer, double &denom)

{

int i;

for(i=2; i<=numer; ++i) {

if( ((numer/i) == ((int )(numer/i))) && ((denom/i) == ((int)(denom/i))) ) {

numer /= i;

denom /= i;

--i;

}

}

}

#endif /* def _REDUCE_H_ */
[/code]


Report Offensive Message For Removal


Response Number 1
Name: Guy
Date: June 2, 2007 at 15:08:59 Pacific
Subject: C++, issues converting decimal to f
Reply: (edit)

It builds fine (Ubuntu 6.10, gcc 4.1.2).

It runs for various numbers I pick: 1.23, 3.14, ...... (I don't know if the output is correct, I just know it continues to run).

But I confirm you have a problem.

For most numbers you list (I have not tried all), it hangs on my box (Ctrl-C gets me out).

I confirm there are other problem numbers: 7.89, ?????. I'm sure I can find others.

I will look at this some more.

Right now, I don't know what the problem is.

Guy



Report Offensive Follow Up For Removal

Response Number 2
Name: Guy
Date: June 2, 2007 at 15:22:37 Pacific
Subject: C++, issues converting decimal to f
Reply: (edit)

One comment, which has absolutely nothing to do with the problem: your call to 'ignore' should really be this:

cin.ignore(numeric_limits<int>::max(),'\n');


Report Offensive Follow Up For Removal

Response Number 3
Name: Razor2.3
Date: June 2, 2007 at 16:38:28 Pacific
Subject: C++, issues converting decimal to f
Reply: (edit)

Your problem is base 2; those numbers infinitely repeat at that base. I.E. 2.36 becomes 2.359999999...


Report Offensive Follow Up For Removal

Response Number 4
Name: Guy
Date: June 3, 2007 at 13:29:58 Pacific
Subject: C++, issues converting decimal to f
Reply: (edit)

Sidetracked. Definitely a problem with those numbers which cannot be represented precisely as a 'double'.

Consider a different approach to (implementation of) 'dec_to_frac'.

What are the implications of declaring numerator and denominator as double? Shouldn't these really always be int/long?



Report Offensive Follow Up For Removal

Response Number 5
Name: Razor2.3
Date: June 3, 2007 at 18:15:12 Pacific
Subject: C++, issues converting decimal to f
Reply: (edit)

I've seen this handled two ways. First is COBOL's method of every digit having its own byte. It keeps things in base 10, but it's a real pain to do in C++.

The second method is to keep the number as a whole number, either by sticking it in its own variable, or by ignoring the decimal until you're doing output (essentially multiplying the number by powers of 10 until it becomes whole).

The second method is what I would choose, as that would drastically reduce the work you have to do. Take the fractional part of the number, shove it into its own long, count the number of digits after the decimal, then your numerator is just pow(10, <# of digits>).

Guy: He declares them as double so he can see if the result of the division is a whole number. Personally, I'd just check the modulus and end up with a function that looks like:


void reduce(long &numer, long &denom) {
....long i = numer;

....while (i > 1)
........if (numer % i | denom % i) i--;
........else {denom /= i; i = numer /= i;}
}

But to each his own.

Edit: Fixed the code. I really should double-check this stuff before posting.


Report Offensive Follow Up For Removal







Use following form to reply to current message:

   Name: From My Computing.Net Settings
 E-Mail: From My Computing.Net Settings

Subject: C++, issues converting decimal to f

Comments:

 


  Homepage URL (*): 
Homepage Title (*): 
         Image URL: 
 
Data Recovery Software




How often do you use Computing.Net?

Every Day
Once a Week
Once a Month
This Is My First Time!


View Results

Poll Finishes In 3 Days.
Discuss in The Lounge