免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1899 | 回复: 9
打印 上一主题 下一主题

[C] 一个移位的困惑 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-06-30 20:23 |只看该作者 |倒序浏览
一个二进制和16进制互转的代码:

typedef unsigned char *LPSTR;
 
UCHAR hextable[16] =
    { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
    'E', 'F'
};
 
#define TOHEX(a, b)    {*b++ = hextable[a >> 4];*b++ = hextable[a&0xf];}
 
LPSTR
BinToHex (LPBYTE p, int len)
{
    int i;
    LPSTR str = (LPSTR) malloc (len * 3 + 1);
    LPSTR basestr = str;
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i < len; i++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TOHEX (p[i], str);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;*str = '\0';
&nbsp;&nbsp;&nbsp;&nbsp;return basestr;
}
&nbsp;
#define HEXTOBIN(x) ( (x) >= '0' && (x) <= '9' ? ((x)-'0') : \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(x) >= 'A' && (x) <= 'F' ? ((x)-'A'+10) : ((x)-'a'+10))
&nbsp;
LPBYTE
HexToBin (LPSTR p, int len)
{
&nbsp;&nbsp;&nbsp;&nbsp;int i;
&nbsp;&nbsp;&nbsp;&nbsp;LPBYTE out = (LPBYTE) malloc (len >> 1);
&nbsp;&nbsp;&nbsp;&nbsp;LPBYTE out_org = out;
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i < len; i += 2)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*out++ = (HEXTOBIN (p[i]) << 4) | HEXTOBIN (p[i + 1]);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return out_org;
}


为什么#define TOHEX(a, b)        {*b++ = hextable[a >> 4];*b++ = hextable[a&0xf];}中的 hextable[a >> 4]能够正确运行,这样一个简单的移位在a的高位为1时,将被补1,这样的话程序不能正确找到数组中的字母啊,可是我做了测试有发现确实是正确的,想不通啊

论坛徽章:
0
2 [报告]
发表于 2009-06-30 21:58 |只看该作者

  1.     LPSTR str = (LPSTR) malloc (len * 3 + 1);
  2.     LPSTR basestr = str;
复制代码

这写法不应该放在子函数中

论坛徽章:
0
3 [报告]
发表于 2009-06-30 21:58 |只看该作者

回复 #1 ziffer 的帖子

注意 hextable就像是函数 把 0-15 映射为 0-f。
一般来说字符的范围是0-128,也就是ascii码, 用二进制表示是 0 -  10000000 之间的一个二进制码。

现在0xf在二进制码中是 1111, 所以把一个输入字符的二进制码以四位为一组,每次处理四位。
所以假设 a是 01001011
第一步把a>>4,处理的高四位, 移动后a是 00000100,也就是十进制吗的4,被赋予了*b
第二步a&0xf 也就是a & 00001011,这是把a的低四位取出来,也就是1011,就是十进制的11,所以heltable[11]给出 16进制的B,并把B赋予*b

[ 本帖最后由 apple753357 于 2009-6-30 22:21 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-07-01 12:25 |只看该作者
原帖由 apple753357 于 2009-6-30 21:58 发表
注意 hextable就像是函数 把 0-15 映射为 0-f。
一般来说字符的范围是0-128,也就是ascii码, 用二进制表示是 0 -  10000000 之间的一个二进制码。

现在0xf在二进制码中是 1111, 所以把一个输入字符的 ...


你回贴都没看我的帖子内容

论坛徽章:
0
5 [报告]
发表于 2009-07-01 14:34 |只看该作者
没听说a>>4 当a的高位为1时会补1.我记得应该以0补齐吧,你试试看就知道了。

论坛徽章:
0
6 [报告]
发表于 2009-07-01 17:34 |只看该作者
你的这段代码里面都没有调用到那个宏

论坛徽章:
0
7 [报告]
发表于 2009-07-01 20:41 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
8 [报告]
发表于 2009-07-01 20:49 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
9 [报告]
发表于 2009-07-02 08:35 |只看该作者
原帖由 xiaoQ008 于 2009-7-1 20:49 发表
it's my test
:
char b='b'+'a';
  printf("%s\n",BinToHex(&b,1));
output
H3;
后面的那个3是对的
但H不知道怎么来的

不知道楼主“可是我做了测试有发现确实是正确的“是传的什么值进去的哦

建议 ...



我的测试

int buf[2];

buf[0] = 0xFEDC1234;
buf[2] = 0;

strHex = BinToHex ((LPSTR)buf, 4);

测试的结果给忘了,是正确的,现在不在那个机器上。
typedef unsigned char *LPSTR;
我在把buf转化成unsigned char后应该是补0?
还是用你的建议把高四位异或掉保险点吧

论坛徽章:
0
10 [报告]
发表于 2009-07-02 09:29 |只看该作者
原帖由 foolishx 于 2009-7-1 14:34 发表
没听说a>>4 当a的高位为1时会补1.我记得应该以0补齐吧,你试试看就知道了。


右移分逻辑右移和算术右移,右移需要考虑负数的情况。而左移不需要。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP