2017-02-23 78 views
-1

所以在char *中有一個可以用16位表示的帶符號的十進制數。我想在2s恭維二進制文件中有一個char *。所以我想在C中從「-42」到「1111111111010110」(注意顯示所有16位)。有沒有一種快速和骯髒的方法來做到這一點?有些庫函數可能嗎?或者我必須自己開始一個大型的功能來做到這一點?有符號二進制數字char * of 2s恭維二進制表示的char * *?

我知道strtol()可能有一定用處。

+0

我想printf有一個二進制說明符。 –

+0

strtol將幫助你將'-42'變成int 42,但是你需要自己編寫int-> binary,因爲[\ * printf不支持二進制輸出格式](http://stackoverflow.com/questions/ 111928/is-a-printf-converter-to-print-in-binary-format) –

+2

[SO搜索以前的問題](http://stackoverflow.com/search?q=%5Bc%5D+convert+整數+到+二進制) – Barmar

回答

-2

不幸的是,printf支持二進制表示。你可以使用下面的函數來創建此數組:

void decStrToBinStr(char* decStr, char* binStr); 
    unsigned long n = strtol(decStr, NULL, 10); 
    int i = 15; 
    while (i>=0) { 
     if (n & 1) 
      binStr[i] = '1'; 
     else 
      binStr[i] = '0'; 

     n >>= 1; 
     --i; 
    } 
} 
+0

@DavidBowling我將值更改爲無符號,以便它始終是邏輯移位,但在這種情況下,如果將它留作簽名長,則它不重要。移位是算術還是邏輯不影響所使用的位。 –

+0

@DavidBowling我修復了一個變量名並將ulong恢復爲長整型後編譯並運行它。沒有使用-werror或其他選項的GCC,仍然會編譯包含實現定義或未定義行爲的代碼。這是我有任何經驗的唯一C編譯器。在這兩種情況下,程序都會輸出預期的字符串「1111111111010110」和「0000000000000000」 儘管如此,使其未經簽名顯然是一個好主意。謝謝。 –

0

沒有一個標準庫函數,你描述可以生成二進制字符串。

然而這並不是特別困難。

#include <stdio.h> 
#include <stdint.h> 
#include <ctype.h> 

int main(int argc, char ** argv) 
{ 
    while(--argc >= 0 && ++argv && *argv){ 
     char const * input = *argv; 
     if(! input) 
      continue; 

     uint32_t value = 0; 
     char negative = 0; 
     for(; *input; input++){ 
      if (isdigit(*input)) 
       value = value * 10 + (*input -'0'); 
      else if (*input == '-' && value == 0) 
       negative = 1; 
      else { 
       printf("Error: unexpected character: %c at %d\n", *input, (int)(input - *argv)); 
       continue; // this function doesn't handle floats, or hex 
      } 
     } 

     if (value > 0x7fff + negative){ 
      printf("Error: value too large for 16bit integer: %d %x\n", value, value); 
      continue; // can't be represented in 16 bits 
     } 

     int16_t result = value; 
     if (negative) 
      result = -value; 

     for (int i=1; i <= 16; i++) 
      printf("%d", 0 != (result & 1 << (16-i))); 

     printf("\n"); 
    } 
} 

該函數處理所有有效的16個值,並利用一個事實,即架構中存儲整數的補值。我沒有意識到架構沒有,所以這是一個相當合理的假設。

請注意,二進制補碼INT_MIN!= -1 * INT_MAX。 這是通過在將無符號32位轉換爲帶符號16位之前將負標誌添加到有效性檢查來處理的。

./foo 1 -1 2 -2 42 -42 32767 -32767 32768 -32768 
0000000000000001 
1111111111111111 
0000000000000010 
1111111111111110 
0000000000101010 
1111111111010110 
0111111111111111 
1000000000000001 
Error: value too large for 16bit integer: 32768 8000 
1000000000000000