对于 char 或 int,我可以这样做:
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");
}
但是对于 double 我不能使用运算符 &。
而且我不能使用 reinterpret_cast(它是 C++)。
那么,该怎么做呢?
对于 char 或 int,我可以这样做:
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");
}
但是对于 double 我不能使用运算符 &。
而且我不能使用 reinterpret_cast(它是 C++)。
那么,该怎么做呢?
memcpy()
根据@Daniel Fischer 的评论,使用 的幼稚实现:
#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
);
}
}
, 与指针相同(省略 char 数组和 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
);
}
}
假设 adouble
有 64 位,这会将 a 的字节重新解释double x
为无符号 64 位整数:
(union { double d; uint64_t u; }) {x} .u;
这是合法的 C,其字节double
取决于实现。它定义了一个复合文字,它是一个联合,用 初始化联合double
,并访问该uint64_t
成员。C 标准规定,当访问最后存储的成员以外的成员时,字节将被重新解释为新类型。
创建 char 指针并使其指向这个双精度。使用您的函数打印第一个 sizeof(double) 字符。
使用union
而不是memcpy
或的解决方案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(" ");
}
}