从任何基数到十进制的转换和区分大小写
Conversion from any base to decimal and case sensitivity
我正在使用以下门户来验证我的代码的结果(同样来自网络):
我的代码如下图:
// C program to convert a number from any base
// to decimal
#include <stdio.h>
#include <string.h>
// To return value of a char. For example, 2 is
// returned for '2'. 10 is returned for 'A', 11
// for 'B'
int val(char c)
{
if (c >= '0' && c <= '9')
return (int)c - '0';
else
return (int)c - 'A' + 10;
}
// Function to convert a number from given base 'b'
// to decimal
int toDeci(char *str, int base)
{
int len = strlen(str);
int power = 1; // Initialize power of base
int num = 0; // Initialize result
int i;
// Decimal equivalent is str[len-1]*1 +
// str[len-1]*base + str[len-1]*(base^2) + ...
for (i = len - 1; i >= 0; i--)
{
// A digit in input number must be
// less than number's base
if (val(str[i]) >= base)
{
printf("Invalid Number\n");
return -1;
}
num += val(str[i]) * power;
power = power * base;
}
return num;
}
// Driver code
int main()
{
char str[] = "25a";
int base = 36;
printf("Decimal equivalent of %s in base %d is " " %d ", str, base, toDeci(str, base));
return 0;
}
如 main()
中所示,如果对 str[]
使用值“25a”,我将得到以下输出:
Invalid Number
Decimal equivalent of 25a in base 36 is -1
但是如果我将 str[]
的值更改为“25A”,我会得到以下输出:
Decimal equivalent of 25A in base 36 is 2782
使用我上面提供的门户 link 进行结果验证,我得到了两个值的最后结果。
所以我的问题是,如何修改我的代码以进行相应的更改?
TIA
维诺德
你为什么不利用strtoll()
功能:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[] = "25a";
int base = 36;
unsigned long long todeci;
todeci = strtoll(str, (char **)NULL, base);
printf("Decimal equivalent of %s in base %d is %lld\n", str, base, todeci);
return 0;
}
输出:
Decimal equivalent of 25a in base 36 is 2782
如果您不能或不想更改函数签名或使用适当的库函数来执行转换,对 val
函数的简单更改将允许代码也管理小写。
int val(char c)
{
if ( '0' <= c && c <= '9')
return c - '0';
else if ( 'A' <= c && c <= 'Z' )
return c - 'A' + 10;
else if ( 'a' <= c && c <= 'z' )
return c - 'a' + 10;
else
return -1;
}
对另一个函数稍做改动(使用 Horner 方法计算多项式),我们也可以避免调用 strlen
.
int toDeci(char *str, int base)
{
unsigned long long int num = 0;
while( *str != '[=11=]' )
{
int digit = val(*str);
if ( digit == -1 || digit >= base )
{
printf("Invalid digit.\n");
return -1;
}
unsigned long long int n = num * base + digit;
if ( n < num )
{
printf("The number is too big.\n");
return -1;
}
num = n;
++str;
}
if ( num > INT_MAX ) // You'll have to include <limits.h>
{
printf("The number is too big to fit into an int.\n");
return -1;
}
return num;
}
请注意,此代码仍然无法处理负数或前缀,例如 0
用于八进制数和 0x
用于十六进制数。错误检查也遵循 OP 的选择(出现问题时返回 -1
),需要重新考虑。
我正在使用以下门户来验证我的代码的结果(同样来自网络):
我的代码如下图:
// C program to convert a number from any base
// to decimal
#include <stdio.h>
#include <string.h>
// To return value of a char. For example, 2 is
// returned for '2'. 10 is returned for 'A', 11
// for 'B'
int val(char c)
{
if (c >= '0' && c <= '9')
return (int)c - '0';
else
return (int)c - 'A' + 10;
}
// Function to convert a number from given base 'b'
// to decimal
int toDeci(char *str, int base)
{
int len = strlen(str);
int power = 1; // Initialize power of base
int num = 0; // Initialize result
int i;
// Decimal equivalent is str[len-1]*1 +
// str[len-1]*base + str[len-1]*(base^2) + ...
for (i = len - 1; i >= 0; i--)
{
// A digit in input number must be
// less than number's base
if (val(str[i]) >= base)
{
printf("Invalid Number\n");
return -1;
}
num += val(str[i]) * power;
power = power * base;
}
return num;
}
// Driver code
int main()
{
char str[] = "25a";
int base = 36;
printf("Decimal equivalent of %s in base %d is " " %d ", str, base, toDeci(str, base));
return 0;
}
如 main()
中所示,如果对 str[]
使用值“25a”,我将得到以下输出:
Invalid Number
Decimal equivalent of 25a in base 36 is -1
但是如果我将 str[]
的值更改为“25A”,我会得到以下输出:
Decimal equivalent of 25A in base 36 is 2782
使用我上面提供的门户 link 进行结果验证,我得到了两个值的最后结果。
所以我的问题是,如何修改我的代码以进行相应的更改?
TIA
维诺德
你为什么不利用strtoll()
功能:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[] = "25a";
int base = 36;
unsigned long long todeci;
todeci = strtoll(str, (char **)NULL, base);
printf("Decimal equivalent of %s in base %d is %lld\n", str, base, todeci);
return 0;
}
输出:
Decimal equivalent of 25a in base 36 is 2782
如果您不能或不想更改函数签名或使用适当的库函数来执行转换,对 val
函数的简单更改将允许代码也管理小写。
int val(char c)
{
if ( '0' <= c && c <= '9')
return c - '0';
else if ( 'A' <= c && c <= 'Z' )
return c - 'A' + 10;
else if ( 'a' <= c && c <= 'z' )
return c - 'a' + 10;
else
return -1;
}
对另一个函数稍做改动(使用 Horner 方法计算多项式),我们也可以避免调用 strlen
.
int toDeci(char *str, int base)
{
unsigned long long int num = 0;
while( *str != '[=11=]' )
{
int digit = val(*str);
if ( digit == -1 || digit >= base )
{
printf("Invalid digit.\n");
return -1;
}
unsigned long long int n = num * base + digit;
if ( n < num )
{
printf("The number is too big.\n");
return -1;
}
num = n;
++str;
}
if ( num > INT_MAX ) // You'll have to include <limits.h>
{
printf("The number is too big to fit into an int.\n");
return -1;
}
return num;
}
请注意,此代码仍然无法处理负数或前缀,例如 0
用于八进制数和 0x
用于十六进制数。错误检查也遵循 OP 的选择(出现问题时返回 -1
),需要重新考虑。