|
||||||
| C and C++ C and C++ forum for discussing all forms of C except for C#. These languages are powerful low level languages used for creating Operating Systems, Device Drivers, compilers and much more. |
![]() |
|
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
|
|||
|
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, I also attached the program files in a zip package: 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_ */
|
| Sponsored Links |
|
|
|
|||||
|
I may be completely off the mark here, but in your declaration of dec_to_frac, you say:
Code:
void dec_to_frac(double decimal, double &numerator, double &denominator) Code:
numerator *= 10; Code:
void dec_to_frac(double decimal, double *numerator, double *denominator) ... *numerator *= 10; ...
__________________
My fun, friendly online games website: Cygnet Games My Squidoo page on Cygnet Games. |
|
|||||
|
Another, more subtle, issue that can cause you problems is this: When you enter a value, like 2.36, it is not necessarily stored in that format in memory. As a result, you may be working with a value like 2.359999999999999999999999. I would strongly urge you to work with the decimal value as a string, to avoid internal representation bugs like this one.
__________________
CodeCall Blog | CodeCall Wiki | Shareware | Linux Forum Programming is a branch of mathematics. |
|
|||
|
Thank you for your replies...
v0id: I am using this algorithm in a larger program in which a user types in an ordered pair of coordinates and the program will calculate linear functions and values based on the ordered pair, the slope: slope,distance, midpoint, y-intercept, x-intercept, two point slope equations, a slope-intercept equation and a standard form equation. In a slope-intercept equation (y=mx+b, m being the slope) the slope must be a whole number, not a fraction or floating point number. In a standard form equation (ax+by+c=0) the value for 'a' must be a whole number as well to be an academically correct textbook solution. Your method of changing the decimal to fraction is one solution but I am trying to use the algorithm of converting the decimal to a fraction, then reducing it to the least common multiple. Multiply the numerator by the denominator and then reduce again to the lowest common multiple. Some algebra textbooks present that method as well as the one you mentioned. I think that the fraction to lowest common multiple problem is very interesting and is a good study in robust code... WingedPanther: As mentioned above, I am using this algorithm in a larger program for a calculated double value, so for the case study I have to keep the user input as a numeric primitive type. I will put a loop limiter in the while loop instead of having being a while(1) loop to prevent the infinite loop from happening. The problem is that as you mentioned with the inaccurate binary representation, the two double values can't be compared. I should change the 'numerator' and 'denominator' value to integer values instead of double values or round the decimal places down to at least three places... Regards, Andrew Last edited by alpha_gamma; 06-04-2007 at 07:33 PM. |
| Sponsored Links |
|
|
![]() |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | Search this Thread |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Binary, Decimal, Hex, the Manual way!! | TcM | Tutorials | 22 | 01-10-2007 01:06 AM |
| WingedPanther | ........ | 2753.6 |
| Xav | ........ | 2704 |
| Brandon W | ........ | 1702.32 |
| John | ........ | 1207.73 |
| marwex89 | ........ | 1175.24 |
| morefood2001 | ........ | 966.05 |
| dcs | ........ | 655.75 |
| Steve.L | ........ | 475.59 |
| orjan | ........ | 418.58 |
| Aereshaa | ........ | 383.54 |