473,695 Members | 2,736 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

critique: conversion to binary

Inspired by fb, Bowsayge decided to write a decimal integer
to binary string converter. Perhaps some of the experienced
C programmers here can critique it. It allocates probably
way too much memory, but it should certainly handle 64-bit
cpus :)

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

char * to_binary (unsigned long value) {
const int maxdata = 100;
char * data = malloc(maxdata+ 1);
int pos = 0;
int pos2 = 0;
if (0 == data) return 0;

if (0 == value) {
return strcpy (data, "0");
}

while (value > 0) {
if (pos >= maxdata) {
printf ("ran out of memory\n");
exit(EXIT_FAILU RE);
}
data [pos++] = '0' + (value & 1);
value >>= 1;
}
data[pos--] = 0;

for (pos2 = 0; pos2 < pos; pos2++, pos--) {
char temp = data[pos];
data[pos] = data[pos2];
data[pos2] = temp;
}

return data;
}

int main (int argc, const char * argv [])
{
int ii = 0;
while (ii < argc) {
unsigned long num = ii < 1 ? 5 : atol(argv[ii]);
char * str = to_binary(num);

if (0 == str) return EXIT_FAILURE;
printf ("%lu (decimal) = %s (binary)\n", num, str);
free(str);
ii++;
}
return EXIT_SUCCESS;
}

Nov 14 '05 #1
9 2278

-----Original Message-----
From: bowsayge [mailto:bo****** @nomail.afraid. org]
Posted At: 03 September 2004 09:13
Posted To: c
Conversation: critique: conversion to binary
Subject: critique: conversion to binary
Inspired by fb, Bowsayge decided to write a decimal integer
to binary string converter. Perhaps some of the experienced
C programmers here can critique it. It allocates probably
way too much memory, but it should certainly handle 64-bit
cpus :)

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

char * to_binary (unsigned long value) {
const int maxdata = 100;
char * data = malloc(maxdata+ 1);
int pos = 0;
int pos2 = 0;
if (0 == data) return 0;

if (0 == value) {
return strcpy (data, "0");
}

while (value > 0) {
if (pos >= maxdata) {
printf ("ran out of memory\n");
exit(EXIT_FAILU RE);
}
data [pos++] = '0' + (value & 1);
value >>= 1;
}
data[pos--] = 0;

for (pos2 = 0; pos2 < pos; pos2++, pos--) {
char temp = data[pos];
data[pos] = data[pos2];
data[pos2] = temp;
}

return data;
}

int main (int argc, const char * argv [])
{
int ii = 0;
while (ii < argc) {
unsigned long num = ii < 1 ? 5 : atol(argv[ii]);
char * str = to_binary(num);

if (0 == str) return EXIT_FAILURE;
printf ("%lu (decimal) = %s (binary)\n", num, str);
free(str);
ii++;
}
return EXIT_SUCCESS;
}


The following works OK for me.

#include <stdio.h>
#include <string.h>

void Bin2( char *buffer, long n)
{
buffer--;
*buffer = (char) (n%2+'0');
n=n/2;
if (n)
Bin2(buffer,n);
}
int main (void)
{
char strBin[]="00000000"; // or 16, 32 etc
char *fred = strBin+strlen(s trBin);

Bin2(fred,22);

printf("%s\n",s trBin);

return 0;
}

GST

Nov 14 '05 #2
bowsayge wrote:
Inspired by fb, Bowsayge decided to write a decimal integer
to binary string converter. Perhaps some of the experienced
C programmers here can critique it. It allocates probably
way too much memory, but it should certainly handle 64-bit
cpus :)

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

char * to_binary (unsigned long value) {
const int maxdata = 100;
char * data = malloc(maxdata+ 1);
int pos = 0;
int pos2 = 0;
if (0 == data) return 0;

if (0 == value) {
return strcpy (data, "0");
}

while (value > 0) {
if (pos >= maxdata) {
printf ("ran out of memory\n");
exit(EXIT_FAILU RE);
}
data [pos++] = '0' + (value & 1);
value >>= 1;
}
data[pos--] = 0;

for (pos2 = 0; pos2 < pos; pos2++, pos--) {
char temp = data[pos];
data[pos] = data[pos2];
data[pos2] = temp;
}

return data;
}

