Problem with character array and integer representation

Hi All,

I'm trying to do arithmetic's of large numbers. I'm using an array of characters to represent the number.

I have read in K&R that
s[i] - '0' gives the numeric value of the character stored in s[i]


where s is an array of character. I'm using this method to convert character to number and vice verse, But, i'm not getting the correct result.

When I create a bigNum object with an initial value, it will give me correct output. But, when I read value using cin, all I get is a blank line.

I checked the archives of the forum and found following link,
http://www.cplusplus.com/forum/beginner/5606/ , but it is also giving me same result.

I'm wrong somewhere in my conversion with types, but not able to figure out. Please help me. I hope I have explained the problem well. If you need any more info, please ask me.

I'm pasting the code below.

BigNum.h
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
#ifndef _BigNum_H_
#define _BigNum_H_

#define MAXDIGITS 100

#define PLUS 1
#define MINUS -1

#include <iostream>
#include <string>
using namespace std;


class bigNum
{
        public:
                bigNum();
                bigNum(long);
                friend ostream & operator<<(ostream &, bigNum);
                friend istream & operator>>(istream &, bigNum);
                char getDigit(int) const;
                int getLastDigit() const;
                void setLastDigit(int);
                void setDigit(int, int);
        private:
                char digits[MAXDIGITS];
                int signbit;
                int lastdigit;
};
#endif 


BigNum.cpp
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
#include "BigNum.h"

bigNum::bigNum() : lastdigit(-1)
{
          int i;
          for(i=0;i<MAXDIGITS;i++)
                *(digits+i) = 0 ;
}

bigNum::bigNum(long a) : lastdigit(-1)
{
        int i;
        for(i=0;i<MAXDIGITS;i++)
                *(digits+i) =  0 ;
        while(a)
        {
                lastdigit++;
                *(digits+lastdigit) =   (a % 10)  + '0';
                a = a / 10;
        }
}

int bigNum::getLastDigit() const { return lastdigit; }

char bigNum::getDigit(int a) const { return *(digits+a); }

void bigNum::setDigit(int digit, int position)
{
                *(digits+position) = digit + '0' ;
}

void bigNum::setLastDigit(int a) { lastdigit = a; }

ostream & operator<<(ostream & out, bigNum a)
{
        int i;
        for(i=a.getLastDigit();i>=0;i--)
                        out << a.getDigit(i) - '0'  ;
        return out;
}

istream & operator>>(istream & in, bigNum a)
{
        char b[100];
        unsigned int i;
        in >> b;
        for(i=0;i<strlen(b);i++)
        {
                a.setDigit( static_cast<int>(*(b+i) - '0'), i);
        }
        a.setLastDigit(strlen(b) - 1);

        return in;
}


testBigNum.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include "BigNum.h"

using namespace std;

int main()
{
        bigNum a;
        cin >> a;
        cout << a << endl;

        return 0;
}
On line 49 you are passing two parameters to setDigit-the first is the value, and the second is the
index, but your setDigit function takes them in the opposite order.

As a matter of design, I would strongly encourage you to not force the user to manage the
"last used digit" in your internal array.

I guess, it did not solve the issue.

I checked the value coming in the digit variable and it is giving me correct output. But, when it is stored in the array and printed, only a blank line is coming.


1
2
3
4
5
void bigNum::setDigit(int digit, int position)
{
        cout << digit <<  endl;
                *(digits+position) = digit + 48 ;
}


To cross check, i rewrote the constructor.

1
2
3
4
5
6
7
8
9
10
11
bigNum::bigNum(long a) : lastdigit(-1)
{
        int i;
        for(i=0;i<MAXDIGITS;i++)
                *(digits+i) =  '0' ;
        while(a)
        {
                setDigit(a%10, ++lastdigit);
                a = a / 10;
        }
}


Here I am getting correct result. Any any idea what is going on?
I got the answer for my question from an old friend of mine.
you are passing 'a' by value, pass it by reference into '>>' . I think that is the catch here.
Now that I got my answer, may I ask why you suggested the following.


As a matter of design, I would strongly encourage you to not force the user to manage the
"last used digit" in your internal array.
It's a matter of separation of concerns.

Internally, your class works by storing the digits in an array. Externally, your user shouldn't need to be
aware of how you represent it. In fact, you even agree with that by virtue of making the array private.

But setLastDigit() sort of "exposes" knowledge of that internal array on the user. Not only do you
have to tell your user that internally you store the number as an "array" of bytes, but you also have
to tell them that you store the digits left justified in the array. For example, 1234 is represented as

"1234000000" and not "0000001234" (assuming MAX_DIGITS is 10 instead of 100 for brevity).

Oh -- but it gets worse, now that I look more closely. You store the digits backwards, so in
actuality, 1234 is stored as "4321000000" not as I said above. Again, in order to use setDigit()
as you've defined it, the user has to know also that you store the number backwards.

So in reality, although all your data members are private, the setDigit, getDigit, etc methods all
completely expose the internal implementation details of the class, so much so that you might
as well make the data members public because as it stands, you could hardly make any
significant changes to the class without breaking the code that uses it. (For example, you
could never right justify the number or store the digits in the right order).
Hi,

Thanks for your comments, and I think I understood what you are saying. I'll modify my implementation and post new implementation tommorow . Could you please check it and give your comments, because I using this for learning purpose and your comments will be invaluable for me.

Thanks.
I can, but I will be away from a computer for a week after today.
Topic archived. No new replies allowed.