web-dev-qa-db-ja.com

10進数から2進数

Cで(10進数から)2進数に変換したい数があります。

バイナリを常に5ビットにしたい(10進数が31を超えることは決してない)。除算で手動で行う機能はすでに持っていますが、5ビットに埋め込むのは難しいです。

もっと簡単な方法はありますか?おそらくビット単位のシフトを使用していますか?

また、バイナリをchar *

14
darksky

ここにエレガントなソリューションがあります:

void getBin(int num, char *str)
{
  *(str+5) = '\0';
  int mask = 0x10 << 1;
  while(mask >>= 1)
    *str++ = !!(mask & num) + '0';
}

ここでは、文字列がnull文字で終了していることを確認することから始めます。次に、1つのマスクを含むマスクを作成します(期待されるマスクは、while条件付きの最初の実行でのシフトを考慮して、一度左にシフトされます)。ループを通過するたびに、マスクは1つ右にシフトされ、対応する文字は「1」または「0」に設定されます(!!に0または1を追加していることを確認してください'0')。最後に、マスクの1が数値から外れると、whileループが終了します。

これをテストするには、以下を使用します。

int main()
{
  char str[6];
  getBin(10, str);
  printf("%s\n", str);
  return 0;
}
19
Aaron Dufour

先行ゼロが必要ない場合は、itoa(value、outputstring、base)を使用できます

例えば

char s[9];
itoa(10, s, 2);
printf("%s\n", s);

印刷します

1010

それ以外の場合は、非常に単純な関数を記述できます。

void tobin5str(int value, char* output)
{
    int i;
    output[5] = '\0';
    for (i = 4; i >= 0; --i, value >>= 1)
    {
        output[i] = (value & 1) + '0';
    }
}

int main()
{
    char s[6];
    tobin5str(10, s);
    printf("%s\n", s);
    return 0;
}

印刷します

01010

より一般的なアプローチは、変換するビット数を尋ねる関数です。

void tobinstr(int value, int bitsCount, char* output)
{
    int i;
    output[bitsCount] = '\0';
    for (i = bitsCount - 1; i >= 0; --i, value >>= 1)
    {
        output[i] = (value & 1) + '0';
    }
}

もちろん、bitsCountは1〜32の値である必要があり、バッファ文字列は少なくともbitsCount + 1文字に割り当てる必要があります。

15

1つのアプローチはこれです:

unsigned int x = 30;

char bits[] = "00000";

bits[4] = (x & 1) + '0';
x >>= 1;
bits[3] = (x & 1) + '0';
x >>= 1;
bits[2] = (x & 1) + '0';
x >>= 1;
bits[1] = (x & 1) + '0';
x >>= 1;
bits[0] = x + '0';

おそらく最もエレガントなアプローチではありません...

4
Mysticial

31の値の場合、mallocを実行して文字列を割り当て、その後ビット操作を行って文字列を埋める代わりに、ルックアップテーブルを使用することもできます。

static const char *bitstrings[] = {
    "00000", "00001", "00010", … "11111"
};

次に、変換はreturn bitstrings[i]と同じくらい簡単です。これを頻繁に行う場合、(mallocを回避することにより)これはより高速になります。

それ以外の場合は、実際にシフトする必要はありません(定数の記述を簡単にする場合を除く)。あなたはビットを使うことができます:

char *bits = malloc(6);
bits[0] = (i & (1<<4)) ? '1' : '0';   /* you can also just write out the bit values, but the */
bits[1] = (i & (1<<3)) ? '1' : '0';   /* compiler should be able to optimize a constant!     */
⋮
bits[6] = 0; /* null-terminate string*/

アディションを使用して、ASCIIを想定している場合に実行できる(おそらく)マイクロ最適化があります。ここでループを使用することもできますが、コメント:-Pには2行必要でした。パフォーマンスに関しては、どちらも重要ではありません。すべての時間はmallocに費やされます。

1
derobert

いつでも分割して5ビットに埋め込むことができます(Aのような文字を印刷すると65になるため、これを8ビットに埋め込んでください)。

#include <stdio.h>
#include <math.h>
void main(){
int binary[8], number, i; //for 5 bits use binary[5]
do{
printf("input a number: ");
scanf("%d",&number);
fflush(stdin);
}while(number>256 || number <0); //for 5 bits... 31 use number>31 || number <0
for (i=0; i<=7; i++)  // for 5 bits use i<=4
    {
    binary[i]=number%2;
    number = number/2;
    }
for (i=7; i >=0; i--)  //for 5 bits use i=4
    printf("%d", binary[i]);
number=0; // its allready 0.
for (i=0; i<=7; i++)  //for 5 bits use i<=4
    {
    number=number+binary[i]*pow(2,i);
    }
printf("\n%c",number);
}
#include <stdio.h>
#include <string.h>

char numstr[9024];
int i = 0;

void format(int n, int base);
void printreverse(char *s);