int main (int argc, const char * argv [])
{
int ii = 0;
while (ii < argc) {
unsigned long num = ii < 1 ? 5 : atol(argv[ii]);
char * str = to_binary(num);

if (0 == str) return EXIT_FAILURE;
printf ("%lu (decimal) = %s (binary)\n", num, str);
free(str);
ii++;
}
return EXIT_SUCCESS;
}


Do you see the memory leak?

It's also an awful lot of rigamarole - why not just allocate temp[] to write
the bit digits to, then do data[pos++] = temp [pos2--]. You could also stack
them.

Cheers!
Rich

Nov 14 '05 #3
On Fri, 3 Sep 2004, bowsayge wrote:
Inspired by fb, Bowsayge decided to write a decimal integer
to binary string converter. Perhaps some of the experienced
C programmers here can critique it. It allocates probably
way too much memory, but it should certainly handle 64-bit
cpus :)
Gak! K.I.S.S.

The code below is unnecessarily complex. Keep it simple. The fact that
something this simple takes more than 25 lines to do makes it harder to
understand and maintain. A quick glance at this code and I don't
immediately know what you are attempting to do.

Additionally, allocate the amount of memory you need. Using <limits.h> you
should be able to figure out how many bits (char in the array) you need to
represent an unsigned long integer.
#include <stdio.h>
#include <stdlib.h>

char * to_binary (unsigned long value) {
const int maxdata = 100;
Try sizeof(value)*C HAR_BIT/3+1. This will be a little too many bytes but
it is safer than a magic number like 100. What happens if this code goes
into a 64-bit machine and years later gets recompiled on a 128 bit
machine? You are only allocating 100 bits. Even if you allocate 512 bits
you are just delaying the problem. I am sure there where people in the
60's program 7 and 8 bit computers who would never imagine there would be
64 bit computers. So they hard coded things for 50 bits.
char * data = malloc(maxdata+ 1);
int pos = 0;
int pos2 = 0;
if (0 == data) return 0;
Just a style thing, I liked to use NULL == data rather than 0 == data.
if (0 == value) {
return strcpy (data, "0");
}
Why the special case for zero? If you can write the code such that zero is
no different from any other value, do it.
while (value > 0) {
if (pos >= maxdata) {
printf ("ran out of memory\n");
exit(EXIT_FAILU RE);
}
It is good that you have some sort of test for exceeding the 100 bit
limit. Unfortunately, you spent the time allocating 100 bytes and
generating 100 bits of data for nothing. It would have been better for the
code to attempt to allocate the correct amount and fail at the malloc.
Less processing.

Additionally, what happened to freeing the memory you allocated? You have
a memory leak.

Also, style issue. I call a utility program and it exits my entire
application. I would not be happy with that. I would prefer this if
statement free the memory and return a NULL pointer.
data [pos++] = '0' + (value & 1);
value >>= 1;
}
data[pos--] = 0;
You appear to be creating the string backwards.
for (pos2 = 0; pos2 < pos; pos2++, pos--) {
char temp = data[pos];
data[pos] = data[pos2];
data[pos2] = temp;
}
And this loop appears to be correcting the mistake. Did you program the
code without this second loop, see the string was backwards and add the
final for loop to correct the problem? I would have corrected the problem
in the first loop.
return data;
}
I created a solution. It is one if statement to see if the malloc failed,
a for loop with one line in the body to create the string, an assignment
after the for loop to end the string and a return statement. Even with
white space, #include statements and the signature it is 18 lines.
int main (int argc, const char * argv [])
{
int ii = 0;
while (ii < argc) {
unsigned long num = ii < 1 ? 5 : atol(argv[ii]);
char * str = to_binary(num);

if (0 == str) return EXIT_FAILURE;
printf ("%lu (decimal) = %s (binary)\n", num, str);
free(str);
ii++;
}
return EXIT_SUCCESS;
}


