0

有人可以向我解释在这种情况下“n”发生了什么吗?

主程序

unsigned long temp0;
PLLSYS0_FWD_DIV_A_DECODE(n);

主文件

#define PLLSYS0_FWD_DIV_A_DECODE(n) ((((unsigned long)(n))>>8)& 0x0000000f)

我知道 n 被移动了 8 位,然后与 0x0000000f 相加。那么 (unsigned long)(n) 实际上做了什么?

#include <stdio.h>

int main(void)
{
    unsigned long test1 = 1;
    printf("test1 = %d \n", test1);
    printf("(unsigned long)test1 = %d \n", (unsigned long)(test1));

return 0;
}

输出:

test1 = 1 
(unsigned long)test1 = 1
4

5 回答 5

2

在您的代码示例中,强制转换没有多大意义,因为test1已经是 a ,但是当宏用于其他类型(如etc unsigned long)时,它是有意义的。unsigned char

你也应该使用%luinprintf 来打印unsigned long.

printf("(unsigned long)test1 = %lu\n", (unsigned long)(test1));
//                              ^^
于 2013-10-04T17:26:53.573 回答
1

有人可以向我解释在这种情况下“n”发生了什么吗?

您正在投射nunsigned long.

那么 (unsigned long)(n) 实际上做了什么?

它将提升nunsigned long.

于 2013-10-04T17:23:48.077 回答
1

它把它扩大到一个unsigned long. 想象一下,如果你用 a 调用char它并将其向右移动 8 位,则与运算不会相同。

也刚刚找到了这个(在右移运算符下查看)为什么它是无符号的。显然无符号强制进行逻辑移位,其中最左边的位被替换为每个移位位置的零。而带符号的值移位执行算术移位,其中最左边的位被删除的最右边的位替换。

例子:

11000011 ( unsigned, shifted to the right by 1 )
01100001

11000011 ( signed, shifted to the right by 1 )
11100001
于 2013-10-04T17:24:02.013 回答
0

转换输入是它在位移和与运算之前所做的一切。注意运算符的顺序和优先级。这很丑陋。

但看起来他们正在避免点击符号位,并且通过这样做而不是函数,没有对 n 进行类型检查。

这只是丑陋的。

更好的形式是拥有一个具有输入类型检查的清晰功能。

于 2013-10-04T17:28:35.820 回答
0

这确保n具有适当的大小(以位为单位),最重要的是被视为无符号。由于移位运算符执行符号扩展,当一个数字有符号且为负数时,扩展将以 1 而不是 0 完成。这意味着负数移位将始终导致负数。

例如:

int main()
{
        long i = -1;
        long x, y;

        x = ((unsigned long)i) >> 8;
        y = i >> 8;

        printf("%ld %ld\n", x, y);
}

在我的机器上它输出:

72057594037927935 -1

由于 中的符号扩展y,该数字继续为 -1:

于 2013-10-04T17:33:14.727 回答