我有一个数字,希望在C语言中将其转换为二进制(从十进制)。
我希望我的二进制始终为5位(十进制永远不会超过31)。我已经有一个手动通过除法实现的函数,但很难将其填充到5位。
是否有更简单的方法?也许使用位移操作?
我还希望以char *
的形式表示二进制。
我有一个数字,希望在C语言中将其转换为二进制(从十进制)。
我希望我的二进制始终为5位(十进制永远不会超过31)。我已经有一个手动通过除法实现的函数,但很难将其填充到5位。
是否有更简单的方法?也许使用位移操作?
我还希望以char *
的形式表示二进制。
这里有一个优雅的解决方案:
void getBin(int num, char *str)
{
*(str+5) = '\0';
int mask = 0x10 << 1;
while(mask >>= 1)
*str++ = !!(mask & num) + '0';
}
这里,我们首先确保字符串以空字符结尾。然后,我们创建一个掩码(mask),其中有一个单一的“1”(它是您期望的掩码,向左移位一次以说明在while条件的第一次运行中的移位)。每次循环时,掩码向右移动一位,然后相应的字符设置为“1”或“0”(!!
确保我们添加了一个0或1到'0'
)。最后,当掩码中的1被移出数字时,while循环结束。
要测试它,请使用以下代码:
int main()
{
char str[6];
getBin(10, str);
printf("%s\n", str);
return 0;
}
如果你不需要前导零,你可以使用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个字符分配空间。
一个解决方案如下:
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';
可能不是最优雅的方法...
您始终可以将其分成5位并填充它(这样做是为了填充8位,因为打印像A这样的字符将是数字65)
#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);
}
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。就性能而言,两者都不会有影响。所有时间都花费在malloc上。
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;
}
#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;
}
#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;
}
希望这能有所帮助
这是一个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 ;
}
既然你只使用了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';
}
通常我会偏向于前两种,但如果出于某些原因其他方式太大(例如用于小型微控制器的代码),最后一种可能更好。
这些都假设您想要左侧填充零到5位的结果。
0-31
表示为 int 的意外表示形式。 - Aaron Dufour=
来获得赋值版本。 - Aaron Dufourmask&num
是一种_按位_和操作。因为mask
只包含一个1
位,如果该位在num
中为0
,则返回0
,如果该位在num
中为1
,则返回非零值。!!
将0
保留为0
,将其他任何东西转换为1
。最后,'0'
是用于表示ASCII中的零字符的数字。 将其加1可得到ASCII中'1'的数字。 - Aaron Dufourchar
类型只是一个单字节的数字。printf
(或者更准确地说,你的 shell)知道如何将它们解释为 ASCII 码。你可以通过printf("%d\n", '0');
来查看它是一个数字。 - Aaron Dufour