Hard to see the code is working with this. Converting from hex to binary
is easy. You might want to print out a hex/binary table. Additionally, why
not just use a for loop and print out 0 to 128 then maybe some boundary
cases. You will see an obvious pattern. If the code is wrong the pattern
will be wrong as well.

--
Send e-mail to: darrell at cs dot toronto dot edu
Don't send e-mail to vi************@ whitehouse.gov
Nov 14 '05 #4
>
char * data = malloc(maxdata+ 1);
int pos = 0;
int pos2 = 0;
if (0 == data) return 0;


Just a style thing, I liked to use NULL == data rather than 0 == data.


Just a style thing: I prefer "data == NULL": What's with this fixation on
writing if statements in reverse, just to catch a typo?
Nov 14 '05 #5
John Smith wrote on 03/09/04 :
if (0 == data) return 0;


Just a style thing, I liked to use NULL == data rather than 0 == data.


Just a style thing: I prefer "data == NULL": What's with this fixation on
writing if statements in reverse, just to catch a typo?


Yes. I'm not found of it, but it can help sometimes.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"

Nov 14 '05 #6
John Smith wrote:
char * data = malloc(maxdata+ 1);
int pos = 0;
int pos2 = 0;
if (0 == data) return 0;


Just a style thing, I liked to use NULL == data rather than 0 == data.


Just a style thing: I prefer "data == NULL": What's with this fixation on
writing if statements in reverse, just to catch a typo?


Just to catch a typo :-)

--
"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
Nov 14 '05 #7
Turner, GS (Geoff) said to us:
The following works OK for me.

void Bin2( char *buffer, long n)

[...]

Yours is a lot more compact. Thanks.

Nov 14 '05 #8
Rich Grise said to us:
bowsayge wrote:
while (ii < argc) {
unsigned long num = ii < 1 ? 5 : atol(argv[ii]);
char * str = to_binary(num);

if (0 == str) return EXIT_FAILURE;
printf ("%lu (decimal) = %s (binary)\n", num, str);
free(str);
ii++;
}
Do you see the memory leak?


No, the "free (str)" above releases the memory.

It's also an awful lot of rigamarole - why not just allocate temp[] to
write the bit digits to, then do data[pos++] = temp [pos2--].
You could also stack them.


Yes! That'll eliminate the need to reverse the string. Thanks.

Nov 14 '05 #9
bowsayge wrote:
Rich Grise said to us:

.... snip ...

It's also an awful lot of rigamarole - why not just allocate
temp[] to write the bit digits to, then do
data[pos++] = temp[pos2--]. You could also stack them.


Yes! That'll eliminate the need to reverse the string. Thanks.


Nothing wrong with reversing strings. A routine to do so is short
and quite efficient, and useful elsewhere. Now that you have
beaten this to death take a look at the following (which I have
published before). Only the first 80 odd lines are generically
useful, the rest is stuff to exercise it and convince oneself that
it works correctly.

/* Routines to display values in various bases */
/* with some useful helper routines. */
/* by C.B. Falconer, 19 Sept. 2001 */
/* Released to public domain. Attribution appreciated */

#include <stdio.h>
#include <string.h>
#include <limits.h> /* ULONG_MAX etc. */

/* =============== ======== */
/* reverse string in place */
size_t revstring(char *stg)
{
char *last, temp;
size_t lgh;

lgh = strlen(stg);
if (lgh > 1) {
last = stg + lgh; /* points to '\0' */
while (last-- > stg) {
temp = *stg; *stg++ = *last; *last = temp;
}
}
return lgh;
} /* revstring */

/* =============== =============== ============== */
/* Mask and convert digit to hex representation */
/* Output range is 0..9 and a..f only */
int hexify(unsigned int value)
{
static char hexchars[] = "0123456789abcd ef";

return (hexchars[value & 0xf]);
} /* hexify */

