Please comment on my integer to string code.

M

manoj1978

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?

I missed #include <limits> :-(

It works fine in MSVC 6 with that.

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).

I put the following into the code.

if ((base > 0) && (i < 0))
{
if (i < -base)
{
str += charTable[-(i % base)];
i /= base;
}
negate = "-";
i = -i;
}

and it works.

I am confused about adding the base part in your code though.
Could you please explain the reason?

Regards,
manoj.
 
D

Dietmar Kuehl

if (i < -base)
{
str += charTable[-(i % base)];
i /= base;
}
[...]

and it works.

For some definition of "it works" but clearly not mine: the result
of using the modulo operator with negative operands is implementation
defined in C++, i.e. it may work depending on the choice of the
implementation. Essentially, the sign of the result is not defined.
I am confused about adding the base part in your code though.
Could you please explain the reason?

By using something like this to figure out the last digit

-(i < -base? i + base: i) % base

(assuming a positive base) the code avoids any problems with the
implementation defined issues of the modulo operator: both operands
are positive and thus the remainder is clearly positive, too.
 
M

manoj1978

Dietmar said:
if (i < -base)
{
str += charTable[-(i % base)];
i /= base;
}
[...]

and it works.

For some definition of "it works" but clearly not mine: the result
of using the modulo operator with negative operands is implementation
defined in C++, i.e. it may work depending on the choice of the
implementation. Essentially, the sign of the result is not defined.

