wowshekar
asked on
creating new datatype..in c++
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();
}
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();
}
Right,
since your fact stays always
vlstr[0]='\0';
vlen=0;
the string you output is the "" string ...
since your fact stays always
vlstr[0]='\0';
vlen=0;
the string you output is the "" string ...
BTW
cout<<strrev(temp)<<endl;
will add a LF for better readability. (Still no math logic check done ...)
======
Werner
cout<<strrev(temp)<<endl;
will add a LF for better readability. (Still no math logic check done ...)
======
Werner
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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..
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.
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.
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
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
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
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
ASKER
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!
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!
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
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
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_STD AFX) || 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
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_STD
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_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
wowshekar
Any more questions? If you could use our answers, it would be nice to accept one of them to close this thread.
======
Werner
Any more questions? If you could use our answers, it would be nice to accept one of them to close this thread.
======
Werner
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