我已经阅读了一些关于类似我的问题的Q& A,但我仍然不确定我的案例是否与这些问题相同。
我想知道为什么我们需要两个演员:(ULONG)(USHORT)(carry >> BITPERDGT)
*sptr_l++ = (USHORT)(carry = (ULONG)*aptr_l++
+ (ULONG)*bptr_l++ + (ULONG)(USHORT)(carry >> BITPERDGT));
ULONG:typedef unsigned long ULONG;
USHORT:typedef unsigned short USHORT;
使用的C库:FLINT
书:C和C ++中的Cryptogtaphy
答案 0 :(得分:2)
尝试逐个采用OP的代码。
*sptr_l++ = (USHORT)(carry = (ULONG)*aptr_l++
+ (ULONG)*bptr_l++ + (ULONG)(USHORT)(carry >> BITPERDGT));
这有点简化为
carry = (ULONG)*aptr_l++ + (ULONG)*bptr_l++ + (ULONG)(USHORT)(carry >> BITPERDGT);
*sptr_l++ = (USHORT)carry;
鉴于ULONG
> = USHORT
范围的范围,可能大于 ......
(USHORT)(carry >> BITPERDGT)
简单地将carry
最低BITPERDGT
个有效位的值移出。其余部分使用(USHORT)
进行投射,最高有效位被归零。
然后代码使用ULONG
将不必要转换为(ULONG)(USHORT)(carry >> BITPERDGT));
。这不是必需的,因为后续添加ULONG
会导致(USHORT)(carry >> BITPERDGT
即使没有演员也会被提升为ULONG
。
为什么要在这一行投两次?
虽然不是需要,但可能存在(ULONG)
强制转换,以强调程序员在添加之前提升(USHORT)(carry >> BITPERDGT))
的结果。
答案 1 :(得分:1)
代码似乎是计算两个大整数之和的例程的一部分(数字表示为USHORT
== unsigned short
,每个都有BITPERDGT
个值位。转换为USHORT
具有丢弃其操作数的高位的效果,但实际上如果转换后的结果具有与操作数不同的值,则例程被破坏(假设我已正确识别它) )。
在此上下文中根本不需要后续转换为ULONG
(== unsigned long
),因为它指定的转换无论如何都要执行,以便计算该操作数的总和。 ULONG
的{{1}}左侧操作数。在任何情况下,它都会对值产生影响,因为+
必须能够表示unsigned long
可以表示的所有值。这样的强制转换只能在特殊的上下文中需要,例如使unsigned short
参数具有相应字段说明符的正确类型,或者扩大值以适应其上层的错误位。