Cannot find my error?

I am trying to write a program that will convert from one base to another and I am running into a problem with it and I have no idea what is happening.

The problem is in convert(...), somehow, and I do not know how..., my second while loop is bugging on me. It would be much easier to have you see the ouput from my program than to explain what is happening.
So, let us say the inputs to this function are: 10, 3, 556

What is wrong, is what is outputted after you press enter to enter 556.
What newTotal should be is displayed above what it actually is.
In my example, newTotal should be 70 but it is 69.

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
#include <iostream>
#include <math.h>

using namespace std;

string convert(int input, int output, int num);
char getNum(int a);

int main()
{
    int inputBase = 0;
    do
    {
        cout << "Base of numbers inputted: ";
        cin >> inputBase;
    } while(inputBase <= 1);

    int outputBase = 0;
    do
    {
        cout << "Base of numbers ouputted: ";
        cin >> outputBase;
    } while(outputBase <= 1);

    //TODO Check for invalid inputs. If any number is greater than output base

    int numToConvert = -1;
    do
    {
        cout << "Number to convert: ";
        cin >> numToConvert;
    } while(numToConvert < 0);

    cout << endl;
    cout << convert(inputBase, outputBase, numToConvert);

    cin.get();
    return 0;
}

string convert(int inputBase, int outputBase, int num)
{
    int startingExponent = 0;

    while(pow(outputBase, startingExponent) <= num)
    {
        startingExponent++;
    }
    startingExponent--;

    int tempNum;
    int newTotal = num;
    string newNum = "";

    do
    {
        tempNum = 0;

        while(newTotal >= pow(outputBase, startingExponent)) {
            tempNum++;
            cout << "power (" << outputBase << "^" << startingExponent << "): " << pow(outputBase, startingExponent) << endl << "tempNum: " << tempNum << endl << "newTotal should be (" << newTotal << " - " << pow(outputBase, startingExponent) << "): " << newTotal - pow(outputBase, startingExponent) << endl;
            newTotal -= pow(outputBase, startingExponent);
            cout << "Acutal newTotal: " << newTotal << endl << endl;
            cin.get();
        }
        startingExponent--;
        newNum += getNum(tempNum);

    } while(newTotal > 0 || startingExponent != -1);

    return newNum;
}

char getNum(int a) {
    return 48 + a;
}


** I know that if I input a inputBase higher than outputBase or if inputBase > 9, it does not work. Leave that alone for now ^.^

Edit: The problem is at line 62. The value isn't what is should be... It would make a lot more sense if it was compiled.
Last edited on
A line 309 characters long? You do know you're allowed to hit return occasionally, don't you.
Yeah. That was just for basic debugging so I could tell what is going on. Just ouputs some variables and I prefer it on one line. The outputs and inputs in that while loop don't have to be there, they are just for debugging

Edit: The problem is inside of that while loop
Last edited on
I think you've got the maths wrong. You're ignoring inputBase completely.
Yeah. I know I am at the moment. I am just trying to get it to convert from base 10 to something else before I try and add conversion from other bases. My problem is in the three lines:

1
2
3
cout << ... << newTotal - pow(outputBase, startingExponent) << endl; 
newTotal -= pow(outputBase, startingExponent);
cout << "Acutal newTotal: " << newTotal << endl << endl;


Here is an example. I enter a base 10 number and want to convert it to base 3. I enter 556 for my number.

The second (I think...) time through the loop, the the first output statement displays newTotal - pow(outputBase, startingExponent) as 70. However, I then change the value in newTotal to newTotal - pow(outputBase, startingExponent). Then, on the next output, the value in newTotal is 69, instead of 70.
Last edited on
Bump
This is what I have when I compile and run your program:

Base of numbers inputted: 10
Base of numbers ouputted: 3
Number to convert: 556

power (3^5): 243
tempNum: 1
newTotal should be (556 - 243): 313
Acutal newTotal: 313

power (3^5): 243
tempNum: 2
newTotal should be (313 - 243): 70
Acutal newTotal: 70

power (3^3): 27
tempNum: 1
newTotal should be (70 - 27): 43
Acutal newTotal: 43

power (3^3): 27
tempNum: 2
newTotal should be (43 - 27): 16
Acutal newTotal: 16

power (3^2): 9
tempNum: 1
newTotal should be (16 - 9): 7
Acutal newTotal: 7

power (3^1): 3
tempNum: 1
newTotal should be (7 - 3): 4
Acutal newTotal: 4

power (3^1): 3
tempNum: 2
newTotal should be (4 - 3): 1
Acutal newTotal: 1

power (3^0): 1
tempNum: 1
newTotal should be (1 - 1): 0
Acutal newTotal: 0

202121


Your problem could come from the fact you're silently converting floating point values in ints without rounding them beforehand.

Depending on your system, pow(outputBase, startingExponent) might not give an exact integer.
If the value you're expecting is Val, since you're using floating point types you could in fact get Val+err, with err a very small error.

Computing
 
newTotal -= pow(outputBase, startingExponent);

is in fact computing
 
newTotal -= Val+err;

ie
 
newTotal = (int)(newTotal - Val - err);

which will results in newTotal - Val - 1 instead of newTotal - Val.

To avoid that, you should round the computed values or use an integer power function like this one:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int IntPow( int value, int exponent )
{
    // this function does not handle negative exponents
    // only exponent needs to be an int, value can be of any type
    int result = 1;
    while( exponent )
    {
        if( exponent & 1 )
            result *= value;

        value *= value;
        exponent >>= 1;
    }
    return result;
}
Last edited on
That's just weird... When I run it I get:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Base of numbers inputted: 10
Base of numbers ouputted: 3
Number to convert: 556

power (3^5): 243
tempNum: 1
newTotal should be (556 - 243): 313
Acutal newTotal: 313

power (3^5): 243
tempNum: 2
newTotal should be (313 - 243): 70
Acutal newTotal: 69

etc.


It's just weird to me and int ^ int returns with a floating point error, but then again I don't know how Math.pow(...) handles the numbers.

And, thanks for showing me another way to do it and stating what the problem actually was.
Math.pow() requires to be called with floating point arguments.
If you call it with int arguments, they are simply cast to floating point types.

In general, it's best to avoid using floating point types when working with integer values, because you have to worry about that kind of stuff every line you write.

By the way, did my suggestion correct the bug ?
As I said, I was not able to reproduce the bug. So my explanation for it was just an educated guess.
Last edited on
Yeah. Your solution fixed the bug I was having.

But... If I called Math.pow() with two integers, let's say 5 and 6, why are they not cast them to 5.0f and 6.0f?
Last edited on
I'm not sure I understand your question.

When you write
1
2
int a = 5, b = 6, c;
c = pow( a, b );

what your compiler really does is
1
2
int a = 5, b = 6, c;
c = (int) pow( (double)a, (double)b );

Last edited on
Well, I'm just wondering how with:
1
2
int a = 5, b = 6, c;
c = (int) pow( (double)a, (double)b );

The a does not get casted to 5.0 and the b 6.0, if they do they, then I'm just curious about where the error comes from.
They do get cast.

The error comes from pow().
If you compute something like
 
c = c - pow(a,b);

your program must first compute c - pow(a,b).

In the case you are mixing different types, the convention is to cast everybody to the most precise type.
pow() returns a double and c is an int. Therefore c is cast to a double to perform the computation:
 
c = (double)c - pow(a,b);


Since c is an int, the result is cast to an int in order to store it in c.
So what your program really does is
 
c = (int)( (double)c - pow(a,b) );


It's in the computation of (double)c - pow(a,b) that the error can happen.
Topic archived. No new replies allowed.