Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的模糊铸造_C_Casting - Fatal编程技术网

C语言中的模糊铸造

C语言中的模糊铸造,c,casting,C,Casting,我很惊讶为什么会得到不同的结果 uint16_t wCaptureTime = 35; wDeltaTime1 = (uint16_t) - (int16_t)wCaptureTime; wDeltaTime2 = 0xFFFF - (int16_t)wCaptureTime; printf("wDeltaTime1 %d \n", wDeltaTime1); printf("wDeltaTime2 %d \n", wDeltaTime2); 代码

我很惊讶为什么会得到不同的结果

    uint16_t wCaptureTime = 35;

    wDeltaTime1 = (uint16_t) - (int16_t)wCaptureTime;
    wDeltaTime2 =  0xFFFF - (int16_t)wCaptureTime;

    printf("wDeltaTime1 %d \n", wDeltaTime1);
    printf("wDeltaTime2 %d \n", wDeltaTime2);
代码的结果是:

wDeltaTime1 65501 
wDeltaTime2 65500 

有没有人可以解释一下或提供一些链接来阅读有关这种行为的信息。

在第一种情况下,您正在向uint16\t投-35。这是65501:

- (uint16_t) 35 = 65501 (as an uint16_t)
在第二种情况下,第一个操作数是0xffff 65535,因此得到65535-35=65550:

65535 - (uint16_t) 35 = 65500
表达式uint16_t-int16_twCaptureTime中的uint16_t是强制转换。当-35被施放到uint16时,得到-35+65536,即65501


如果sizeofint为2,则0xFFFF-int16twaptureTime在无符号算术中为65535-35,即65500。如果sizeofint为4,则您将得到相同的结果,尽管表达式将使用有符号整数算法进行计算。

假设实现使用32位整数,并且wDeltaTime1为整数,则DeltaTime1中的操作=uint16_t-int16_TcaptureTime;它们是:

int16_t转换将uint16_t wCaptureTime转换为int16_t。该值仍为35。 此int16_t将自动升级为int。该值保持为35。 一元运算符对值求反,产生−35 uint16\u t转换将其转换为uint16\u t。对uint16的转换是以65536模执行的,因此结果是−35 + 65536 = 65501. 此uint16_t转换为wDeltaTime1,int的类型。值为65501。 该值分配给wDeltaTime1,在wDeltaTime1中生成65501。 wDeltaTime2中的操作=0xFFFF-int16_twaptureTime;它们是:

0xFFFF是一个int常量,值为65535。 int16_t转换将uint16_t wCaptureTime转换为int16_t。该值仍为35。 此int16_t将自动升级为int。该值保持为35。 二进制运算符从65535中减去35,得到65535− 35 = 65500. 此值被指定给wDeltaTime2,在wDeltaTime2中生成65500。 您可能会感到困惑的一个原因是uint16_t中的否定相当于从65536中减去,而不是从65535或0xFFFF中减去。65535是16位的“全一”模式;它的行为不像零。65536是uint16环绕的地方,所以它的行为更像零

按位补码运算符~,将仅考虑低16位35到65500。第1行:

int16_twaptureTime;触发到int16\t的显式转换。保留值35。 -int16_twaptureTime;应用一元运算符。对于32位或更大的计算机,wCaptureTime将整数提升为int。对于8/16位计算机,类型保持为int16。 uint16_t-int16_t捕获时间;触发负值到uint16\t的显式转换。此转换按照C17 6.3.1.3进行:

否则,如果新类型是无符号的,则会通过重复地将新类型中可以表示的最大值加上或减去一个值来转换该值,直到该值在新类型的范围内

在2的补码32位计算机上-35将产生0xFFDD=65501

第2行:

0xFFFF在8/16位CPU上为无符号int类型,但在32位或更大位CPU上为int类型。 如果0xFFFF是无符号int,则操作数int16_twCaptureTime;由于通常的算术转换,无论强制转换是什么,都会被提升为无符号整数。在这种情况下,将发生与第1行相同的有符号到无符号转换,最终得到类似无符号算术65535-0xFFDD=34十进制的结果。 如果0xFFFF为int,则操作数int16\u twCaptureTime;将升级为int。该操作仅使用两个int操作数65535-35=65500执行。 学习和学习


此外,整数常量的类型也很重要。大多数情况下,它们是int,但对于十六进制整数常量,它们也可以是无符号int,具体取决于值。

您确定WDELTATIME1定义吗?无论如何,此代码的行为将根据CPU寄存器大小=int.32位的大小而有所不同?小于32位?不,C中没有隐式操作数。@JohnBollinger:我想他的意思是-x隐式为0-x,我并不同意这种说法。@EricPostphil,只有当操作符被解释为二进制-,而它当然是一元-,才可能有隐式第一个操作数。结果在代数上等价于从0中减去单个操作数,这是一个站不住脚的问题,部分原因是代数等价总是赋予计算等价,部分原因是这两个运算符具有不同的优先级。@JohnBollinger:我不是说C运算符。从数学上讲,−x是0-x。这个答案有误导性。在第二种情况下,第一个操作数是0xFFFF,它将适合整数或无符号整数。在任何系统上,它都将始终是一个正值,并且永远不会被视为-1,除非显式转换为有符号类型。@Lundin:谢谢,实际上有几个地方不会发生自动升级。我更新了答案−35到uint16_t是由C标准6.3.1.3 2定义的,模,而不是实现定义的。你迟到了,但我认为
这是一个特别好的答案。@EricPostFischil是的,这是实现定义的格式2的compl