We help IT Professionals succeed at work.

creating new datatype..in c++

wowshekar
wowshekar asked
on
hi!
i wrote a program which calculates 100!. but i dont know why the output shows no result.. it says nothing when i tried to print the result.. here is the code:
i think there is something wrong in putvl routine..please let me know my error..


#include <iostream.h>
#include <string.h>
#include <stdlib.h>

const int sz=200;

class verylong
{
private:
     char vlstr[sz];
     int vlen;
     verylong multdigit(int);
     verylong mult10(verylong);
public:
     verylong()
     {
          vlstr[0]='\0';
          vlen=0;
     }

     verylong(char s[sz])
     {
          strcpy(vlstr,s);
          vlen=strlen(s);
     }

     verylong(unsigned long n)
     {
          ltoa(n,vlstr,10);
          strrev(vlstr);
          vlen=strlen(vlstr);
     }

     void putvl();
     void getvl();
     verylong operator + (verylong);
     verylong operator * (verylong);
};


void verylong::putvl()
{
     char temp[sz];
     strcpy(temp,vlstr);
     cout<<strrev(temp);
}

void verylong::getvl()
{
     cin>>vlstr;
     vlen=strlen(vlstr);
     strrev(vlstr);
}

verylong verylong::operator + (verylong v)
{
     char temp[sz];

     int maxlen=(vlen>v.vlen) ? vlen:v.vlen;
     int carry = 0;;
     for(int j=0; j<maxlen; j++)
     {
          int d1=(j>vlen-1) ? 0:vlstr[j]-'0';
          int d2=(j>vlen-1) ? 0:vlstr[j]-'0';
          int digitsum=d1+d2+carry;
          if(digitsum>=10)
          {
               digitsum-=10;
               carry=1;
          }
          else
               carry=0;
          temp[j]=digitsum+'0';
     }

     if(carry==1)
          temp[j++]='1';
     temp[j]='\0';
     return verylong(temp);
}

verylong verylong::operator * (verylong v)
{
     verylong pprod;
     verylong tempsum;
     for (int j=0;j<v.vlen;j++)
     {
          int digit=v.vlstr[j]-'0';
          pprod=multdigit(digit);
          for(int k=0;k<j;k++)
               pprod=mult10(pprod);
          tempsum=tempsum+pprod;
     }
     return tempsum;
}

verylong verylong::mult10(verylong v)
{
     char temp[sz];
     for(int j=v.vlen-1;j>=0;j--)
          temp[j+1]=v.vlstr[j];
     temp[0]='0';
     temp[v.vlen+1]='\0';
     return verylong(temp);
}

verylong verylong::multdigit(int d2)
{
     char temp[sz];
     int carry = 0;
     for (int j=0;j<vlen;j++)
     {
          int d1=vlstr[j]-'0';
          int digitprod=d1*d2;
          digitprod+=carry;
          if(digitprod>=10)
          {
               carry=digitprod/10;
               digitprod-=carry*10;
          }
          else
          carry=0;
          temp[j]=digitprod+'0';
     }
     if(carry!=0)
          temp[j++]=carry+'0';
     temp[j]='\0';
     return verylong(temp);
}


void main()
{
     unsigned long numb,j;
     verylong fact;


     cout<<"\n\nEnter a number: ";
     cin>>numb;

     for(j=numb;j>0;j--)
          fact=fact*j;
     cout<<"factorial is ";
     fact.putvl();
}

         
Comment
Watch Question

Commented:
your constructor for verylong sets the var to 0 by default. So in
    verylong fact;
fact = 0;
Your multiplication

fact=fact*j;

will therefor be 0 forever (0 * anything = 0);

I didn't check the program too thorrowly, but initializing

    verylong fact = 1;

produces an output and makes more sense ...
At least a starting point for your own debugging.

======
Werner

Commented:
Right,

since your fact stays always
         vlstr[0]='\0';
         vlen=0;
the string you output is the "" string ...

Commented:
BTW

cout<<strrev(temp)<<endl;

will add a LF for better readability. (Still no math logic check done ...)

======
Werner
Two problems:

1. fact = 0 by default (as mentioned by Werner). For any calculation you should start by putting fact = 1 BTW, 0! = 1 by definition.

2. the lines
         int d1=(j>vlen-1) ? 0:vlstr[j]-'0';
         int d2=(j>vlen-1) ? 0:vlstr[j]-'0';
should be changed to
         int d1=(j>vlen-1) ? 0:vlstr[j]-'0';
         int d2=(j>v.vlen-1) ? 0:v.vlstr[j]-'0';

then everything works!

Author

Commented:
hi!
thanks for your response.. i made changes but it still prints wrong result. if i give 2 it prints 0 and if i give 12 it prints 0000.. i think there is some problem with my initialization or may be with the constructor.. please tell me what to do..
i did the changes as given by LoungeLizard.. thank you..please look through my constructor..if you find any mistakes please inform me..thank you once again..
Hmm, that's strange. I took your code, made the two changes above and it works perfectly.

The only other change I made was to change the declaration of

for(int j = ....)

to

int j;

for(j=...)


This is because the new ANSI C++ standard see the for(...) {...} also as a scope and the variable j will go out of scope and cannot be used after that.

