简体   繁体   English

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

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

I want to print the bits of a float number.我想打印浮点数的位。

My plan was to:我的计划是:

  • Discover how many bits there are at all发现有多少位
  • Create and int array and insert into it the bits of the number using simple right bits shifting.创建 int 数组并使用简单的右位移将数字的位插入其中。
  • Because the bits were inserted in a reversed order to what I need, lets run another loop to go over the array one again but this time, from the last element to the first one.因为这些位的插入顺序与我需要的相反,所以让我们再次运行另一个循环到 go 在数组上,但这次是从最后一个元素到第一个元素。

Why ?为什么

Lets take for example the number 4.2: I believe the bits were entered in the following way:让我们以数字 4.2 为例:我相信这些位是按以下方式输入的:

4 - 1000 4 - 1000

2 - 0010 2 - 0010

So together it's 10000010.所以加起来是10000010。

Enters FILO - First in -> Last out.进入 FILO - 先进 -> 后出。 So 0 will be the first element but as you cans see here, we need it in the end.所以 0 将是第一个元素,但正如你在这里看到的,我们最终需要它。

Here is my code:这是我的代码:

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]);
    
    }
    
}

And here the output:这里是 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

ain me what is going on here?在我这里发生了什么事?

Use memcpy使用内存

You cannot perform bitwise operations on a float.您不能对浮点数执行按位运算。

You can use memcpy to copy your float to an unsigned int and preserves its bits:您可以使用 memcpy 将float复制到unsigned int并保留其位:

float num_cpy = number;

becomes变成

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

Note that if you try to cast the result, by taking your float address in memory and cast it as unsigned, with:请注意,如果您尝试转换结果,请通过在 memory 中获取您的浮点地址并将其转换为无符号,使用:

num_cpy = *(float *)&number; 

You will strip the floating point part away, you will preserve the value (or what can be preserved) but loose the accuracy of its binary representation.您将去除浮点部分,您将保留该值(或可以保留的值),但会降低其二进制表示的准确性。


Example例子

In the below example,在下面的示例中,

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);

will output将 output

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

More reading更多阅读

I recommend that you especially take a look at floating point internal representation that sums up very well what is going at the bits level.我建议您特别看一下浮点内部表示,它很好地总结了位级别的情况。

Internal Representation: sign: 1 bit, exponent: 8 bits, fraction: 23 bits内部表示:符号:1 位,指数:8 位,小数:23 位
(for a single precision, 32 bits floating point, that we call float in C) (对于单精度 32 位浮点,我们在 C 中称为 float)

OP's code has various problems aside from compiler error.除了编译器错误之外,OP 的代码还有各种问题。

i => 0 is not proprer code. i => 0不是正确的代码。 Perhaps OP wanted i >= 0 ?.也许 OP 想要i >= 0 Even that has trouble.即使那样也有麻烦。

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's repaired code. 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 Output

01000000100001100110011001100110
sEeeeeeeeMmmmmmmmmmmmmmmmmmmmmmm
0x1.0cccccp+2

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

相关问题 Dafny:验证最简单的数组求和是行不通的。 有人可以向我解释为什么吗? - Dafny: Verification of the most simple array summation does not work. Can somebody explain me why? 任何人都可以解释为什么这不起作用? - Can anyone explain why this does not work? 有人可以向我解释这段代码是如何工作的吗? - Can someone explain to me how does this code work? 谁能解释一下这个特定的print语句在for循环中做了什么? - Can anyone explain me what does this particular print statement do in for loop? 你能解释一下为什么这段代码有这个 output 吗? - Can you explain why this code has this output? 你能解释一下JS代码吗? 它是如何工作的? - Can you explain me the JS code ? How its working? 有人可以解释为什么这种迭代嵌套数据结构的方式有效吗? - Can someone explain why this way of iterating a nested data structure does work? 谁能向我解释为什么这个JavaScript Promise“管道”不保留我推入的数组,但是起始索引却保留了? - Can anyone explain to me why this JavaScript Promise “pipeline” doesn't retain the array I push in…but the start index does? 有人可以向我解释此代码吗? - Can anybody explain me this code? 有人可以向我解释为什么这个循环不能给我想要的结果吗? - Can someone explain to me why this loop doesn't give me the desired result?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM