posted at 2015-11-21 19:21:52 +0000
好吧,这个其实是某某书上的一道习题,刚开始看的时候我还以为可以直接输入0xFFF的形式同时赋值给int类型来进行转换,结果,结果发现我想多了。所以,我决定来写篇文章谈谈这个算法。好吧,下面进入正题。
首先说说我们的转换原理,当然是基于除K取余法的逆运算。
比如,我们现有16进制数据 0xFFF (16进制:1,2,….A,B…F,其中A=10,F=15)
按照除K取余法的逆运算,我们有:
0xFFF = 15(16^2) + 15(16^1) + 15*(16^0) = 4095
0x12A = 1(16^2) + 2(16^1) + 10*(16^0) = 298
程序的具体实现:
我在文章开头提到,我之前想的是直接用scanf()输入一个16进制数字,再赋值给int即可,后来,我试了直接输入FFF或者是输入0xFFF发现都不行,最后突然想到,原来自己忘记了scanf的%d只接受数字,所以。
我们要自己写函数转换,就需要接受一个字符串型的16进制数据。然后再用循环依次处理字符串中的每一个字符。
在写的过程中了,最早想的是针对每一个字符我用if块或switch-case来实现判断不同的字符和分别对它们进行不同的处理。不过后来又想了想,这种方法难免会让代码很长。
所以,后来查ASCII表的,想到,我可以利用加减法来判断是那个字符。方法如下:
我们要分2种情况:字符属于‘0’—‘9’和字符属于‘A’—‘F’或‘a’—‘f’的情况。
然后,查ASCII表知:‘A’=65,‘a’=97,‘0’=48
所以,接下来我们要判断当前处理字符是哪个就会变得非常简单,不用if块或switch-case哦。
if ((hex[i] >= 'A' && hex[i] <= 'F') || (hex[i] >= 'a' && hex[i] <= 'f')) {
if (hex[i] >= 'A' && hex[i] <= 'F')
//A=65,
{
for (p = 1; p < len; p++) {
buf *= 16;
}
dec += (ch - 55) * buf;
} else
//a=97,
{
for (p = 1; p < len; p++) {
buf *= 16;
}
dec += (ch - 87) * buf;
}
}
dec += (ch - 55) * buf;
当然,这里的不用if块指的是判断单个字符上,但是我们仍然需要用if保证当前处理字符在16进制中合法。
下面是完整代码:
#include<stdio.h>
#include < string.h >
int Hex2Dec(char hex) {
int dec = 0, i = 0, len = 0, buf = 0, p = 0;
char ch = 0;
while (hex[len]) {
len++;
}
while (hex[i]) {
ch = hex[i];
buf = 1;
if ((hex[i] >= 'A' && hex[i] <= 'F') || (hex[i] >= 'a' && hex[i] <= 'f')) {
if (hex[i] >= 'A' && hex[i] <= 'F')
//A=65,
{
for (p = 1; p < len; p++) {
buf_ = 16;
}
dec += (ch - 55) buf;
} else if (hex[i] >= 'a' && hex[i] <= 'f')
//a=97,
{
for (p = 1; p < len; p++) {
buf_ = 16;
}
dec += (ch - 87) buf;
}
} else if (hex[i] >= '0' && hex[i] <= '9')
//0=48,
{
for (p = 1; p < len; p++) {
buf_ = 16;
}
dec += (ch - 48) * buf;
} else {
printf("nninvaild data input!nn");
return 0;
}
i++;
len--;
}
return dec;
}
int main() {
char hex[99] = {0};
printf("please enter a Hex number:");
gets(hex);
printf("its equal to %dnn", Hex2Dec(hex));
return 0;
}
运行结果:和计算器算出来的一模一样
© kanch
→ zl AT kanchz DOT com
last updated on 2022-07-27 01:57:54 +0000