1

如何正确地将 4 个字节转换为一个无符号长变量?

我正在 MPLAB C18 上编程 PIC18,这是我的代码。

unsigned long theseconds = 0x00;
BYTE timeToSave[4];

timeToSave[0] = 0xFF;
timeToSave[1] = 0xFF;
timeToSave[2] = 0x01;
timeToSave[3] = 0x01;

theseconds  =   timeToSave[0] & 0xFF;
theseconds |=  (timeToSave[1] << 8) & 0xFFFF;
theseconds |=  (timeToSave[2] << 16) & 0xFFFFFF;
theseconds |=  (timeToSave[3] << 24) & 0xFFFFFFFF;
printf("\r\nSeconds:%lu",theseconds);

这是我不断得到的输出, 秒:255

谢谢!

4

1 回答 1

3

这应该工作

unsigned long theseconds = 0x00;
BYTE timeToSave[4];

timeToSave[0] = 0xFF;
timeToSave[1] = 0xFF;
timeToSave[2] = 0x01;
timeToSave[3] = 0x01;

theseconds  =   timeToSave[3];
theseconds  <<= 8;
theseconds  |=   timeToSave[2];
theseconds  <<= 8;
theseconds  |=   timeToSave[1];
theseconds  <<= 8;
theseconds  |=   timeToSave[0];
printf("\r\nSeconds:%lu",theseconds);

您的代码失败有两个原因。
我想int是 16 位,因此 16 或 24 的移位将导致 0,因为 ANSI-C 中的规则是BYTEtimeToSave[x]实际上是无符号字符)应该扩展为 int。
显然,将一个 16 位的值移位 15 次以上也会导致为 0。

但是为什么你得到 255 而不是 65535?
我想编译器不符合 ANSI,并且不会以适当的方式扩展您的 unsigned char。

为了使您的代码正常工作,转换每一行就足够了。

theseconds  =   timeToSave[0];
theseconds |=  ((unsigned long)timeToSave[1] << 8);
theseconds |=  ((unsigned long)timeToSave[2] << 16);
theseconds |=  ((unsigned long)timeToSave[3] << 24);

掩码是无意义的&,因为值不能超出范围

于 2013-07-15T19:35:44.750 回答