Program crashes if I do not put endl before returning string value

Can someone please explain to me or help me understand why my function is not working correctly please basically it works 90% perfect if I add a std::cout << std::endl; before I return my string value. (if I do not put that or I put a flush, or I put a new line and flush it will crash).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const std::string fraction(const long double a)
    { 
        long double denominator = a*1000000, numerator = 1000000, factor = gcf(denominator,numerator);
        denominator /= factor;
        numerator /= factor;
/*what it basically does it multiples the decimal number by 1million and sets
 that as the denominator and then sets the numerator to 1million then it will 
get the greatest common factor of the denominator and numerator then after that 
it divides both the denominator and numerator by the gcf.*/
        std::cout  << std::endl;
        return(intToString(characteristic(denominator))+"/"+intToString(characteristic(numerator)));
/*after I get the denominator and numerator I am returning a string that is the denominator/numerator
ex: "1/3" if the denominator is 1 and numerator is 3*/
    }


Oh and I said it works 90% because I was being lazy which I know I should not have been when I am programming and I just multiplied and then divied by gcf instead of doing a continued fraction (which frankly I think would take quiet a while but would be effective http://en.wikipedia.org/wiki/Continued_fraction
basically I think i have to do that method anyways because my method doesnt take into consideration 2.5/1 is really 5/2 and not 2/1

Thanks for any help/suggestions/tips
-giblit
Please show how you are calling the function and/or the functions you are calling. cout'ing an endl should not cause or prevent a crash. You may have some memory corruption going on.
What do you think would happen if gcf() returned zero?
yeah I just realized that kooth right after I posted it lol thanks though I am goign to fix that and I am calling the function like this zhuge
thanks for the response both of you appreciate it
1
2
3
4
5
6
int main()
{
double db = (double)1/3;
math m; //the function is in a class
std::cout << m.fraction(db) << std::endl;
}
Last edited on
@giblit:
What kooth said is exactly the problem.
If you devide an integer by zero, an exception is raised.
Otherwise if it's not an integer, the float value becomes NaN and you cannot successfully represent it in a numerical form.

Probably the cause of your crash.
It still crashes after fixing that. The only way it will not crash if if I put std::cout << std::endl;
on my fraction code before the return
if I remove it the program just crashes
here is all the functions that are being used for the fraction
This is in my header file header.h

EDIT::Forgot 3 functions I just now added to top of the header file
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class math {
const int characteristic(const double a)
    {
        std::string number = intToString(a), leftNumber;
        int leftOfDecimal;
        for(unsigned int i = 0; i<number.size(); i++) if(number[i] == '.') leftOfDecimal = i;
        for(unsigned int i = 0; i < leftOfDecimal; i++) leftNumber.push_back(number[i]);
        return(atoi(leftNumber.c_str()));
    }
    const double mantissa(const double a)
    { 
        std::string number = intToString(a), leftNumber;
        int leftOfDecimal;
        for(unsigned int i = 0; i<number.size(); i++) if(number[i] == '.') leftOfDecimal = i;
        for(unsigned int i = leftOfDecimal; i < number.size(); i++) leftNumber.push_back(number[i]);
        return(atof(leftNumber.c_str()));
    }
    const std::string intToString(double a)
    {
        std::stringstream ss;
        std::string str;
        ss << a;
        ss >> str;
        return(str);
    }
 const unsigned int gcf(const double a, const double b)
    {
        unsigned int gcf, smallest = smallestNumber(a, b), largest = largestNumber(a, b);
        for(unsigned int i = 1; i<smallest+1; i++) if(smallest % i == 0 && largest % i == 0) gcf = i;
        return(gcf);
    }
    const unsigned int smallestNumber(const long double a, const long double b)
    {
        unsigned int smallest;
        if(a > b) smallest = b;
        else smallest = a; 
        return(smallest);
    }
    const unsigned int largestNumber(const long double a, const long double b)
    { 
        unsigned int largest; 
        if(a > b) largest = a; 
        else largest = b; 
        return(largest); 
    }
    const std::string fraction(const long double a)
    {
        long double denominator = a*10000000, numerator = 10000000, factor = gcf(denominator,numerator);
        denominator /= factor;
        numerator /= factor;
        //if  i put a std::cout << std::endl; here it works but then i have an extra line
        return(intToString(characteristic(denominator))+"/"+intToString(characteristic(numerator)));
    }
}


this is my main cpp file

1
2
3
4
5
6
7
8
9
#include "header.h"
#include <iostream>
int main()
{
     math m;
     double db = (double)1/3;
     std::cout << m.fraction(db) << std::endl;
     return(0);
}
Last edited on
You really should put code in to test what gcf() returns.

What is the exact error message from the crash? Is there a core file? If so, can you run mdb or gdb against it?
All the errors I found myself, with just TWO MINUTES of testing:

1. main->fraction->characteristic:
leftOfDecimal is undefined.
It is not being set.

I assumed you wanted 0, and I kept running.

Result: 3/0.

You have too many undefined variables being used here and there, and little bottlenecks.

Consider updating the tutorials/guides you are using.
Im not using a tutorial there is nothing on decimal to fraction and I.updated the code so its better and theblem is.not an errorit is the program crashes without an endl before the return thanks for responses though. And characteristic is the numbers before decimal I'm trying to use continued fractions to get a fraction now I have the a[I]s now I just need to write a formula that can convert them to LCD then string
@essgeich what undefined variables do I have?
Last edited on
There are so many things wrong with your code it's difficult to know where to start.

I would begin by getting rid of the math class and working on your individual functions until they actually work before trying to put together a bunch of erroneous functions and scratching your head at the resultant mess.
@giblit:
Almost everyone.

int leftOfDecimal; ---> undefined value
int leftOfDecimal = 0; ---> value = 0
they seem to work though I was testing them one at a time its just the decimal to fraction I updated a couple of the functions though
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
 const long double factorial(double a)
    {
        if(a > 1) return(a * factorial(a - 1));
        else return(1);
    }
    const double sq(const double a)
    {
        return(a*a);
    }
    const double cb(const double a)
    {
        return(a*a*a);
    }
    const double power(double a, int b)
    {
        bool return2 = false;
        double value = a;
        if(b < 0)
        {
            b = absolute(b);
            return2 = true;
        }
        for(unsigned int i = 1; i<b; i++) a *= value;
        if(return2)
            a = inverse(a);
        if(b != 0)
            return(a);
        if(b == 0)
            return(1);
    }
    const double power(double a, double b)
    {
        //fraction(a);
        bool return2 = false;
        double value = a;
        if(b < 0)
        {
            b = absolute(b);
            return2 = true;
        }
        for(unsigned int i = 1; i<b; i++)
            a *= value;
        if(return2)
            a = inverse(a);
        return(a);
    }
    const double sqrt(const double a)
    {
        double i = 0;
        while(a - .01 > sq(i)) i += .001;
        return(i);
    }
    const double cbrt(const double a)
    {
        double i = 0;
        while(a - .01 > cb(i)) i += .001;
        return(i);
    }
    const double root(const double a, const double b)
    {
        double i = 0;
        while(a - .01 > power(i,b)) i += .001;
        return(i);
    }
    const double e()
    {
        double e = 1, num = 1;
        for(unsigned int i = 1; i<11; i++)
        {
            num *= i;
            e += 1/(num);
        }
        return(e);
    }
    const double pi()
    {
        return((double)22/7);
    }
    const double absolute(double a)
    {
        if(a < 0) a *= -1;
        return(a);
    }
    const double inverse(double a)
    {
        return(1/a);
    }
    const signed int characteristic(const double a)
    {
        std::string number = intToString(a), leftNumber;
        unsigned int decimalAt = 0, leftOfDecimal;
        for(unsigned int i = 0; i<number.size(); i++) if(number[i] == '.') decimalAt = i;
        if(decimalAt == 0) number.append(".0");
        for(unsigned int i = 0; i<number.size(); i++) if(number[i] == '.') leftOfDecimal = i+1;
        for(unsigned int i = 0; i < leftOfDecimal; i++) leftNumber.push_back(number[i]);
        return(atoi(leftNumber.c_str()));
    }
    const unsigned int mantissa(const double a)
    {
        std::string number = intToString(a), leftNumber;
        int leftOfDecimal;
        for(unsigned int i = 0; i<number.size(); i++) if(number[i] == '.') leftOfDecimal = i;
        for(unsigned int i = leftOfDecimal+1; i < number.size(); i++) leftNumber.push_back(number[i]);
        return(atoi(leftNumber.c_str()));
    }
    const std::string intToString(double a)
    {
        std::stringstream ss;
        std::string str;
        ss << std::setprecision(10) << a;
        ss >> std::setprecision(10) >> str;
        return(str);
    }
    const unsigned int gcf(const double a, const double b)
    {
        unsigned int gcf, smallest = smallestNumber(a, b), largest = largestNumber(a, b);
        for(unsigned int i = 1; i<smallest+1; i++) if(smallest % i == 0 && largest % i == 0) gcf = i;
        return(gcf);
    }
    const double smallestNumber(const double a, const double b)
    {
        double smallest;
        if(a > b) smallest = b;
        else smallest = a;
        return(smallest);
    }
    const double largestNumber(const double a, const double b)
    {
        double largest;
        if(a > b) largest = a;
        else largest = b;
        return(largest);
    }


Now I am going to try and finish my continued fraction it almost works (the problem though is that I was using doubles and it kinda doesn't work with doubles because 4 is really like 3.999999999 so I can't exactly take off 4 from that) but I am going to take the characteristic and then the mantissa to the say 15th decimal and put them in two separate numbers to get rid of my problem with doubles.
thanks for all the help

Last edited on
Hmm after some more testing. I found that my characteristic works up to 10 digits to the left. And my mantissa has a bug in it. It seems that it only works (well up to 7th digit because of double I'm guessing) if the characteristic and mantissa are the same size I guess I'll be working on that more and I going to use Euclids GCD instead of the continued fraction I think. here is the code I have so far (only works with certain fractions because of the mantissa bug) also there is a bug with my Euclids because of doubles also for example
double 1/10 is supposed to be .1 but it is displayed as .100000000000000000000000055 or something like that don't feel like counting the output'd 0s.
I believe I can fix the euclid bug and the mantissa by converting the doubles to strings and then taking only 10 digits after the decimal I'll let you guys know if it works with me luck =] (PS I figure that 10 digits for mantissa and characteristic is good and pretty precise ex. 1234567890.1234567890)

Edit: 1 more bug with my mantissa I just realized if it is .0625 it will output 625 instead of 0625 I guess I could make it a double and make it .0625 or make it a string of 0625 which I think would be better
Last edited on
I can only imagine the warnings and errors you're getting with this. It would be wise to post your code up here to get help.

One thing that is going to really bite you is putting the actions of your "if" statements on the same line. When you use a debugger to step through this ... code, you will get lost. Also, your "for" loops could use some curly braces for better formatting. I'm just sayin' ...
I have 0 errors and warnings with the class

and I am doing some testing right now comparing string and double and the results show that it is much better to use strings than doubles for the fraction part.
1
2
3
4
5
6
7
8
cout << "INTS::::::::::::::::::::::" << endl;
    cout << "1/10: " << setprecision(100) << (double)1/10 << endl;
    cout << "1/12: " << setprecision(100) << (double)1/12 << endl;
    cout << "1/10 * 1/12: " << setprecision(100) << (double)1/10 * (double) 1/12 << endl << endl;
    cout << "STRINGS::::::::::::::::::" << endl;
    cout << "1/10: " << setprecision(100) << m.numberToString((double) 1/10) << endl;
    cout << "1/12: " << setprecision(100) << m.numberToString((double) 1/12) << endl;
    cout << "1/10 * 1/12: " << setprecision(100) << m.numberToString((double) 1/10 * (double) 1/12) << endl << endl;


the m.numberToString is just a basic string stream

and the output is like this
INTS::::::::::::::::::::::
1/10: 0.1000000000000000055511151231257827021181583404541015625
1/12: 0.08333333333333332870740406406184774823486804962158203125
1/10 * 1/12: 0.00833333333333333321768510160154619370587170124053955078125

STRINGS::::::::::::::::::
1/10: 0.1
1/12: 0.0833333
1/10 * 1/12: 0.00833333

Press <RETURN> to close this window...
Last edited on
Okay got my decimal to fraction working pretty nice =] (seems to work for everything but 22/7(pi) or e) I am going to fix my characteristic and mantissa some more but here is the code let me know if there is anything I could improve on possibly thanks.
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 const signed int characteristic(const double a)
    {
        std::string number = numberToString(a), leftNumber;
        unsigned int decimalAt = 0, leftOfDecimal;
        for(unsigned int i = 0; i<number.size(); i++)
            if(number[i] == '.')
                decimalAt = i;
        if(decimalAt == 0)
            number.append(".0");
        for(unsigned int i = 0; i<number.size(); i++)
            if(number[i] == '.')
                leftOfDecimal = i;
        for(unsigned int i = 0; i < leftOfDecimal; i++)
            leftNumber.push_back(number[i]);
        return(stringToNumber(leftNumber));
    }
const std::string mantissa(const std::string a)
    {
        std::string leftNumber;
        int leftOfDecimal;
        for(unsigned int i = 0; i<a.size(); i++)
            if(a[i] == '.')
                leftOfDecimal = i;
        for(unsigned int i = leftOfDecimal; i< a.size(); i++)
            leftNumber.push_back(a[i]);
        return(leftNumber);
    }

    const std::string numberToString(double a)
    {
        std::stringstream ss;
        std::string str;
        ss  <<  a;
        ss  >> str;
        return(str);
    }const double stringToNumber(std::string a)
    {
        double b;
        std::stringstream ss(a);
        ss >> b;
        return(b);
    }
const std::string decimalToFraction(double a)
    {
        std::string mantissaStr = mantissa(numberToString(a)), characteristicStr, denominator, numerator;
        int toPower = mantissaStr.size() - 1, gcfInt;
        characteristicStr = numberToString(characteristic(a)*power(10,toPower));
        mantissaStr = numberToString(stringToNumber(mantissa(numberToString(a)))*power(10,toPower));
        denominator = numberToString(stringToNumber(characteristicStr) + stringToNumber(mantissaStr));
        numerator = numberToString(power(10, toPower));
        gcfInt = gcf(stringToNumber(denominator), stringToNumber(numerator));
        denominator = numberToString(stringToNumber(denominator) / gcfInt);
        numerator = numberToString(stringToNumber(numerator) / gcfInt);
        return(denominator+"/"+numerator);
    }
int main()
{
double a = (double) 1/16, b = (double) 1/4;
std::cout << decimalToFraction(.0625) << std::endl;
std::cout << decimalToFraction(a) << std::endl;
std::cout << decimalToFraction(b) << std::endl;
}


(there might be a couple bugs with the longer decimals like .062094 that I am going to fix soon)
Last edited on
Topic archived. No new replies allowed.