The obvious portability problem is that we have b[i^SIZE-1]
where I'd expect b[SIZE-1-i]
. That looks like an error of judgement: it produces the same results when SIZE
is an exact power of 2, but not otherwise.
Instead of the SIZE
preprocessor macro, I'd probably use a constant within the function:
static const size_t length = sizeof n * CHAR_BIT;
If you do stick with the macro, consider #undef SIZE
afterwards so it's available to other code.
As a style issue, I don't like the for
loop with empty body on the same line. That looks more like code-golf than something that's intended to be readable - especially with the "work" of the loop stuffed into the control expression.
We really want the cast to char
to happen to the sum, since char
+char
yields int
. That said, gcc -pedantic -Wconversion
doesn't complain without it.
I would write the character constant 0
as '\0'
to better convey the intent. That's especially important as we have '0'
close by.
You might find it easier, clearer and more efficient to work backwards from the least-significant bit:
int putb(unsigned long long n)
{
char b[(sizeof n * CHAR_BIT) + 1];
char *p = b + sizeof b;
*--p = '\0';
for (; p-- > b; n >>= 1) {
*p = '0' + (char)(n & 1);
}
return puts(b);
}
This gives the option of a version that doesn't print leading zeros (and therefore modified to accept any size integer):
#include <stdint.h>
int putb(uintmax_t n)
{
char b[(sizeof n * CHAR_BIT) + 1];
char *p = b + sizeof b;
*--p = '\0';
do {
*--p = '0' + (n & 1);
} while (n >>= 1);
return puts(p);
}
This one is trivially modified to add a 0b
prefix, should that be desired.