I have a doubt here. which among these causes undefined behavior?
Because i was relying on these :-((

negetive % negetive.
negetive % positive.
positive % negetive
By using something like this to figure out the last digit

-(i < -base? i + base: i) % base

(assuming a positive base) the code avoids any problems with the
implementation defined issues of the modulo operator: both operands
are positive and thus the remainder is clearly positive, too.

Now I got it.Thanks.

Regards,
manoj.
 
J

Jerry Coffin

@j52g2000cwj.googlegroups.com>, (e-mail address removed)
says...
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?

It's not particularly new. VC++ 6.0 and gcc 2.95.3 are
particularly old...
 
D

Dietmar Kuehl

I have a doubt here. which among these causes undefined behavior?
Because i was relying on these :-((

negetive % negetive.
negetive % positive.
positive % negetive

Well, they are not "undefined" but "implementation defined". There
is a subtle difference: for "undefined" the implementation does not
have to state what it does and actually may not even detect the
situation at all. For "implementation defined" the implementation
is supposed to tell somewhere how it handles the situation.

The relevant quote from the standard is this (5.6, expr.mul,
paragraph 4):

If the second operand of / or % is zero the behavior is undefined;
otherwise (a/b)*b + a%b is equal to a. If both operands are
nonnegative then the remainder is nonnegative; if not, the sign of
the remainder is implementation-defined.
 
M

manoj1978

Dietmar said:
The relevant quote from the standard is this (5.6, expr.mul,
paragraph 4):

If the second operand of / or % is zero the behavior is undefined;
otherwise (a/b)*b + a%b is equal to a. If both operands are
nonnegative then the remainder is nonnegative; if not, the sign of
the remainder is implementation-defined.
I posted my message before seeing this.Sorry.

Regards,
manoj.
 
M

manoj1978

Dietmar Kuehl wrote:

I have a doubt here. which among these causes undefined behavior?
Because i was relying on these :-((

negetive % negetive.
negetive % positive.
positive % negetive

I have the following assumption about % and /

When b != 0.

1. abs(a/b) == abs(a) / abs(b)
2. sign of a/b is positive if a and b have the same sign.negative
otherwise.
3. abs(a%b) == abs(a) % abs(b)
4. sign of a %b == sign of a.
5. (a/b) * b + a%b == a
From C Standard May 6,2005 draft Page 82

section 6.5.5 Mulplicative operators

5 The result of the / operator is the quotient from the division of the
first operand by the
second; the result of the % operator is the remainder. In both
operations, if the value of
the second operand is zero, the behavior is undefined.
6 When integers are divided, the result of the / operator is the
algebraic quotient with any
fractional part discarded(88) If the quotient a/b is representable, the
expression
(a/b)*b + a%b shall equal a.

foot note 88) This is often called ''truncation toward zero''.

How many of my assumptions are valid? Also what the C++ standard says
about this?
 
M

manoj1978

Dietmar Kuehl wrote:

I have a doubt here. which among these causes undefined behavior?
Because i was relying on these :-((

negetive % negetive.
negetive % positive.
positive % negetive

I have the following assumption about % and /

When b != 0.

1. abs(a/b) == abs(a) / abs(b)
2. sign of a/b is positive if a and b have the same sign.negative
otherwise.
3. abs(a%b) == abs(a) % abs(b)
4. sign of a %b == sign of a.
5. (a/b) * b + a%b == a
From C Standard May 6,2005 draft Page 82

section 6.5.5 Mulplicative operators

5 The result of the / operator is the quotient from the division of the
first operand by the
second; the result of the % operator is the remainder. In both
operations, if the value of
the second operand is zero, the behavior is undefined.
6 When integers are divided, the result of the / operator is the
algebraic quotient with any
fractional part discarded(88) If the quotient a/b is representable, the
expression
(a/b)*b + a%b shall equal a.

foot note 88) This is often called ''truncation toward zero''.

How many of my assumptions are valid? Also what the C++ standard says
about this?
 
M

manoj1978

Dietmar said:
Well, they are not "undefined" but "implementation defined". There
is a subtle difference: for "undefined" the implementation does not
have to state what it does and actually may not even detect the
situation at all. For "implementation defined" the implementation
is supposed to tell somewhere how it handles the situation.

The relevant quote from the standard is this (5.6, expr.mul,
paragraph 4):

If the second operand of / or % is zero the behavior is undefined;
otherwise (a/b)*b + a%b is equal to a. If both operands are
nonnegative then the remainder is nonnegative; if not, the sign of
the remainder is implementation-defined.

A quick search of comp.lang.c shows that what you say is true for C90
also.but differs in C99.
Regards,
manoj
 
D

Dietmar Kuehl

A quick search of comp.lang.c shows that what you say is true for C90
also.but differs in C99.

I know that this was addressed in C99 and it is likely to work in
C++, too. However, this does not really help if you want to have
your code portable.
 
M

manoj1978

Dietmar said:
I know that this was addressed in C99 and it is likely to work in
C++, too. However, this does not really help if you want to have
your code portable.
Yes.Especially since I dont work with that many C99 compilers also.
I have taken care of that now.
Regards,
manoj
 
B

BobR

(e-mail address removed) wrote in message ...
// ------------------------------------
class Manoj{ [snip]
}; //class Manoj
// ------------------------------------
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");

Oooops. It was very late and I got in a hurry to get it posted. Glad you
figured it out.
Changed charTable into character array and added step to handle
INT_MIN.
It works fine.Once again thanks.
Regards,
manoj.

I didn't know if you knew 'class', but, thought it would be easier to test
that way (and I wouldn't have to transfer/translate code from the form I test
in ( that class is inside another class of same design, in my 'testbench'
wxWidgets program)).

So, is it *all* working to your satisfaction now?
 
M

manoj1978

BobR said:
(e-mail address removed) wrote in message ...
Oooops. It was very late and I got in a hurry to get it posted. Glad you
figured it out. No probs :)

I didn't know if you knew 'class', but, thought it would be easier to test
that way (and I wouldn't have to transfer/translate code from the form I test
in ( that class is inside another class of same design, in my 'testbench'
wxWidgets program)).
Yeah,I know class.Not used in the code,since i initially wrote this in
c.I just modified it so as to post here :)
So, is it *all* working to your satisfaction now?
Yes.I thought it may need much work to handle % and / truncating to
infinity.
But on testing with the following functions,found that code needed
change only in INT_MAX handler,since "if (i % base >= 0)" take care of
this change automatically.

int divToInf(int a,int b)
{
bool sign = true;
int add = 0;
if (a < 0)
{
a = -a;
sign = !sign;
add = 1;
}
if (b <0)
{
b = -b;
sign = !sign;
}

if (sign)
{
return a/b + add;
} else {
return -( a/b + add);
}
}

int modToInf(int a,int b)
{
return a - b * divToInf(a,b);
}

Once again thanks.
Regards,
manoj.
 
R

Richard Herring

Hi All,
I wrote the following to print an integer in its string
representation for base -36 to 36.
Please comment on this code.

#include <iostream>
#include <string>

using std::abs;
using std::cout;
using std::endl;
using std::reverse;
using std::string;

char charTable[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

void printBase(int i, int base)
{
if ((abs(base) <= 1) || (abs(base) > 36) || (i == 0))
{
cout << "0" << endl;
return;
}
[snip rest of code]

You've had lots of feedback on the other stuff, but I haven't noticed
anybody commenting on this combination of two completely unrelated
tests:

If the argument is zero, output "0". Fine; that's the expected result.

If the base is out of bounds, output "0". Do you really want an input
error to produce the same result as valid data?

(Incidentally, what have you got against base-1 representation? ;-)
 
M

manoj1978

Richard Herring wrote:
I havent seen this post due to google's interface.Sorry about the
delay.
You've had lots of feedback on the other stuff, but I haven't noticed
anybody commenting on this combination of two completely unrelated
tests:

If the argument is zero, output "0". Fine; that's the expected result.

If the base is out of bounds, output "0". Do you really want an input
error to produce the same result as valid data?

I got that comment also :)
I have seperated them.
(Incidentally, what have you got against base-1 representation? ;-)
Nothing.Somebody asked about negative base numbers in a group.I
searched in math forum about it and wrote the code.Regards,
manoj.
 
R

Richard Herring

Richard Herring wrote:
I havent seen this post due to google's interface.Sorry about the
delay.

I got that comment also :)
I have seperated them.
Nothing.Somebody asked about negative base numbers in a group.I
searched in math forum about it and wrote the code.

Base *1*, not general non-negative bases. It's very easy: 1, 11, 111,
1111, 11111, ...
 
B

Ben Pope

Richard said:
Base *1*, not general non-negative bases. It's very easy: 1, 11, 111,
1111, 11111, ...

Looks like a classic off by one bug to me!

Surely it's:
0, 00, 000, 0000, ...

At least, in a C++ newsgroup.

Ben Pope
 

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,540
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top