繁体   English   中英

浮点数的打印位不起作用,你能解释一下为什么吗?

[英]Print bits of float number does not work, can you explain me why?

我想打印浮点数的位。

我的计划是:

  • 发现有多少位
  • 创建 int 数组并使用简单的右位移将数字的位插入其中。
  • 因为这些位的插入顺序与我需要的相反,所以让我们再次运行另一个循环到 go 在数组上,但这次是从最后一个元素到第一个元素。

为什么

让我们以数字 4.2 为例:我相信这些位是按以下方式输入的:

4 - 1000

2 - 0010

所以加起来是10000010。

进入 FILO - 先进 -> 后出。 所以 0 将是第一个元素,但正如你在这里看到的,我们最终需要它。

这是我的代码:

float FloatAnalysis(float number)
{
    int arr[32] = {0};
    float num_cpy = number;
    size_t num_of_bits = 0, i = 0;
    
    while (0 != number)
    {
        num_cpy >>= 1;
        ++num_of_bits;
    }
    
    num_cpy = number;
    
    for(i = 0; i < num_of_bits; ++i)
    {
    
        arr[i] = (num_cpy & 1);
        num_cpy >>= 1;
    
    }
    
    
    for(i = num_of_bits-1; i => 0; --i)
    {
    
        printf("%d", arr[i]);
    
    }
    
}

这里是 output:

bitwise.c:359:11: error: invalid operands to binary >> (have ‘float’ and ‘int’)
  359 |   num_cpy >>= 1;
      |           ^~~
bitwise.c:368:21: error: invalid operands to binary & (have ‘float’ and ‘int’)
  368 |   arr[i] = (num_cpy & 1);
      |                     ^
bitwise.c:369:11: error: invalid operands to binary >> (have ‘float’ and ‘int’)
  369 |   num_cpy >>= 1;
      |           ^~~

Can you expl

在我这里发生了什么事?

使用内存

您不能对浮点数执行按位运算。

您可以使用 memcpy 将float复制到unsigned int并保留其位:

float num_cpy = number;

变成

unsigned int num_cpy;
memcpy(&num_cpy, &number, sizeof(unsigned)); 

请注意,如果您尝试转换结果,请通过在 memory 中获取您的浮点地址并将其转换为无符号,使用:

num_cpy = *(float *)&number; 

您将去除浮点部分,您将保留该值(或可以保留的值),但会降低其二进制表示的准确性。


例子

在下面的示例中,

float number = 42.42;
unsigned int num_cpy;
memcpy(&num_cpy, &number, sizeof(unsigned)); 
unsigned int num_cpy2 = *(float *)&number;
printf("Bits in num_cpy: %d    bits in num_cpy2: %d\n", __builtin_popcount(num_cpy), __builtin_popcount(num_cpy2));
printf("%d\n", num_cpy);
printf("%d\n", num_cpy2);

将 output

Bits in num_cpy: 12    bits in num_cpy2: 3
1110027796 // memcpy
42 // cast

更多阅读

我建议您特别看一下浮点内部表示,它很好地总结了位级别的情况。

内部表示:符号:1 位,指数:8 位,小数:23 位
(对于单精度 32 位浮点,我们在 C 中称为 float)

除了编译器错误之外,OP 的代码还有各种问题。

i => 0不是正确的代码。 也许 OP 想要i >= 0 即使那样也有麻烦。

size_t num_of_bits = 0, i = 0;
...
//  Bug: i => 0 is always true as `i` is an unsigned type.
for(i = num_of_bits-1; i >= 0; --i)  {
    printf("%d", arr[i]);
}

OP的修复代码。

float FloatAnalysis(float number) {
  assert(sizeof(float) == sizeof(unsigned));
  int arr[32] = {0};

  //float num_cpy = number;
  unsigned num_cpy;
  memcpy(&num_cpy, &number, sizeof num_cpy);  // copy the bit pattern to an unsigned

  // size_t num_of_bits = 0, i = 0;
  size_t num_of_bits = 32, i = 0;  // Always print 32 bits

  //while (0 != number) {
  //  num_cpy >>= 1;
  //  ++num_of_bits;
  //}
  //num_cpy = number;

  for (i = 0; i < num_of_bits; ++i) {
    arr[i] = (num_cpy & 1);
    num_cpy >>= 1;
  }

  // for(i = num_of_bits-1; i => 0; --i)
  for (i = num_of_bits; i-- > 0; ) { // Change test condition
    printf("%d", arr[i]);
  }
  printf("\n");

  // Some more output
  //      12345678901234567890123456789012
  printf("sEeeeeeeeMmmmmmmmmmmmmmmmmmmmmmm\n");
  printf("%a\n", number);
  return number;
}

int main() {
  FloatAnalysis(4.2f);
}

Output

01000000100001100110011001100110
sEeeeeeeeMmmmmmmmmmmmmmmmmmmmmmm
0x1.0cccccp+2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM