Alternatively, you could use the ternary operator:
retval[j] = (a & mask) ? '1' : '0';
A slightly briefer and trickier way would be:
retval[j] = '1' - !(a & mask);
Finally, you might consider getting rid of `mask':
instead of shifting it successively to the left, consider
shifting `a' rightward so the bits slide successively into
the ones' place. Then you could write
retval[j] = '0' + (a & 1);
This last suggestion has a flaw: right-shifting a negative
value gives an implementation-defined result. But you've
already chosen to ignore what happens when you try to store
the value 128 in `mask' (whose maximum is only 127), so I
suspect you'd be willing to take your chances on the shift,
too.
Thanks for all the cool tips and suggestions. Since you mentioned if I
was interested only in the values up to 2^n-1, this is what I was
trying to do.I was trying to understand the bigger problem, i.e., how
different architectures interpret the bytes internally. I was trying
to understand how a 32 bit float stores a number say 3.1422357234
internally in its 32 bits, and thats why I wrote this program. I
wanted to understand how positive and negative (2s complement) are
stored internally. Following is my code.
I hate to post this much amount of code but I want to get suggestions
on how to write better code, and if there are any obvious mistakes in
the programs that would give me incorrect results and hence my
understanding about these issues wouldn't be correct.
#include<stdio.h>
#include<inttypes.h>
#include<stdlib.h>
#include<string.h>
#define CHAR_BIT 8
void print8bits(int8_t a){
int8_t mask = 1;
char retval[] = "00000000\0";
int i, j = sizeof(a)* CHAR_BIT -1;
for(i = 0; i < sizeof(int8_t) * CHAR_BIT; i++)
{
if (a & mask)
retval[j] = '1';
mask = mask << 1;
j--;
}
printf("Printing 8 bit integer = %s, %d\n", retval, a);
}
char *print8bitsW(int8_t a){
int8_t mask = 1;
char *retval = malloc(9);
memcpy(retval, "00000000\0", strlen("00000000\0"));
int i, j = sizeof(a)* CHAR_BIT -1;
for(i = 0; i < sizeof(int8_t) * CHAR_BIT; i++)
{
if (a & mask)
retval[j] = '1';
mask = mask << 1;
j--;
}
printf("Printing 8 bit integer = %s, %d\n", retval, a);
return retval;
}
void print16bits(int16_t a){
int16_t mask = 1;
char retval[] = "0000000000000000\0";
int i, j = sizeof(a) * CHAR_BIT - 1;
for(i = 0; i < sizeof(a) * CHAR_BIT; i++)
{
if (a & mask)
retval[j] = '1';
mask = mask << 1;
j--;
}
printf("Printing 16 bit integer = %s, %d\n", retval, a);
}
void print32bits(int32_t a){
int32_t mask = 1;
char retval[] = "00000000000000000000000000000000\0";
int i, j = sizeof(a) * CHAR_BIT - 1;
for(i = 0; i < sizeof(a) * CHAR_BIT; i++)
{
if (a & mask)
retval[j] = '1';
mask = mask << 1;
j--;
}
printf("Printing 32 bit integer = %s, %d\n", retval, a);
}
void printfloat(float a){
int32_t mask = 1;
char retval[] = "00000000000000000000000000000000\0";
int i, j = sizeof(a) * CHAR_BIT - 1;
uint32_t *p = (uint32_t *) &a;
for(i = 0; i < sizeof(a) * CHAR_BIT; i++)
{
if (*p & mask)
retval[j] = '1';
mask = mask << 1;
j--;
}
printf("Printing 32 bit float = %s, %f\n", retval, a);
}
void printdouble(double a){
int32_t mask;
char retval[] =
"0000000000000000000000000000000000000000000000000000000000000000\0";
int i, j = sizeof(a) * CHAR_BIT - 1, k;
uint32_t *p = (uint32_t *) &a;
/*
* p now points to the last 32 bit of the 96 bits. After each
* iteration we consider the lower 32 bits. For example, in first
* iteration we consider bbits from 95 to 64, then 63 to 32 and
* finally 31 to 0.
*/
p += (sizeof(a)/sizeof(mask))-1;
for (k = 0; k < (sizeof(a)/sizeof(mask)); k++){
p = p - k;
mask = 1;
for(i = 0; i < sizeof(mask) * CHAR_BIT; i++)
{
if (*p & mask)
retval[j] = '1';
mask = mask << 1;
j--;
}
}
printf("Printing 64 bit doble = %s, %lf\n", retval, a);
}
void printlongdouble(long double a){
int32_t mask;
char retval[] =
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\0";
int i, j = sizeof(a) * CHAR_BIT - 1, k;
uint32_t *p = (uint32_t *) &a;
/*
* p now points to the last 32 bit of the 96 bits. After each
* iteration we consider the lower 32 bits. For example, in first
* iteration we consider bbits from 95 to 64, then 63 to 32 and
* finally 31 to 0.
*/
p += (sizeof(a)/sizeof(mask))-1;
for (k = 0; k < (sizeof(a)/sizeof(mask)); k++){
p = p - k;
mask = 1;
for(i = 0; i < sizeof(mask) * CHAR_BIT; i++)
{
if (*p & mask)
retval[j] = '1';
mask = mask << 1;
j--;
}
}
printf("Printing 96 bit long doble = %s, %Lf\n", retval, a);
}
void printlong(long a){
long mask = 1;
char retval[] = "00000000000000000000000000000000\0";
int i, j = sizeof(a) * CHAR_BIT - 1;
for(i = 0; i < sizeof(a) * CHAR_BIT; i++)
{
if (a & mask)
retval[j] = '1';
mask = mask << 1;
j--;
}
printf("Printing 32 bit long = %s, %ld\n", retval, a);
}
void printlonglong(long long a){
long long mask = 1;
char retval[] =
"0000000000000000000000000000000000000000000000000000000000000000\0";
int i, j = sizeof(a) * CHAR_BIT - 1;
for(i = 0; i < sizeof(a) * CHAR_BIT; i++)
{
if (a & mask)
retval[j] = '1';
mask = mask << 1;
j--;
}
printf("Printing 64 bit long long = %s, %lld\n", retval, a);
}
int main()
{
print8bits(5);
print8bits(-5);
print16bits(123);
print16bits(-123);
print32bits(27345234);
print32bits(-27345234);
printfloat(3.14);
printfloat(-3.14);
printfloat(1265654.3414);
printfloat(-1265654.3414);
printlong(1234126534);
printlong(-1234126534);
printdouble(423432.42342342);
printdouble(-423432.42342342);
printlonglong(-65656361);
printlonglong(65656361);
printlongdouble(-1765347347537.234234234);
printlongdouble(1765347347537.234234234);
return 0;
}
I don't expect you to browse the whole code but if you could point out
any obvious mistakes, that would be great.
Thanks to all of you for your replies.
Daniel