input error

A

Al

I am typing the following code to convert a binary number to decimal.
It usually works fine with little numbers, but with some numbers, it
reads strange values:

#include <stdio.h>
#include <stdlib.h>

int main()
{
int bin, dec=0, num=1;
scanf("%d", &bin);
printf("%d\n", bin); //look at the value it prints!!
dec += (bin%10) * 1;
bin /= 10;
while (bin>1)
{
dec += (bin%10) * num*2;
num*=2;
bin /= 10;
}
dec += bin * num*2;
printf("%d\n", dec);
system("pause");
return 0;

}

When I debug or print the value of bin with an input of: 10011001100,
the values it prints are a lot different: 1421066508 for bin value and
2028 for dec!!!!!!!!

What's the problem? I it for integer overflow maybe?

_____ (also posted in comp.lang.c++)
 
M

Mike Wahler

Al said:
I am typing the following code to convert a binary number to decimal.
It usually works fine with little numbers, but with some numbers, it
reads strange values:

#include <stdio.h>
#include <stdlib.h>

int main()
{
int bin, dec=0, num=1;
scanf("%d", &bin);
printf("%d\n", bin); //look at the value it prints!!
dec += (bin%10) * 1;
bin /= 10;
while (bin>1)
{
dec += (bin%10) * num*2;
num*=2;
bin /= 10;
}
dec += bin * num*2;
printf("%d\n", dec);
system("pause");
return 0;

}

When I debug or print the value of bin with an input of: 10011001100,
the values it prints are a lot different: 1421066508 for bin value and
2028 for dec!!!!!!!!

I think you have a fundamental misunderstanding. When you
input e.g. 1001, that is *not* a binary number, it's decimal
(i.e. the value is 'one thousand and one', not nine.

scanf and printf with %d work with *decimal* numbers, not
binary. There are no built-in specifiers for binary.

If you want to convert an input sequence of one and zero
characters to binary, you'll need to take your input as
a string, convert each one or zero character to numeric
(subtract the character '0' from it), and use those
numeric values in your computations.

-Mike
 
F

Flash Gordon

Al said:
I am typing the following code to convert a binary number to decimal.
It usually works fine with little numbers, but with some numbers, it
reads strange values:

#include <stdio.h>
#include <stdlib.h>

int main()

It is better (but not required) that you be explicit that you are not
using any parameters.

int main(void)
{
int bin, dec=0, num=1;
scanf("%d", &bin);

what if the user enters "one"? scanf returns a value for a reason, you
would be advised to check it when using scanf.
printf("%d\n", bin); //look at the value it prints!!

// style comments are inadvisable on Usenet since although they are
valid in C99 and are a common extension on C89 compilers (i.e. most
compilers) they do not survive line wrapping.
dec += (bin%10) * 1;

Why multiply by 1? What if the user enters 2? Some error trapping might
be a good idea.
bin /= 10;
while (bin>1)
{
dec += (bin%10) * num*2;

What if the user entered 21? Error checking would be good around here as
well.
num*=2;
bin /= 10;
}
dec += bin * num*2;
printf("%d\n", dec);
system("pause");
return 0;

}

When I debug or print the value of bin with an input of: 10011001100,
the values it prints are a lot different: 1421066508 for bin value and
2028 for dec!!!!!!!!

What's the problem? I it for integer overflow maybe?

Probably. The range of int can be as small as small as -32767 to + 32767
(yes, I did exclude -32768 deliberately). Even if int is 32 bits the
decimal value 1011001100 still won't fit.

A better approach would be to read the input as a string and process it
character by character remembering to check for overflow. Remember that
with signed integer types you have to check whether the overflow will
occur *before* doing the calculation, since once it has occurred all
bets are off.

Also, with appropriate initialisation I'm sure you could avoid the need
to handle the first digit as a special case.
_____ (also posted in comp.lang.c++)

In C++ the best solution might be different, although I believe the
problems I've pointed out would still apply. So you should really decide
which language you are using.
 
S

Skarmander

Mike Wahler wrote:
If you want to convert an input sequence of one and zero
characters to binary, you'll need to take your input as
a string, convert each one or zero character to numeric
(subtract the character '0' from it)

No. '1' - '0' is not guaranteed to be 1 (though you'd indeed be
hard-pressed to find a configuration where it doesn't hold). This also
lacks error checking, but let's assume that's been taken care of.

By far the quickest way of solving the entire problem is to use
strtoul(), but of course this may not present as good a learning
experience (implementing a strtoul() equivalent might be a bit too much
of a learning experience, however).

S.
 
S

Skarmander

Skarmander said:
Mike Wahler wrote:



No. '1' - '0' is not guaranteed to be 1

Except, of course, that it is. Why do I even bother? Consistency and C
don't mix. :)

S.
 
F

Flash Gordon

Skarmander said:
Mike Wahler wrote:


No. '1' - '0' is not guaranteed to be 1 (though you'd indeed be
hard-pressed to find a configuration where it doesn't hold). This also
lacks error checking, but let's assume that's been taken care of.

Actually, '1' - '0' *is* guaranteed to be 1 by the C standard. It's
covered in section 5.2.1 of N1124 (Google for it).

From what I've seen Mike knows rather more about C than you, so you
might find it advisable to check in the standard before claiming that he
is wrong.
By far the quickest way of solving the entire problem is to use
strtoul(), but of course this may not present as good a learning
experience (implementing a strtoul() equivalent might be a bit too much
of a learning experience, however).

Indeed.
 
S

Skarmander

Flash said:
Actually, '1' - '0' *is* guaranteed to be 1 by the C standard. It's
covered in section 5.2.1 of N1124 (Google for it).
Already have it. I quote the thing fairly often, too. Except section
5.2.1, of course...

I'm going to chalk it up to the asynchronous nature of Usenet that you
didn't see my own correction to this, which I posted not one minute
afterwards. (Although I didn't quote chapter and verse.)
From what I've seen Mike knows rather more about C than you, so you
might find it advisable to check in the standard before claiming that he
is wrong.
Actually, it's advisable to check in the standard before claiming anything.

I can't be bothered to keep track of my intellectual superiors, and
besides, it gives them an unfair advantage. I might be tempted to accept
claims on authority, and that's not a good thing to do -- at least not
when it comes to the semantics of C.

S.
 

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,770
Messages
2,569,584
Members
45,079
Latest member
ElidaWarin

Latest Threads

Top