簡體   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