/* =============== =============== =============== ===== */
/* convert unsigned number to string in various bases */
/* 2 <= base <= 16, controlled by hexify() */
/* Returns actual output string length */
size_t basedisplay(uns igned long number, unsigned int base,
char *stg, size_t maxlgh)
{
char *s;

/* assert (stg[maxlgh]) is valid storage */
s = stg;
if (maxlgh && base)
do {
*s = hexify(number % base);
s++;
} while (--maxlgh && (number = number / base) );
*s = '\0';
revstring(stg);
return (s - stg);
} /* basedisplay */

/* =============== =============== =============== === */
/* convert signed number to string in various bases */
/* 2 <= base <= 16, controlled by hexify() */
/* Returns actual output string length */
size_t signbasedisplay (long number, unsigned int base,
char * stg, size_t maxlgh)
{
char *s;
size_t lgh;
unsigned long n;

s = stg; lgh = 0;
n = (unsigned long)number;
if (maxlgh && (number < 0L)) {
*s++ = '-';
maxlgh--;
n = -(unsigned long)number;
lgh = 1;
}
lgh = lgh + basedisplay(n, base, s, maxlgh);
return lgh;
} /* signbaseddispla y */
/* =============== ===== */
/* flush to end-of-line */
int flushln(FILE *f)
{
int ch;

while ('\n' != (ch = fgetc(f)) && (EOF != ch)) /* more */;
return ch;
} /* flushln */

/* ========== END of generically useful routines ============ */

/* =============== ========== */
/* Prompt and await <return> */
static void nexttest(char *prompt)
{
static char empty[] = "";

if (NULL == prompt) prompt = empty;
printf("\nHit return for next test: %s", prompt);
fflush(stdout);
flushln(stdin);
} /* nexttest */

/* =============== =============== */
/* Display a value and its length */
static void show(char *caption, int sz, char *stg)
{

if ((unsigned)sz != strlen(stg))
printf("Somethi ng is wrong with the sz value\n");
printf("%s: sz = %2d \"%s\"\n", caption, sz, stg);
} /* show */

