My implementation of a binary-to-bits converting function:
#include <stdio.h>
#include <limits.h>
unsigned char *return_byte (unsigned char source)
{
static unsigned char byte[CHAR_BIT];
unsigned char *p = byte, i;
for(i = 0; i < CHAR_BIT; i++)
p[i] = '0' + ((source & (1 << i)) > 0);
return p;
}
int main(void)
{
unsigned char val = 200;
printf("Value:\t%i\nBinary:\t%s", val, return_byte(val));
return 0;
}
Output:
Value: 200 Binary: 00010011
-
\$\begingroup\$ I just received an idea for optimization. Make the function understands of endians. But I will leave this to the reviewers. \$\endgroup\$Genis– Genis2015年02月22日 22:18:35 +00:00Commented Feb 22, 2015 at 22:18
-
2\$\begingroup\$ You could provide a self-review. \$\endgroup\$user34073– user340732015年02月22日 22:22:14 +00:00Commented Feb 22, 2015 at 22:22
-
\$\begingroup\$ Can I actually do that? \$\endgroup\$Genis– Genis2015年02月22日 22:34:36 +00:00Commented Feb 22, 2015 at 22:34
-
1\$\begingroup\$ Yes, you can - especially if it dramatically improves the code. \$\endgroup\$user34073– user340732015年02月22日 22:35:11 +00:00Commented Feb 22, 2015 at 22:35
-
\$\begingroup\$ Your output is (of course) little-endian. That's not the conventional way to write numbers. We usually write big-endian style even in non-decimal bases. 200 is 'two hundred' not 'two'. I would normally read binary '00010011' as nineteen (decimal). \$\endgroup\$user59064– user590642015年02月23日 14:06:59 +00:00Commented Feb 23, 2015 at 14:06
1 Answer 1
return_byte
doesn't tell much what the function is intended to do.btoa
would be more in line with C naming convention (akin toitoa
)A
p
variable is pretty much useless. Considerstatic unsigned char byte[CHAR_BIT]; unsigned char i; for(i = 0; i < CHAR_BIT; i++) byte[i] = '0' + ((source & (1 << i)) > 0); return byte;
Using an
unsigned char
for indexing is questionable. In any case it doesn't buy you much against a nativeint
.A boolean expression as
+
operand may raise some eyebrows (true
is guaranteed to be a non-zero in an arithmetic context, but it is not guaranteed to be 1). I recommend to force an arithmetic value by right-shiftingsource
instead of left-shifting the mask:for(i = 0; i < CHAR_BIT; i++) { byte[i] = '0' + (source & 1); source >>= 1; }
You do not null-terminate the resulting string. The fact that your test succeeded is a sheer (un)luck.
You probably know that returning static makes the code non-reentrant and thread-unsafe. You may want to let client provide a space for a resulting string.
-
\$\begingroup\$ I don´t think I need to null-terminated with the use of
static
, which will automatically enzero all the bytes. Everything other than that seems fairly legal. \$\endgroup\$Genis– Genis2015年02月22日 23:02:20 +00:00Commented Feb 22, 2015 at 23:02 -
\$\begingroup\$ It will "enzero" CHAR_BIT bytes (and we will overwrite them at the very first call anywhay). What happens with the next byte beyond the array (where a terminator is to be expected), which is not under your control? \$\endgroup\$vnp– vnp2015年02月22日 23:13:55 +00:00Commented Feb 22, 2015 at 23:13
-
\$\begingroup\$ It will be NULL, because
static
in most modern compilers ensures the buddy-memory fragments too. Make a test, but with gcc compiler and with std=c99 \$\endgroup\$Genis– Genis2015年02月22日 23:25:58 +00:00Commented Feb 22, 2015 at 23:25 -
\$\begingroup\$ As I said, it will be NULL until somebody else (who claimed that byte) wrote something there. \$\endgroup\$vnp– vnp2015年02月22日 23:41:04 +00:00Commented Feb 22, 2015 at 23:41
-
\$\begingroup\$ Yes.. true that true. \$\endgroup\$Genis– Genis2015年02月22日 23:45:09 +00:00Commented Feb 22, 2015 at 23:45