Please comment on my integer to string code.

B

BobR

Phlip,
Thanks for the info. I appreciate you taking the time.

I have a lot of fun with try-catch in my 'experiments'. Of course I would
never do such things in 'real' code. <G> (reserved for critical errors that
are hard to handle otherwise).

I'll have to do some more testing next time I'm over on a GNU(Debian)
partition in this box.

You ever pop in some screwy stuff like that to rattle your 'lead'? <G>
 
P

Phlip

red said:
We're way OT here, but it turns them into catch(int)?

The purpose of topicality is to grow a healthy community whose members know
they can stretch the bounds now and then.
I could never figure out C0000005 errors (Win32 equivalent of SegV) turned
into. That's the main reason I had catch(...) in my code.

Google this verbiage:

"try-except-statement :
__try compound-statement
__except ( expression ) compound-statement

"The try-except statement is a Microsoft extension to the C and C++
languages that enables 32-bit target applications to gain control when
events that normally terminate program execution occur. Such events are
called exceptions, and the mechanism that deals with exceptions is called
structured exception handling."

Except it ain't catch, it's __except. That's why it's OT - because nobody
will crack down on me if I get the natty details wrong.
 
M

manoj1978

BobR said:
(e-mail address removed) wrote in message
<[email protected]>...
Style-wise, **IMHO**, (at this point) it stinks!! I'd put the 'using *'
inside the function/main if I couldn't type "std::". thanks.will keep in mind.
My suggestions inline below.
// >char charTable[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