/* =========== */
/* exercise it */
int main(void)
{
#define LGH 40
#define VALUE 1234567890

char stg[LGH];
unsigned int base;
int sz;

printf("\nExerc ising basedisplay routine\n");
printf("\nbase sz value\n");
for (base = 2; base <= 16; base++) {
sz = (int)basedispla y(VALUE, base, stg, LGH - 1);
printf("%2d %2d %s\n", base, sz, stg);
}

nexttest("ULONG _MAX");
for (base = 8; base <= 16; base++) {
sz = (int)basedispla y(ULONG_MAX, base, stg, LGH - 1);
printf("%2d %2d %s\n", base, sz, stg);
}

basedisplay(0, 10, stg, 3);
printf("\nzero %s\n", stg);

basedisplay(VAL UE, 10, stg, 3);
printf("3 lsdigits only, base 10 %s\n", stg);

printf("\nBad calls:\n");

sz = (int)basedispla y(VALUE, 10, stg, 0);
show("0 length field", sz, stg);

sz = (int)basedispla y(VALUE, 1, stg, 20);
show("base 1, lgh 20", sz, stg);

sz = (int)basedispla y(VALUE, 0, stg, 20);
show("base 0, lgh 20", sz, stg);

sz = (int)signbasedi splay(-1234, 10, stg, 0);
show("0 lgh fld, -ve", sz, stg);

sz = (int)signbasedi splay(-1234, 10, stg, 2);
show("truncate -1234", sz, stg);

nexttest("Syste m limits");

sz = (int)signbasedi splay(SCHAR_MIN , 10, stg, 20);
show("SCHAR_MIN ", sz, stg);

sz = (int)signbasedi splay(SCHAR_MAX , 10, stg, 20);
show("SCHAR_MAX ", sz, stg);

sz = (int)signbasedi splay(UCHAR_MAX , 10, stg, 20);
show("UCHAR_MAX ", sz, stg);

sz = (int)signbasedi splay(CHAR_MIN, 10, stg, 20);
show("CHAR_MIN ", sz, stg);

sz = (int)signbasedi splay(CHAR_MAX, 10, stg, 20);
show("CHAR_MAX ", sz, stg);

sz = (int)signbasedi splay(MB_LEN_MA X, 10, stg, 20);
show("MB_LEN_MA X ", sz, stg);

sz = (int)signbasedi splay(SHRT_MIN, 10, stg, 20);
show("SHRT_MIN ", sz, stg);

sz = (int)signbasedi splay(SHRT_MAX, 10, stg, 20);
show("SHRT_MAX ", sz, stg);

sz = (int)signbasedi splay(USHRT_MAX , 10, stg, 20);
show("USHRT_MAX ", sz, stg);

sz = (int)signbasedi splay(INT_MIN, 10, stg, 20);
show("INT_MIN ", sz, stg);

sz = (int)signbasedi splay(INT_MAX, 10, stg, 20);
show("INT_MAX ", sz, stg);

sz = (int)signbasedi splay(INT_MAX, 10, stg, 20);
show("INT_MAX ", sz, stg);

sz = (int) basedisplay(UIN T_MAX, 10, stg, 20);
show("UINT_MAX ", sz, stg);

sz = (int)signbasedi splay(LONG_MIN, 10, stg, 20);
show("LONG_MIN ", sz, stg);

sz = (int)signbasedi splay(LONG_MAX, 10, stg, 20);
show("LONG_MAX ", sz, stg);

sz = (int) basedisplay(ULO NG_MAX, 10, stg, 20);
show("ULONG_MAX ", sz, stg);

nexttest("DONE" );
return 0;
} /* main */

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
2382
by: Aakash Bordia | last post by:
Hello, Does anybody know what is the documented and known behavior of inserting/updating binary columns using host variables from a client to a server which have different code pages? Will any code page / character set conversion take place? I am particulary interested in insert/update from subqueries. eg: insert into t1(binarycol) select :HV1 from t2 versus
6
1418
by: Gernot Frisch | last post by:
template <class flt> void write(FILE* pF, const flt& f) { // this will definitely _not_ write // an x-platfrom binary file fwrite(&f, sizeof(f), 1, pF); } int main() {
4
2657
by: Ken Tough | last post by:
Seems like a simple thing to find out, but I'm struggling. I have googled, but everything I find is about implicit conversion, not explicit. Is this implementation-specific, or does ANSI/ISO lay out what should happen for: -------------------------- signed char sc; unsigned char uc;
16
5125
by: TTroy | last post by:
Hello, I'm relatively new to C and have gone through more than 4 books on it. None mentioned anything about integral promotion, arithmetic conversion, value preserving and unsigned preserving. And K&R2 mentions "signed extension" everywhere. Reading some old clc posts, I've beginning to realize that these books are over-generalizing the topic. I am just wondering what the difference between the following pairs of terms are: 1)...
188
7176
by: christopher diggins | last post by:
I have posted a C# critique at http://www.heron-language.com/c-sharp-critique.html. To summarize I bring up the following issues : - unsafe code - attributes - garbage collection - non-deterministic destructors - Objects can't exist on the stack - Type / Reference Types
3
17894
by: Amjad | last post by:
Hi, Are there any built-in methods in VB.NET that convert one number in one format to its equivalent in another format? For example I want to convert the number 162 (decimal) to 10100010 (binary) or to A2 (hexadecimal) and vice versa. Thanks.
4
5534
by: Russell Warren | last post by:
I've got a case where I want to convert binary blocks of data (various ctypes objects) to base64 strings. The conversion calls in the base64 module expect strings as input, so right now I'm converting the binary blocks to strings first, then converting the resulting string to base64. This seems highly inefficient and I'd like to just go straight from binary to a base64 string. Here is the conversion we're using from object to...
7
19216
by: elliotng.ee | last post by:
I have a text file that contains a header 32-bit binary. For example, the text file could be: %%This is the input text %%test.txt Date: Tue Dec 26 14:03:35 2006 00000000000000001111111111111111 11111111111111111111111111111111 00000000000000000000000000000000 11111111111111110000000000000000
15
85773
by: David Marsh | last post by:
I accidentally typed %b instead of %d in a printf format string and got a binary representation of the number. Is that standard C or a compiler extension?
0
8616
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
9112
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8971
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8815
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5826
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4569
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2994
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2251
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
1970
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.