want a better version of this

S

sugaray

Hi, can somebody help me out with a better version of the following
functions which only convert decimal integer to it's corresponding
binary form. the
problem i'm having now is that I can't figure out how to handle when 0
is
passed as parameter in only one function, my code below have to add
one more function to handle this situation, any help is appreciated,
thanx.


char *Dec2Bin(const int decimal) {

char *binary=new char[64];
int dividend,i;

dividend=decimal;
for(i=0;dividend!=0;++i) {
binary=(dividend&1)+'0'; // (a % b) == (a & (b-1))
dividend>>=1;
}
binary='\0';

return strrev(binary);
}

char *Decimal2Binary(const int decimal) {
return (decimal==0)?"0":Dec2Bin(decimal);
}
 
E

Emmanuel Delahaye

In said:
char *binary=new char[64];

There is no 'new' in C. Please repost to the appropriate newsgroup. It seems
that C is not your langage.

If you insist in writing your code in C, please change it so that it uses C
functions and instructions.
 
P

pete

sugaray said:
Hi, can somebody help me out with a better version of the following
functions which only convert decimal integer to it's corresponding
binary form. the
problem i'm having now is that I can't figure out how to handle when 0
is
passed as parameter in only one function, my code below have to add
one more function to handle this situation, any help is appreciated,
thanx.

char *Dec2Bin(const int decimal) {

/* BEGIN bitstr.c */

#include <stdio.h>
#include <limits.h>

#define E_TYPE float
#define STRING " %s = %f\n"

typedef E_TYPE e_type;

char *bitstr(char *, void const *, size_t);

int main(void)
{
e_type e, d;
char ebits[CHAR_BIT * sizeof e + 1], *s;

s = STRING;
for (e = 0.2f; 0.75 > e; e += 0.125) {
bitstr(ebits, &e, sizeof e);
printf(s, ebits, e);
}
for (d = 2; 20000 > d; d *= 2) {
for (e = d - 1; 0.75 > e - d; e += 0.5) {
bitstr(ebits, &e, sizeof e);
printf(s, ebits, e);
}
}
return 0;
}

char *bitstr(char *str, const void *obj, size_t n)
{
unsigned char mask;
const unsigned char *byte = obj;
char *const ptr = str;

while (n-- != 0) {
mask = ((unsigned char)-1 >> 1) + 1;
do {
*str++ = (char)(mask & byte[n] ? '1' : '0');
mask >>= 1;
} while (mask != 0);
}
*str = '\0';
return ptr;
}

/* END bitstr.c */
 
R

Richard Heathfield

Emmanuel said:
In said:
char *binary=new char[64];

There is no 'new' in C.

It's a perfectly valid identifier name (albeit used in a rather strange and
syntactically erroneous manner in the code you quote here). In fact, I
often use it myself in code such as:

FOO *prefix_CreateFoo(args...)
{
FOO *new = malloc(sizeof *new);
if(new != NULL)
{
...set up valid FOO instance...
}
return new;
}
 
E

Emmanuel Delahaye

It's a perfectly valid identifier name (albeit used in a rather strange
and syntactically erroneous manner in the code you quote here). In fact,
I often use it myself in code such as:

FOO *prefix_CreateFoo(args...)
{
FOO *new = malloc(sizeof *new);
if(new != NULL)
{
...set up valid FOO instance...
}
return new;
}

I prefer to use 'this', in this case!
 
G

Georg Troxler

Emmanuel said:
In said:
char *binary=new char[64];

There is no 'new' in C.

It's a perfectly valid identifier name (albeit used in a rather strange and
syntactically erroneous manner in the code you quote here). In fact, I
often use it myself in code such as:

FOO *prefix_CreateFoo(args...)
{
FOO *new = malloc(sizeof *new);
if(new != NULL)
{
...set up valid FOO instance...
}
return new;
}


You can use:

Char* binary = (char*)malloc(sozeof(char)*64); // allocate 64 times space
for a char
assert(binary); // make sure everything went ok (Memoryoverflow asf.)


// don¹t forget when you don¹t use binary anymore
free(binary);
 
R

Richard Heathfield

Georg said:
You can use:

Char

Undefined type.
* binary = (char*)

Unnecessary cast.

malloc(sozeof(char)

Undeclared macro, sozeof
*64); // allocate 64 times space

If that's what you want to do, use:

char *binary = malloc(64);

or, perhaps:

char *binary = malloc(64 * sizeof *binary);

for a char