std::string charTable( "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
// >void printBase(int i, int base){
std::string CalcBase(int i, int base){
using std::abs; // etc.
if ((abs(base) <= 1) || (abs(base) > 36) || (i == 0)){
// > cout << "0" << endl;
// > return;
return "0";
}

string str = "";
if ((base > 0) && (i < 0)){
str += "-"; // prints "-16 = 10-" for base==16 Thanks.
i = -i; Will this really cause issue if i is smallest negetive int?
}

do {
if (i % base >= 0){
// > str += charTable[i % base];
str += charTable.at( i % base );
i = i / base;
} else {
// > str += charTable[i % base - base];
str += charTable.at( i % base - base );
i = i /base + 1;
}
} while(i);
// > reverse(str.begin(), str.end());
std::reverse(str.begin(), str.end());

// prints "-16 = 10-" for base==16
Will this be ok?
if (str[0] == '-')
std::reverse(str.begin()+1,str.end());
// > cout << str << endl;
return str;
} // CalcBase(int,int)

int main(){

try{
for(int i(-55); i <= 55; ++i){
// > cout << i << " = ";
// > printBase( i, -10 );
std::cout << i <<" = "<<CalcBase( i, -10 )<<std::endl;
} // for(i)
} // try
catch(std::eek:ut_of_range &Oor){
std::cerr<<"caught "<<Oor.what()<<std::endl;
return EXIT_FAILURE;
}
catch(...){
std::cerr<<"caught ... something"<<std::endl;
return EXIT_FAILURE;
}
return 0;
} // main()end

Thanks and Regards,
manoj.

// - output - (base==-10)
-55 = 65
-54 = 66
[snip]
-11 = 29
-10 = 10
-9 = 11
-8 = 12
[snip]
-2 = 18
-1 = 19
0 = 0
1 = 1
[snip]
8 = 8
9 = 9
10 = 190
11 = 191
[snip]
54 = 154
55 = 155


And your C++ problem is?
I modified a C code for this.I havent used C++ much.Want to be sure
that,there is no stupid mistakes.Thanks Bob,
Regards,
manoj.
 
V

Victor Bazarov

Will this really cause issue if i is smallest negetive int?

Whatever you mean by "smallest negetive"...

If 'i' is INT_MIN (and on some systems it's -32768), then change
its sign and the result may not be representable in an int. What
happens after that is implementation-defined, most likely the 'i'
gets truncated, and you get 0. So, -INT_MIN is 0? That doesn't
seem right...

V
 
M

manoj1978

Victor said:
Whatever you mean by "smallest negetive"...

If 'i' is INT_MIN (and on some systems it's -32768), then change
its sign and the result may not be representable in an int. What
happens after that is implementation-defined, most likely the 'i'
gets truncated, and you get 0. So, -INT_MIN is 0? That doesn't
seem right..
Thanks for the info.
Regards,
manoj..
 
P

Phlip

thanks.will keep in mind.

The ulterior principle here is "give everything the narrowest feasible
scope". For example, prefer this:

loop thing
{
int x ...
}

over this:

int x;
loop thing
{
....
}
// x not used here

If it's not used outside the loop, put it inside the loop block.
Will this really cause issue if i is smallest negetive int?

Write a test case (one of the assert() lines I pitched that puts in such an
input that you reach this line with the smallest int.
// > str += charTable[i % base];
str += charTable.at( i % base );

Note that someone bounced this suggestion. charTable is potentially
constant, so it has no need to be a full-fledged string object.

Write it like this:

char const charTable[] = "0123...Z";
Will this be ok?
if (str[0] == '-')
std::reverse(str.begin()+1,str.end());

I don't know, but I trimmed out the excess stuff from the post, and put
blank lines around your question, to make it easier for others to spot and
answer.

You might also write a test case that forces that situation.
 
M

manoj1978

Phlip said:
The ulterior principle here is "give everything the narrowest feasible
scope". For example, prefer this:

loop thing
{
int x ...
}

over this:

int x;
loop thing
{
...
}
// x not used here

If it's not used outside the loop, put it inside the loop block.


Write a test case (one of the assert() lines I pitched that puts in such an
input that you reach this line with the smallest int.

On my system,it remains as it is.I modified the code to treat that
input as invalid.
// > str += charTable[i % base];
str += charTable.at( i % base );

Note that someone bounced this suggestion. charTable is potentially
constant, so it has no need to be a full-fledged string object.

Write it like this:

char const charTable[] = "0123...Z"; Ok.
Will this be ok?
if (str[0] == '-')
std::reverse(str.begin()+1,str.end());

I don't know, but I trimmed out the excess stuff from the post, and put
blank lines around your question, to make it easier for others to spot and
answer.

You might also write a test case that forces that situation.
I tried with that and it is working fine.want to be sure that it is
okay to use that in C++ or does it have any hidden problems.

Regards,
manoj.
 
M

manoj1978

Phlip said:
Write a test case (one of the assert() lines I pitched that puts in such an
input that you reach this line with the smallest int.

Using C's INT_MIN is okay for C++ or does it have its own way of
representing smallest int?

Regards,
manoj.
 
P

Phlip

manoj1978 said:
Using C's INT_MIN is okay for C++ or does it have its own way of
representing smallest int?

A language lawyer will know the exact difference between INT_MIN and the
"trait" that Dietmar suggested. In general, you may use the mostly harmless
C library things in C++, because C++'s ISO Standard includes the C Library
entirely, by reference, hence a compiler must agree on C's and C++'s size of
ints.
I tried with that and it is working fine.want to be sure that it is
okay to use that in C++ or does it have any hidden problems.

You are answering around my point.

Please write a batch of test cases, like this:

assert("16" == printBase(36+6));
assert("A6" == printBase(10*36+6));
assert("FOO" == printBase(15*36*36 + 25*36 + 36));
...

Run them all each time you make the tiniest change to your program. Put
another way, only make such tiny changes that all the tests pass after each
one. If they fail, use Undo to back out your changes.

That is what your professors should teach on the first day of school; it's
what your textbooks should cover right after "hello world". All programs
need many test cases for every feature. The alternative is always endless
debugging.
 
M

manoj1978

Phlip said:
You are answering around my point.

Please write a batch of test cases, like this:

assert("16" == printBase(36+6));
assert("A6" == printBase(10*36+6));
assert("FOO" == printBase(15*36*36 + 25*36 + 36));
...

Run them all each time you make the tiniest change to your program. Put
another way, only make such tiny changes that all the tests pass after each
one. If they fail, use Undo to back out your changes.

I have to run it for all integers to make sure that in this code,it
will never cause problems.
But a person who know C++ well can immediately tell, if I reverse part
of a string like this,then it will cause issues or will work always.I
really want opinion on the language features I used more than the
algorithm,input or output.
That is what your professors should teach on the first day of school; it's
what your textbooks should cover right after "hello world". All programs
need many test cases for every feature. The alternative is always endless
debugging.

Regards,
manoj.
 
J

Jerry Coffin

@i40g2000cwc.googlegroups.com>, (e-mail address removed)
says...

[ ... ]
Using C's INT_MIN is okay for C++ or does it have its own way of
representing smallest int?

The C version continues to work fine, but you can also
use std::numeric_limits<int>::min(). This can be
particularly useful inside of a template where you don't
necessarily know what type you're dealing with ahead of
time.
 
M

manoj1978

Jerry said:
The C version continues to work fine, but you can also
use std::numeric_limits<int>::min(). This can be
particularly useful inside of a template where you don't
necessarily know what type you're dealing with ahead of
time.
MSVC 6 and gcc 2.95.3 complains on this.Devcpp (having gcc version
3.4.2 mingw) works fine with this.Is this a new feature?
 
B

BobR

(e-mail address removed) wrote in message ...
I have to run it for all integers to make sure that in this code,it
will never cause problems.
But a person who know C++ well can immediately tell, if I reverse part
of a string like this,then it will cause issues or will work always.I
really want opinion on the language features I used more than the
algorithm,input or output.
Regards,
manoj.


#include <iostream> // C++
#include <ostream> // std::endl
#include <string>
// ------------------------------------
class Manoj{
public: // ------------------------------ public
Manoj():
charTable("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
{} // Ctor
// ------------------------------------
void execute( int base, std::eek:stream &cout=std::cout){
cout<<"\n___[ base = "<<base<<" ]___"<<std::endl;
// ------------
for(int i(-55); i <= 55; ++i){
cout << i <<" = "<<CalcBase( i, base )<<std::endl;
} // for(i)
// ------------
cout<<"___[ Done ]___\n"<<std::endl;
} //execute(int,std::eek:stream&)
// ------------------------------------
private: // ------------------------------ private
std::string charTable;
// ------------------------------------
std::string CalcBase( int i, int base ){
using std::abs;
if((abs(base) <= 1) || (abs(base) > 36) || (i == 0)){
return "0";
}
std::string str("");
std::string negate("");
if((base > 0) && (i < 0)){
negate = "-";
i = -i;
}
do{
if(i % base >= 0){
str += charTable.at( i % base );
i = i / base;
}
else{
str += charTable.at( i % base - base );
i = i /base + 1;
}
} while(i);
std::reverse(str.begin(), str.end());
str = negate + str;
// Will this be ok? Try it
// if (str[0] == '-')
// std::reverse(str.begin()+1,str.end());
return str;
} //CalcBase(int,int)
// ------------------------------------
}; //class Manoj
// ------------------------------------

#include <fstream> // std::endl

int main(){
Manoj Man;
Man.execute( 10, std::cout);
Man.execute( 16 );

ofstream File("MyTest.txt");
if( !File ){
std::cerr<<"ofstream File FAILURE!!"<<std::endl;
return EXIT_FAILURE;
}
for(int i( -36 ); i <= 36; ++i){
Man.execute( i, File );
} // for(i)
return 0;
} // main()end
// ------------------------------------
 
M

manoj1978

BobR wrote:

#include <iostream> // C++
#include <ostream> // std::endl
#include <string>
// ------------------------------------
class Manoj{
public: // ------------------------------ public
Manoj():
charTable("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
{} // Ctor
// ------------------------------------
void execute( int base, std::eek:stream &cout=std::cout){
cout<<"\n___[ base = "<<base<<" ]___"<<std::endl;
// ------------
for(int i(-55); i <= 55; ++i){
cout << i <<" = "<<CalcBase( i, base )<<std::endl;
} // for(i)
// ------------
cout<<"___[ Done ]___\n"<<std::endl;
} //execute(int,std::eek:stream&)
// ------------------------------------
private: // ------------------------------ private
std::string charTable;
// ------------------------------------
std::string CalcBase( int i, int base ){
using std::abs;
if((abs(base) <= 1) || (abs(base) > 36) || (i == 0)){
return "0";
}
std::string str("");
std::string negate("");
if((base > 0) && (i < 0)){
negate = "-";
i = -i;
}
do{
if(i % base >= 0){
str += charTable.at( i % base );
i = i / base;
}
else{
str += charTable.at( i % base - base );
i = i /base + 1;
}
} while(i);
std::reverse(str.begin(), str.end());
str = negate + str;
// Will this be ok? Try it
// if (str[0] == '-')
// std::reverse(str.begin()+1,str.end());
return str;
} //CalcBase(int,int)
// ------------------------------------
}; //class Manoj
// ------------------------------------

#include <fstream> // std::endl

int main(){
Manoj Man;
Man.execute( 10, std::cout);
Man.execute( 16 );

ofstream File("MyTest.txt");
if( !File ){
std::cerr<<"ofstream File FAILURE!!"<<std::endl;
return EXIT_FAILURE;
}
for(int i( -36 ); i <= 36; ++i){
Man.execute( i, File );
} // for(i)
return 0;
} // main()end
// ------------------------------------

Hi Bob,
Thank you very much for the code.
I changed ofstream File("MyTest.txt"); to std::eek:fstream
File("MyTest.txt");
Changed charTable into character array and added step to handle
INT_MIN.
It works fine.Once again thanks.
Regards,
manoj.
 
D

Dietmar Kuehl

MSVC 6 and gcc 2.95.3 complains on this.Devcpp (having gcc version
3.4.2 mingw) works fine with this.Is this a new feature?

Both MSVC 6 and gcc 2.95* should be considered pre-standard compilers.
Many compilers where pretty late to support certain features provided
by the standard. Whether it is a "new" feature depends on your view:
the standard is now in place for something like seven years...
 
M

manoj1978

Dietmar said:
Both MSVC 6 and gcc 2.95* should be considered pre-standard compilers.
Many compilers where pretty late to support certain features provided
by the standard. Whether it is a "new" feature depends on your view:
the standard is now in place for something like seven years...

Unfortunately my office still uses these two for developement.
At home i have VC 2005 express and Devcpp.
 
D

Dietmar Kuehl

It will cause a problem on all platforms using two's complement to
represent the negative integers. Historically there had been machines
which used a different approach but I would suspect that all modern
systems actually use two's complement. The tricky part here is that
the range of values is asymmetric. If you are using n bits to
represent your integer, the range for signed integers is

-2^(n - 1) to 2^(n - 1) - 1

("x^y" in the above expression means "x to the power of y" not the
C++ meaning of XOR). Applying the usual approach to change the sign
of the number, nothing happens to the smallest negative number: it
just stays the same.
On my system,it remains as it is.I modified the code to treat that
input as invalid.

This is actually the wrong fix! You should treat the situations
somehow. One approach is to handle the least significant digit
specifically and only negate the resulting values afterwards. This
could be done by adding the base to negative values smaller than the
base itself before negating the negative value. I recently posted
code which did just that (although the transformation uses a fixed
base of 10).
 
M

manoj1978

Dietmar said:
This is actually the wrong fix! You should treat the situations
somehow. One approach is to handle the least significant digit
specifically and only negate the resulting values afterwards. This
could be done by adding the base to negative values smaller than the
base itself before negating the negative value. I recently posted
code which did just that (although the transformation uses a fixed
base of 10).

I knew that it is a wrong fix.But unfortunately not able to think of
any solution.
Will surely try your idea.

Thanks and Regards,
manoj.
 
M

manoj1978

Dietmar said:
This is actually the wrong fix! You should treat the situations
somehow. One approach is to handle the least significant digit
specifically and only negate the resulting values afterwards. This
could be done by adding the base to negative values smaller than the
base itself before negating the negative value. I recently posted
code which did just that (although the transformation uses a fixed
base of 10).

Could you please give a link of this posting?

Regards,
manoj.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top