我阅读了关于C语言在移位操作中保留进位位的内容,这个信息可以在特定于处理器的.h文件中找到。
这是真的吗?我应该使用这种方法吗?还是我应该自己计算进位位?
我阅读了关于C语言在移位操作中保留进位位的内容,这个信息可以在特定于处理器的.h文件中找到。
这是真的吗?我应该使用这种方法吗?还是我应该自己计算进位位?
在C语言中,没有标准的方法来访问原始操作中的进位位。
你需要在一个更大的数据类型中执行移位操作:
uint16_t foo = ...;
uint32_t tmp = (uint32_t)foo << shift;
uint16_t result = (uint16_t)tmp;
uint16_t carry = (uint16_t)(tmp >> 16);
或者通过执行相反的转移:
uint16_t result = foo << shift;
uint16_t carry = foo >> (16 - shift);
shift == 0
,则此第二种方法将调用未定义的行为。因此,您需要单独处理这种情况。shift
< 0 或 >= 16 无论如何都是未定义行为,而我的第二种方法也意味着 shift == 0
同样是未定义行为。 - Oliver Charlesworth0
可能是可以的。我们都认为uint16_t result = foo << 0
没问题吧?但是uint16_t carry = foo >> 16
不是已经定义了吗? - chux - Reinstate Monicafoo >> 16
是UB。我被困在6.5.7 p4&5中。 - chux - Reinstate Monica标准C不提供对移位操作的进位访问。
一些C实现具有特定于处理器的.h文件或其他扩展,可以允许访问。
在实际应用中,应避免使用来自处理器特定的.h文件或扩展功能。但是如果必须使用,请考虑同时编写C标准解决方案,至少作为文档的一部分。请参见推荐的@Oli Charlesworth解决方案。
通常,要创建有效的可移植代码,可能需要从更高的层面查看问题,并且不使用进位。另一方面,如果这是针对一小范围计算机的,可以使用适合您的(或支付您工资的)方法。
我的早期示例中指出了各种弱点。我现在将其视为依赖于实现。它们已被删除。