int main()
{
     int testnum = 312;    // some random test number
     format(testnum, 2);   // 2 for binary
     printreverse(numstr);
     putchar('\n');

     return 0;
}

void format(int n, int base)
{
    if (n > 0) {
        char tmp = (n % base) + '0';
        numstr[i++] = tmp;

        // If we put this above other two we don't need printreverse,
        // But then we will have unwanted results in other places of numstr if we can't reset it

        format(n/base, base); 
    } else
        numstr[i] = '\0'; // terminating character
}

void printreverse(char *s)
{
    long len = strlen(s);
    while (len-->0)
        putchar(s[len]);
}
0
Pramod

私の見解:

char* to_bitstring(uint32_t val, char buffer[], int size) {
    buffer[--size] = 0;
    while (size > 0) {
        buffer[--size] = (val % 2 ? '1' : '0');
        val = val >> 1;
    }

    return buffer; /* convenience */
}

これにより、SIZE文字がBUFFERに書き込まれます。

char buffer[17];
printf("%s\n", to_bitstring(42, buffer, sizeof(buffer)));

そして印刷します:

0000000000101010
0
Hugo

5ビットでのみ作業しているので、ルックアップテーブルを使用してみませんか?次のようなもの:

/* Convert nstr to a number (decimal) and put a string representation of the
 * lowest 5 bits in dest (which must be at least 6 chars long) */
void getBinStr(char *dest, const char *nstr)
{
  char *lkup[32] = { 
    "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111",
    "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111",
    "10000", "10001", "10010", "10011", "10100", "10101", "10110", "10111",
    "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111" };
  strcpy(dest, lkup[atoi(nstr) & 0x1f]);
}

またはスイッチ:

void getBinStr(char *dest, const char *nstr)
{
  switch (atoi(nstr)) {
    case 31:  strcpy(dest,"11111"); break;
    case 30:  strcpy(dest,"11110"); break;
    ...
    case 1:   strcpy(dest,"00001"); break;
    case 0:   strcpy(dest,"00000"); break;
    default:  strcpy(dest,"error");
  }
}

または、長すぎると思われる場合は、次のようになります。

void getBinStr(char *dest, const char *nstr)
{
  unsigned x = atoi(nstr);
  dest[0] = (x & 0x10) ? '1' : '0';
  dest[1] = (x & 0x08) ? '1' : '0';
  dest[2] = (x & 0x04) ? '1' : '0';
  dest[3] = (x & 0x02) ? '1' : '0';
  dest[4] = (x & 0x01) ? '1' : '0';
  dest[5] = '\0';
}

私は通常、最初の2つのうちの1つを優先しますが、何らかの理由で他のものが大きすぎる(小さなマイクロコントローラーのコードなど)場合は、最後の1つを使用する方が良いでしょう。

これらはすべて、結果をゼロで埋めて5ビットにすることを前提としています。

0
Dmitri
#include<stdio.h>

int mask = 1;
void decToBi(int);

void decToBi(int n){
    for(int j=15;j>=0;j--){
        int result;
        result = n & (mask<<j);
        if(result)
            printf("1");
        else
            printf("0");
    }    
}    
int main(){
    int n;
    scanf("%d",&n);
    decToBi(n);
    printf("\n");
return 0;
}

お役に立てれば

#include "stdio.h"
#include "conio.h"

int main(void)
{
int i, d , n = 1;
int store[10];

printf("Please enter a number to be converted to binary:\n");
scanf("%d",&d);

for (i=0;i<8 ;i++ )
  store[i] = 0;

i = 0;

do{
if(d & n ){
    n <<= 1;  //10
    store[i] = 1;
    i++;
}
else {
    n <<= 1;
    store[i] = 0;
    i++;
}

}while(n <= d);

printf("\n");
for (i=7;i>=0 ;i-- ){
  printf("%d",store[i]);
if(i == 4)
    printf(" ");
}
printf("\n");
return 0;
}
0
Ahmed Hassan
int main() {
    int n,c,k;
    printf("Enter_an_integer_in_decimal_number_system:_");
    scanf("%d",&n);
    printf("%d_in_binary_number_system_is:_", n);
    for (c = n; c > 0; c = c/2) {
        k = c%2;
        k = (k>0)? printf("1"):printf("0");
    }
    getch();
    return 0;
}
0
Mohmed AbdAllah

これは、システムでサポートされている任意の10進数をビット単位演算子を使用して10進数を2進数に変換し、必要なメモリのみを保持するCプログラムです

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char **argv) 
{
    int n, t = 0;
    char *bin, b[2] = ""; 
    scanf("%d", &n);
    bin = (char*)malloc(sizeof(char) + 2);
    while (n != 0)
    {
        t = n >> 1;
        t = t << 1;
        t = n - t;
        n = n >> 1;
        itoa(t, b, 10);
        bin = realloc((char*)bin, sizeof(char) + 1);
        strcat(bin, b);
    }
    strrev(bin);
    printf("\n%s\n", bin);

    return 0 ;
}
0
Rahul Raina