Illegal syntax for for-loop. (Hint: if you must use BCPL/C99 comments, make
sure your lines don't wrap!)

assert(binary); // make sure everything went ok (Memoryoverflow asf.)

This is a lousy use of assert. Assertions are best used for asserting
conditions that /must/ be true if and only if the programmer didn't screw
up. Furthermore, assert(pointerexpression) is not portable to C90.

Far better to check for NULL and handle the out-of-memory condition
robustly.
 
R

Robert Bachmann

Georg said:
Char* binary = (char*)malloc(sozeof(char)*64); // allocate 64 times space
for a char
#include <stdlb.h>
somewhere

char* binary=malloc(sizeof(char)*64);
or:
char* binary=malloc(64);
assert(binary); // make sure everything went ok (Memoryoverflow asf.)
I don't think this is a good idea.
Imagine the following code:

#define NDEBUG
#include <assert.h>
#include <stdlib.h>
int main(void)
{
char *c;

c=malloc(64);
assert(c);

strcpy(p,"hello");

return 0;
}

In this code strcpy is also executed if c==NULL.
So I do think it is better to use:
if (!c) { /* or if (c==NULL) whatever you prefer */
/*some error handling here*/
}

or

if (c) { /* or if (c!=NULL) */
/*do something with c*/
}

-rb
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
You can use:

Char* binary = (char*)malloc(sozeof(char)*64); // allocate 64 times
space for a char

(assuming typos are fixed) A complicated way of writing

char* binary = malloc(64);
assert(binary);

And what happens in release mode when NDEBUG is defined? Nothing. It's bad!
// don¹t forget when you don¹t use binary anymore
free(binary);

Agreed.
 
M

Martin Ambuhl

Georg Troxler wrote:

You can use:

Char* binary = (char*)malloc(sozeof(char)*64); // allocate 64 times space
for a char
assert(binary); // make sure everything went ok (Memoryoverflow asf.)

What the hell language is this? You _may_ mean
char *binary = malloc(64); /* note the case of 'char', the absence of the
superfluous cast, the absence of the
tautological and misspelled 'sozeof(char) *'
*/
if (!binary) { /* handle error */ }
 
R

Richard Heathfield

Randy said:
I suppose this is a good way to make sure you code isn't accidentally
used with a C++ compiler?

Yes, precisely. C and C++ are divided by a common syntax. It's important not
to mix them up accidentally.
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
I suppose this is a good way to make sure you code isn't accidentally
used with a C++ compiler?

He he! I'm not supposed to know a word about C++. But for what you have
suggested, I put this on my sources (.c only)

#ifdef __cplusplus
#error This source file is not C++ but rather C. Please use a C-compiler
#endif
 
R

Richard Heathfield

Emmanuel said:
He he! I'm not supposed to know a word about C++. But for what you have
suggested, I put this on my sources (.c only)

#ifdef __cplusplus
#error This source file is not C++ but rather C. Please use a C-compiler
#endif

That's fine for C99, but IIRC there is no restriction on C90 compilers
defining __cplusplus for whatever dastardly purpose they choose. Therefore,
tempting as your suggestion is, I cannot adopt it myself.

Of course, I could do this:

static int new;

at the top of every C file. :)
 
R

Randy Howard

That's fine for C99, but IIRC there is no restriction on C90 compilers
defining __cplusplus for whatever dastardly purpose they choose. Therefore,
tempting as your suggestion is, I cannot adopt it myself.

Now, that is pedantic. :)
Of course, I could do this:

static int new;

at the top of every C file. :)

Well, you could at least do this...

static int new; /* Hey! this file is NOT valid C++, don't even try. */

and then way down at the bottom somewhere....

static int this; /* Hello! I warned you, do you never give up? */
 
C

CBFalconer

Richard said:
.... snip ...

Of course, I could do this:

static int new;

at the top of every C file. :)

Maybe:

static char this, class, new; /* why waste space */
 
S

Sean Kenwrick

sugaray said:
Hi, can somebody help me out with a better version of the following
functions which only convert decimal integer to it's corresponding
binary form. the
problem i'm having now is that I can't figure out how to handle when 0
is
passed as parameter in only one function, my code below have to add
one more function to handle this situation, any help is appreciated,
thanx.


char *Dec2Bin(const int decimal) {

char *binary=new char[64];
int dividend,i;

dividend=decimal;
for(i=0;dividend!=0;++i) {
binary=(dividend&1)+'0'; // (a % b) == (a & (b-1))
dividend>>=1;
}
binary='\0';

return strrev(binary);
}

char *Decimal2Binary(const int decimal) {
return (decimal==0)?"0":Dec2Bin(decimal);
}


Why not fill the string from the left, thus avoiding the need to do strrev ?
Something like this?

char *Dec2Bin(const unsigned int decimal) {
int i,num_bits;
char *binary;

num_bits=sizeof(int)*8;
binary=calloc(1,num_bits+1);

for(i=num_bits;i>=0;i--)
binary[num_bits-i]=((1<<i)&decimal)+'0';

return binary;
}

If you don't want the trailing '0's then add a flag which gets set when the
first non zero bit is reached and check against this flag inside your inner
loop so that all future '0's get written.

Note I have also changed the function argument to unsigned int since I think
there might be some implementation issues with using signed integers..

Sean
 
S

Sean Kenwrick

Sean Kenwrick said:
sugaray said:
Hi, can somebody help me out with a better version of the following
functions which only convert decimal integer to it's corresponding
binary form. the
problem i'm having now is that I can't figure out how to handle when 0
is
passed as parameter in only one function, my code below have to add
one more function to handle this situation, any help is appreciated,
thanx.


char *Dec2Bin(const int decimal) {

char *binary=new char[64];
int dividend,i;

dividend=decimal;
for(i=0;dividend!=0;++i) {
binary=(dividend&1)+'0'; // (a % b) == (a & (b-1))
dividend>>=1;
}
binary='\0';

return strrev(binary);
}

char *Decimal2Binary(const int decimal) {
return (decimal==0)?"0":Dec2Bin(decimal);
}


Why not fill the string from the left, thus avoiding the need to do strrev ?
Something like this?

char *Dec2Bin(const unsigned int decimal) {
int i,num_bits;
char *binary;

num_bits=sizeof(int)*8;
binary=calloc(1,num_bits+1);

for(i=num_bits;i>=0;i--)
binary[num_bits-i]=((1<<i)&decimal)+'0';

return binary;
}

If you don't want the trailing '0's then add a flag which gets set when the
first non zero bit is reached and check against this flag inside your inner
loop so that all future '0's get written.

Note I have also changed the function argument to unsigned int since I think
there might be some implementation issues with using signed integers..

Sean

There is an error in the above it should read something like:

binary[num_bits-i]=((1<<i)&decimal)?'1':'0';

Sean
 

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

Forum statistics

Threads
474,138
Messages
2,570,804
Members
47,349
Latest member
jojonoy597

Latest Threads

Top