1

For a char or int, I can do this:

void print2(char c)//print char c in binary
{
    for(int i=7;i>=0;i--)
        if ((1<<i)&c) printf("1");
        else printf("0");
}

But for double I can't use operator &.

And I can't use reinterpret_cast(It's C++).

Then, How to do that?

Sayakiss
  • 6,878
  • 8
  • 61
  • 107
  • 8
    `memcpy` it to a `unsigned char[sizeof (double)]`. – Daniel Fischer May 09 '13 at 10:47
  • memcpy? I never knew it. Sounds interesting. @DanielFischer Thanks. – Buddha May 09 '13 at 10:56
  • Oh wait, I think I've misinterpreted "And I can't use reinterpret_cast(It's C++).". You're working in C, then using a union is simpler (less code) than `memcpy`. If you can `assert(sizeof (double) == sizeof(uint64_t))`, I'd suggest a `union pun { double d; uint64_t u; };`, otherwise using an `unsigned char[sizeof (double)]` in the union would be an option. – Daniel Fischer May 09 '13 at 11:02
  • @DanielFischer Plus: you would need to add an `assert (sizeof(double) == sizeof(unsigned long long))` somehere. IMHO the memcpy to char[sizeof(double)] is more flexible wrt portability. (especially if stdint.h is not available) – wildplasser May 09 '13 at 11:14

4 Answers4

2

A solution with union rather than memcpy or pointer:

void print2(double x)//print double x in binary
{
    union {
        double x;
        char c[sizeof(double)];
    } u;

    assert(sizeof(char) == 1);

    u.x = x;

    for (unsigned ofs = 0; ofs < sizeof(double); ofs++) {
        for(int i = 7; i >= 0; i--) {
            printf(((1 << i) & u.c[ofs]) ? "1" : "0");
        }
        printf(" ");
    }
}
Axel Kemper
  • 10,544
  • 2
  • 31
  • 54
1

Create char pointer and make it point to this double. Print first sizeof(double) chars using your function.

stralep
  • 858
  • 8
  • 16
1

Presuming a double has 64 bits, this reinterprets the bytes of a double x as an unsigned 64-bit integer:

(union { double d; uint64_t u; }) {x} .u;

This is legal C, with the bytes of the double being implementation-dependent. It defines a compound literal that is a union, initializes the union with the double, and accesses the uint64_t member. The C standard says that when a member other than the last-stored member is accessed, the bytes are reinterpreted as the new type.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
1

Naive implementation with memcpy(), as per @Daniel Fischer's comment:

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

void double_to_bits(double val);

int main(void)
{
unsigned idx;

double vals[] = { -1.0, 0.0, 1.0, 2.0 };

for (idx = 0; idx < 4; idx++ ) {
        printf("\nvals[%u]= %+lf-->>", idx, vals[idx] );
        double_to_bits(vals[idx] );
        }
printf("\n");

return 0;
}

void double_to_bits(double val)
{
unsigned idx;
unsigned char arr[sizeof val];

memcpy (arr, &val, sizeof val);

for (idx=CHAR_BIT * sizeof val; idx-- ; ) {
        putc(
        ( arr[idx/CHAR_BIT] & (1u << (idx%CHAR_BIT) ) )
        ? '1'
        : '0'
        , stdout
        );
        }
}

, and the same with a pointer (omitting the char array and the memcpy)

void double_to_bits2(double val)
{
unsigned idx;
unsigned char *ptr = (unsigned char*) &val;

for (idx=CHAR_BIT * sizeof val; idx-- ; ) {
        putc(
        ( ptr[idx/CHAR_BIT] & (1u << (idx%CHAR_BIT) ) )
        ? '1'
        : '0'
        , stdout
        );
        }
}
wildplasser
  • 43,142
  • 8
  • 66
  • 109