What compiler are you using?

I will have a look at the constructors but I din't see anything wrong.
What you can also do (I did it to find the bug) is to put cout's everywhere in your code. That way you can follow what is happening at each stage. If you have a fancy IDE like Visual C++ or C++ Builder you can add watches and breakpoints to do debugging.
CERTIFIED EXPERT
Author of the Year 2009

Commented:
I agree, it works with just the two changes
  fact=1 in main and
  d2= (j>v.Xxxxx... in operator +

verylarge is very cool!  Next assignment:  Display the digits of the worlds longest meaningful number:  The Mersenne prime:

  2^1257787-1

but be warned, it is 378632 digits in length!

-- Dan

Commented:
wowshekar

1) I don't think that is your own code. If you were able to write a class like "verylong", you should be able to find the two major flaws in that code.

2) As everybody else stated, with these two fixes the program works (even for your !12), so you did somethinh wrong. (what compiler are you using).

3) LoungeLizard's suggestion to put in couts will help. You can always use your putvl function for that. Did you know that you can overload the << operator also?

======
Werner

Author

Commented:
hi griessh!
thanks for your time for looking at my code.. yes i agree that its not my code entirely. but i know what iam doing. if you dont want to decode or find whats going wrong, then no problem. dont even try to say to someone that its not their code. because everyone needs some startup to start their assignment. this was just beginning of my assignment. i got to do more.. i have to develop my verylong class. one more thing.. i know what a constructor is and what it does.
dont mess up things here!

Commented:
Sorry if I misjudged you ...

If that's a homework assignment, then I would suggest to you to either use a debugger for your system or make use of the couts in your code. You have to be able find these very basic problems you have before you can even think of debugging logical problems that might show up.

Good luck

======
Werner

Commented:
I agree that debugging can solve problems like this. Debugging is an art, but can be learned with a toolset of techniques, such as the suggested one of printing out intermediate results.

If you are using Windows, you may be interested in the following TRACE function I wrote and use in all my programs.

You can strip out the bells and whistles if you like and still have a nice TRACE function.

--------------------

Example:

TRACE("x = %d, Name = %s", x, Name);

--------------------

Source file:

// Define this to store TRACE output in C:\DebugOutput.txt instead of showing
// it in the Debug Window
//#define               FAST_TRACE_TO_FILE

// Define this to enable TRACE output in Release builds
//#define               FORCE_DEBUG_IN_STDAFX

#if defined(FORCE_DEBUG_IN_STDAFX) || defined(FAST_TRACE_TO_FILE) || \
     defined(_DEBUG)
#define _LOCAL_DEBUG
#endif

#ifdef FAST_TRACE_TO_FILE
#include               <IO.h>
#include               <fcntl.h>

// From stdio.h or mmsystem.h
#define SEEK_CUR    1
#define SEEK_END    2
#define SEEK_SET    0

int                         AppendFlag = _O_TRUNC;
int                         TraceFile;
#endif // FAST_TRACE_TO_FILE

#ifdef _LOCAL_DEBUG
char                    TempText[9000];
#endif

// Send an informational message to Debug Window, if any
#ifndef _LOCAL_DEBUG
     inline
#endif
void                    Trace(const char * Format, ...)
     {
#ifdef _LOCAL_DEBUG
     va_list               Args;
     int                    Len;

     char *               pText;

     pText = TempText;

     // Start with the message prefix
     pText += wsprintf(pText, "%s> ", AppName);

     // Format the string, append to message prefix
     va_start(Args, Format);
     pText += wvsprintf(pText, Format, Args);
     va_end(Args);
     pText += wsprintf(pText, "\r\n");

     // Limit the length to 200 chars
     Len = lstrlen(TempText);
     if (Len > 200)
          lstrcpy(TempText + 200 - 6, "...\r\n");

#ifdef FAST_TRACE_TO_FILE
     // Write string at end of C:\DebugOutput.txt
     TraceFile = _open("C:\\DebugOutput.txt", _O_CREAT | _O_WRONLY | _O_BINARY |
          _O_SEQUENTIAL | AppendFlag);
     _write(TraceFile, TempText, lstrlen(TempText));
     _close(TraceFile);
     AppendFlag = _O_APPEND;
#else
     // Send string to debug window, if any
     OutputDebugString(TempText);
     Sleep(64); // Windows bug workaround: Sometimes text is truncated
#ifdef SYNC_TRACE
     Sleep(SYNC_TRACE);
#endif // SYNC_TRACE
#endif // FAST_TRACE_TO_FILE
#endif // _LOCAL_DEBUG
     } // End of Trace

--------------------

Include file:

// Define SYNC_TRACE before Include of StdAfx.h to pause after every line of
// TRACE output by SYNC_TRACE msec

#undef                    TRACE
#define                    TRACE Trace

void                    Trace(const char * Format, ...);

#ifdef SYNC_TRACE
#     if (SYNC_TRACE + 0) == 0
#          error Macro SYNC_TRACE is defined but has an empty string
#     endif
#endif SYNC_TRACE
--------------------

David

Commented:
wowshekar

Any more questions? If you could use our answers, it would be nice to accept one of them to close this thread.

======
Werner

Explore More ContentExplore courses, solutions, and other research materials related to this topic.