将十进制转换为任意基数(从 2 到 36)的 C 代码
C code for converting decimal to any base (from 2 to 36)
我最近刚开始学习C。我写了一个很短的程序,可以在十进制和二进制之间进行转换。我想尝试编写一个在十进制和任何基数(直到 36)之间进行转换的代码。但是,我的代码只是打印出垃圾。
#include <stdio.h>
#include <string.h>
void printBase(int n, int k, int i, char a[])
{
int placeholder;
if (n != 0)
{
//return n % 2 + 10 * printBinary(n / 2);
placeholder=(char)(n%k);
if(placeholder>=10)
{
a[i] = (char)(placeholder - 10) + 'A';
} else {
a[i] = (char)placeholder;
}
i++;
printBase(n/2, k, i, a);
}
for (i=0; a[i]!='[=10=]'; i++)
{
printf("%c", a[i]);
}
return;
}
void reverse(char fromStr[], char toStr[])
{
int i, j=0;
i=getchar();
for (i=0; fromStr[i]!='[=10=]'; i++)
{
j++;
}
i=0;
while (j>=0)
{
toStr[i]=fromStr[j];
i++;
j--;
}
printf("%s", toStr);
}
int main()
{
int n, k;
char a[81], b[81];
setvbuf(stdout, NULL, _IONBF, 0);
printf("Enter a deicmal number you want to convert to binary: ");
scanf("%i", &n);
fflush(stdout);
printf("Enter a base: ");
scanf("%i", &k);
printBase(n, k, 0, a);
//printf("%s", a);
//reverse(a, b);
return 0;
}
我认为问题出在我的反向函数上,但它在这段代码之外工作正常。即使当我在 printBase 函数中打印出字符串 a 时,它也会打印出垃圾。这里有什么问题?
#define c ('A' - 10)
int n = 4564567; // any number
int b = 16; // any base
int tmp = n < 0 ? -n : n;
int i = 0;
while (tmp)
{
tmp /= b;
++i; // you need to calculate how long will be the number
}
while (i--)
{
a[i] = n % b + ((n % b < 10) ? '0' : c); // you have to check if the remaining is below 10 or not. That is very important
n /= b;
}
我想你忘记在 else 的情况下添加 '0'
改编自旧源文件https://github.com/agavrel/42-ft_printf/blob/master/srcs/pf_number.c
根据您的代码,下面的代码可以满足您的要求。它在 a
中放置一个 reverse 转换,仍然必须向后打印:
void convertBase(int n, int k, char a[])
{
int j, i=0, sign= 0;
if (n==0) a[i++]='0';
if (n<0 ) {sign= -1; n= -n;}
while (n>0) {
j= n%k;
if (j<10)
a[i]= j+'0';
else
a[i]= j+'A';
n= n/k;
i++;
}
if (sign== -1) a[i++]= '-';
a[i]= 0;
}
这里是还原:
void revStr(char *s)
{
char c;
int i=0, j=0;
while (s[i]) i++; i--;
while (i>j) {
c= s[j];
s[j]=s[i];
s[i]= c;
i--; j++;
}
}
使用 itoa
的一些通用实现
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
static const char* DIGISTS = "0123456789ABCDEFGHIKLMNOPQRSTVXYZ";
void itoa(long long i, unsigned char radix, char* to) {
char *s = to + 65;
char sign;
unsigned len;
if(i < 0) {
sign = 1;
len = 2;
} else {
sign = 0;
len = 1;
}
*s = '[=10=]';
do {
*(--s)= * ( DIGISTS + abs(i % radix) );
i /= radix;
++len;
} while(i != 0);
if(sign)
*(--s) = '-';
memmove( to, s, len );
}
int main(int argc, const char** argv)
{
char a[65];
itoa( LLONG_MAX, 2, a);
printf("binary: %s \n", a);
itoa(12345, 10, a);
printf("digit: %s \n", a);
itoa(64018, 16, a);
printf("hex : 0x%s \n", a);
itoa(-24, 24, a);
printf("base 24 : base24x%s \n", a);
itoa(LLONG_MAX, 36, a);
printf("base 36 : base36x%s \n", a);
return 0;
}
反转数组的替代方法是使用递归。
由于某些整数类型的位数从来没有这么大,因此递归不会过多。
下面使用 do {} while
循环来避免 printBase(0)
的特殊情况。
它还在 printBase_helper()
中使用负值,其中 /,%
在 C99 中定义明确。这避免了代码的未定义行为,例如 n = -n
当 n == INT_MIN
.
void printBase_helper(int neg, int base) {
if (neg <= -base) {
printBase_helper(neg / base, base);
neg %= base;
}
putchar("0123456789ABCDEFGHIJKLMONOPQSTUVWXYZ"[-neg]);
}
void printBase(int n, int base) {
if (n < 0) {
putchar('-');
} else {
n = -n;
}
printBase_helper(n, base);
}
测试码
int main(void) {
int value[] = {0, 1, -1, 10, INT_MAX, INT_MIN};
int base[] = {10, 2, 36};
for (unsigned v = 0; v < sizeof value / sizeof value[0]; v++) {
for (unsigned b = 0; b < sizeof base / sizeof base[0]; b++) {
printf("Base %2d, value %11d, --> base %2d, value ", 10, value[v], base[b]);
printBase(value[v], base[b]);
printf("\n");
}
}
return 0;
}
输出
Base 10, value 0, --> base 10, value 0
Base 10, value 0, --> base 2, value 0
Base 10, value 0, --> base 36, value 0
Base 10, value 1, --> base 10, value 1
Base 10, value 1, --> base 2, value 1
Base 10, value 1, --> base 36, value 1
Base 10, value -1, --> base 10, value -1
Base 10, value -1, --> base 2, value -1
Base 10, value -1, --> base 36, value -1
Base 10, value 10, --> base 10, value 10
Base 10, value 10, --> base 2, value 1010
Base 10, value 10, --> base 36, value A
Base 10, value 2147483647, --> base 10, value 2147483647
Base 10, value 2147483647, --> base 2, value 1111111111111111111111111111111
Base 10, value 2147483647, --> base 36, value ZIK0ZJ
Base 10, value -2147483648, --> base 10, value -2147483648
Base 10, value -2147483648, --> base 2, value -10000000000000000000000000000000
Base 10, value -2147483648, --> base 36, value -ZIK0ZK
我不知道我自己的问题的答案应该贴在下面,抱歉!
但这里是我自己编写的代码,如果它对任何人有帮助的话:
#include <stdio.h>
#include <string.h>
void printBinary(int n, int k, int i, char a[])
{
int placeholder;
if (n != 0)
{
placeholder=(n%k);
if(placeholder>=10)
{
a[i] = (placeholder - 10) + 'A';
} else if(placeholder>=0 && placeholder<=9){
a[i] = placeholder + '0';
}
i++;
a[i]='[=10=]';
printBinary(n/k, k, i, a);
}
return;
}
int main()
{
int n, k;
char a[81], b[81];
setvbuf(stdout, NULL, _IONBF, 0);
printf("Enter a deicmal number you want to convert to binary: ");
scanf("%i", &n);
fflush(stdout);
printf("Enter a base: ");
scanf("%i", &k);
printBinary(n, k, 0, a);
n=strlen(a);
k=0;
n--;
while (n>=0)
{
b[k]=a[n];
n--;
k++;
}
b[k]='[=10=]';
printf("%s", b);
return 0;
}
Try this one.
#include<stdio.h>
int main()
{
int n,b,t1,i=0;
float t2,t3,t4;
int a[10];
scanf("%d%d",&n,&b);
for( i=0; n!=0; i++)
{
t1=n/b;
t2=(float)n/b;
t3=(float)t2-t1;
t1=t3*b;
t2=(float)t3*b;
t4=(float)t2-t1;
if(t4>=0.5)
{
a[i]=t3*b+1;
}
else
{
a[i]=t3*b;
}
n=n/b;
}
for(int j=i; j>0; j--)
{
printf("%d",a[j-1]);
}
return 0;
}
我最近刚开始学习C。我写了一个很短的程序,可以在十进制和二进制之间进行转换。我想尝试编写一个在十进制和任何基数(直到 36)之间进行转换的代码。但是,我的代码只是打印出垃圾。
#include <stdio.h>
#include <string.h>
void printBase(int n, int k, int i, char a[])
{
int placeholder;
if (n != 0)
{
//return n % 2 + 10 * printBinary(n / 2);
placeholder=(char)(n%k);
if(placeholder>=10)
{
a[i] = (char)(placeholder - 10) + 'A';
} else {
a[i] = (char)placeholder;
}
i++;
printBase(n/2, k, i, a);
}
for (i=0; a[i]!='[=10=]'; i++)
{
printf("%c", a[i]);
}
return;
}
void reverse(char fromStr[], char toStr[])
{
int i, j=0;
i=getchar();
for (i=0; fromStr[i]!='[=10=]'; i++)
{
j++;
}
i=0;
while (j>=0)
{
toStr[i]=fromStr[j];
i++;
j--;
}
printf("%s", toStr);
}
int main()
{
int n, k;
char a[81], b[81];
setvbuf(stdout, NULL, _IONBF, 0);
printf("Enter a deicmal number you want to convert to binary: ");
scanf("%i", &n);
fflush(stdout);
printf("Enter a base: ");
scanf("%i", &k);
printBase(n, k, 0, a);
//printf("%s", a);
//reverse(a, b);
return 0;
}
我认为问题出在我的反向函数上,但它在这段代码之外工作正常。即使当我在 printBase 函数中打印出字符串 a 时,它也会打印出垃圾。这里有什么问题?
#define c ('A' - 10)
int n = 4564567; // any number
int b = 16; // any base
int tmp = n < 0 ? -n : n;
int i = 0;
while (tmp)
{
tmp /= b;
++i; // you need to calculate how long will be the number
}
while (i--)
{
a[i] = n % b + ((n % b < 10) ? '0' : c); // you have to check if the remaining is below 10 or not. That is very important
n /= b;
}
我想你忘记在 else 的情况下添加 '0'
改编自旧源文件https://github.com/agavrel/42-ft_printf/blob/master/srcs/pf_number.c
根据您的代码,下面的代码可以满足您的要求。它在 a
中放置一个 reverse 转换,仍然必须向后打印:
void convertBase(int n, int k, char a[])
{
int j, i=0, sign= 0;
if (n==0) a[i++]='0';
if (n<0 ) {sign= -1; n= -n;}
while (n>0) {
j= n%k;
if (j<10)
a[i]= j+'0';
else
a[i]= j+'A';
n= n/k;
i++;
}
if (sign== -1) a[i++]= '-';
a[i]= 0;
}
这里是还原:
void revStr(char *s)
{
char c;
int i=0, j=0;
while (s[i]) i++; i--;
while (i>j) {
c= s[j];
s[j]=s[i];
s[i]= c;
i--; j++;
}
}
使用 itoa
的一些通用实现#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
static const char* DIGISTS = "0123456789ABCDEFGHIKLMNOPQRSTVXYZ";
void itoa(long long i, unsigned char radix, char* to) {
char *s = to + 65;
char sign;
unsigned len;
if(i < 0) {
sign = 1;
len = 2;
} else {
sign = 0;
len = 1;
}
*s = '[=10=]';
do {
*(--s)= * ( DIGISTS + abs(i % radix) );
i /= radix;
++len;
} while(i != 0);
if(sign)
*(--s) = '-';
memmove( to, s, len );
}
int main(int argc, const char** argv)
{
char a[65];
itoa( LLONG_MAX, 2, a);
printf("binary: %s \n", a);
itoa(12345, 10, a);
printf("digit: %s \n", a);
itoa(64018, 16, a);
printf("hex : 0x%s \n", a);
itoa(-24, 24, a);
printf("base 24 : base24x%s \n", a);
itoa(LLONG_MAX, 36, a);
printf("base 36 : base36x%s \n", a);
return 0;
}
反转数组的替代方法是使用递归。
由于某些整数类型的位数从来没有这么大,因此递归不会过多。
下面使用 do {} while
循环来避免 printBase(0)
的特殊情况。
它还在 printBase_helper()
中使用负值,其中 /,%
在 C99 中定义明确。这避免了代码的未定义行为,例如 n = -n
当 n == INT_MIN
.
void printBase_helper(int neg, int base) {
if (neg <= -base) {
printBase_helper(neg / base, base);
neg %= base;
}
putchar("0123456789ABCDEFGHIJKLMONOPQSTUVWXYZ"[-neg]);
}
void printBase(int n, int base) {
if (n < 0) {
putchar('-');
} else {
n = -n;
}
printBase_helper(n, base);
}
测试码
int main(void) {
int value[] = {0, 1, -1, 10, INT_MAX, INT_MIN};
int base[] = {10, 2, 36};
for (unsigned v = 0; v < sizeof value / sizeof value[0]; v++) {
for (unsigned b = 0; b < sizeof base / sizeof base[0]; b++) {
printf("Base %2d, value %11d, --> base %2d, value ", 10, value[v], base[b]);
printBase(value[v], base[b]);
printf("\n");
}
}
return 0;
}
输出
Base 10, value 0, --> base 10, value 0
Base 10, value 0, --> base 2, value 0
Base 10, value 0, --> base 36, value 0
Base 10, value 1, --> base 10, value 1
Base 10, value 1, --> base 2, value 1
Base 10, value 1, --> base 36, value 1
Base 10, value -1, --> base 10, value -1
Base 10, value -1, --> base 2, value -1
Base 10, value -1, --> base 36, value -1
Base 10, value 10, --> base 10, value 10
Base 10, value 10, --> base 2, value 1010
Base 10, value 10, --> base 36, value A
Base 10, value 2147483647, --> base 10, value 2147483647
Base 10, value 2147483647, --> base 2, value 1111111111111111111111111111111
Base 10, value 2147483647, --> base 36, value ZIK0ZJ
Base 10, value -2147483648, --> base 10, value -2147483648
Base 10, value -2147483648, --> base 2, value -10000000000000000000000000000000
Base 10, value -2147483648, --> base 36, value -ZIK0ZK
我不知道我自己的问题的答案应该贴在下面,抱歉! 但这里是我自己编写的代码,如果它对任何人有帮助的话:
#include <stdio.h>
#include <string.h>
void printBinary(int n, int k, int i, char a[])
{
int placeholder;
if (n != 0)
{
placeholder=(n%k);
if(placeholder>=10)
{
a[i] = (placeholder - 10) + 'A';
} else if(placeholder>=0 && placeholder<=9){
a[i] = placeholder + '0';
}
i++;
a[i]='[=10=]';
printBinary(n/k, k, i, a);
}
return;
}
int main()
{
int n, k;
char a[81], b[81];
setvbuf(stdout, NULL, _IONBF, 0);
printf("Enter a deicmal number you want to convert to binary: ");
scanf("%i", &n);
fflush(stdout);
printf("Enter a base: ");
scanf("%i", &k);
printBinary(n, k, 0, a);
n=strlen(a);
k=0;
n--;
while (n>=0)
{
b[k]=a[n];
n--;
k++;
}
b[k]='[=10=]';
printf("%s", b);
return 0;
}
Try this one.
#include<stdio.h>
int main()
{
int n,b,t1,i=0;
float t2,t3,t4;
int a[10];
scanf("%d%d",&n,&b);
for( i=0; n!=0; i++)
{
t1=n/b;
t2=(float)n/b;
t3=(float)t2-t1;
t1=t3*b;
t2=(float)t3*b;
t4=(float)t2-t1;
if(t4>=0.5)
{
a[i]=t3*b+1;
}
else
{
a[i]=t3*b;
}
n=n/b;
}
for(int j=i; j>0; j--)
{
printf("%d",a[j-1]);
}
return 0;
}