在C中将小端十六进制转换为大端十进制

时间:2013-03-27 09:29:18

标签: c bit-shift fat

我试图理解并实现一个基于FAT12的简单文件系统。我目前正在查看以下代码片段,它让我发疯:

int getTotalSize(char * mmap) { int *tmp1 = malloc(sizeof(int)); int *tmp2 = malloc(sizeof(int)); int retVal;

* tmp1 = mmap[19];
* tmp2 = mmap[20];
printf("%d and %d read\n",*tmp1,*tmp2);
retVal = *tmp1+((*tmp2)<<8);
free(tmp1);
free(tmp2);
return retVal;

};

从我到目前为止所读到的,FAT12格式以小端格式存储整数。 并且上面的代码是获取文件系统的大小,该文件系统存储在引导扇区的第19和第20个字节中。

但是我不明白为什么

* tmp1 = mmap[19];
* tmp2 = mmap[20];
printf("%d and %d read\n",*tmp1,*tmp2);
retVal = *tmp1+((*tmp2)<<8);
free(tmp1);
free(tmp2);
return retVal;
有效。是按位&lt;&lt; 8将第二个字节转换为十进制?还是大端格式? 为什么只对第二个字节而不是第一个字节进行处理?

有问题的字节是[小端格式]:

40 0B

我尝试通过首先将订单切换为

来手动转换它们

0B 40

然后从十六进制转换为十进制,我得到正确的输出,我只是不明白如何将第一个字节添加到第二个字节的按位移位做同样的事情? 感谢

3 个答案:

答案 0 :(得分:3)

此处malloc()的使用严重facepalm - 诱导。绝对不必要,以及严重的“代码味道”(让我怀疑代码的整体质量)。另外,mmap显然应该是unsigned char(或者更好,uint8_t)。

那就是说,你问的代码很简单。

给定两个字节大小的值ab,有两种方法可以将它们组合成一个16位值(这是代码正在做的):你可以考虑{{ 1}}是最不重要的字节,或a

使用框,16位值可以如下所示:

b

或者像这样,如果您反而认为+---+---+ | a | b | +---+---+ 是最重要的字节:

b

+---+---+ | b | a | +---+---+ lsb合并为16位值的方法很简单:

msb

UPDATE :256来自这个事实,即多字节数字中每个连续更重要的字节的“值”。将其与十进制数字中的10的角色进行比较(要合并两个单位十进制数result = (msb * 256) + lsb; c,您将使用d)。

考虑result = 10 * c + dmsb = 0x01,然后上面会是:

lsb = 0x00

您可以看到result = 0x1 * 256 + 0 = 256 = 0x0100 字节最终位于16位值的上半部分,正如预期的那样。

您的代码正在使用msb按位向左移位,这与乘以2 8 相同,即256。

请注意,上面的<< 8是一个值,即内存中的字节缓冲区,因此它的字节顺序无关紧要。

答案 1 :(得分:1)

我认为将单个数字或字节组合成更大的整数没有问题。

让我们用2位数做十进制:1(最不重要)和2(最重要):

1 + 2 * 10 = 21(10是系统基础)

现在让我们用2位数做基数256:0x40(最低有效)和0x0B(最重要):

0x40 + 0x0B * 0x100 = 0x0B40(0x100 = 256是系统基础)

然而,问题可能在于其他地方,12位整数如何存储在FAT12中。

12位整数占用1.5个8位字节。在3个字节中,您有2个12位整数。

假设你有3个字节的0x12,0x34,0x56。

为了提取第一个整数,你只需要取第一个字节(0x12)和第二个字节的第4个最低有效位(0x04)并将它们组合起来:

0x12 + ((0x34 & 0x0F) << 8) == 0x412

为了提取第二个整数,你需要取第二个字节(0x03)和第三个字节(0x56)的4个最高有效位并将它们组合成这样:

(0x56 << 4) + (0x34 >> 4) == 0x563

如果您阅读了有关FAT的官方微软文档(在线查找fatgen103),您将找到所有与FAT相关的公式/伪代码。

答案 2 :(得分:0)

<<运算符是左移运算符。它取值为操作符左侧的值,并将其移动到操作符右侧使用的数字。

因此,在您的情况下,它将*tmp2八位的值向左移位,并将其与*tmp1的值组合,以从两个八位值生成一个16位值。

例如,假设您有整数1。这是16位二进制,0000000000000001。如果将其向左移8位,则最终得到二进制值0000000100000000,即十进制的256

演示文稿(即二进制,十进制或十六进制)与它无关。所有整数都以相同的方式存储在计算机上。