中间乘法的值通常需要比输入多两倍的位数。
// Example
int foo(int a, int b, int carry, int rem) {
int2x c; // Some type that is twice as wide at `int`
c = (int2x)a * b + carry;
return (int) (c % rem);
}
考虑到填充的潜在可能性(似乎限制了sizeof()
的有用性)和非二进制补码整数(限制了位操作),...
以下代码是否总是创建所需的类型?(当它存在时。)
如果不是,如何编写至少合理的解决方案,即使不完全可移植?
#include <limits.h>
#include <stdint.h>
#if LONG_MAX/2/INT_MAX - 2 == INT_MAX
typedef long int2x;
typedef unsigned long unsigned2x;
#elif LLONG_MAX/2/INT_MAX - 2 == INT_MAX
typedef long long int2x;
typedef unsigned long long unsigned2x;
#elif INTMAX_MAX/2/INT_MAX - 2 == INT_MAX
typedef intmax_t int2x;
typedef uintmax_t unsigned2x;
#else
#error int2x/unsigned2x not available
#endif
[编辑]
如果long
,long long
和intmax_t
都不起作用,那么可以使用#error
。我想知道的是,如果至少有一个long
,long long
或intmax_t
有效,那么int2x
是否会被正确地输入?
注:以上假设xxx_MAX
是某些奇数2的幂减1。这可能是一个好的假设吗?以上在至少两个平台上运行良好,但这并不是很好的可移植性测试。
long long
来保险呢?毕竟你最后还是要将其强制转换回int
,那么在中间变量上节省开销又有什么意义呢? - barak manosINT_MAX
与INT16_MAX
和INT32_MAX
进行比较,以确定int
是16
还是32
位宽度。然后分别为int2x
使用int_least32_t
或int_least64_t
。 - Jens Gustedtint16_t
等)呢? - Oliver Charlesworthint
、long
和long long
都可以完全相同的大小(只要它们是64位或更大)。在这种情况下,您可以自己将乘法分解为半大小的单元,而不是使用#error
。 - R.. GitHub STOP HELPING ICE#else #error
难道不能捕获“类型...必须存在。”吗?3)考虑使用UINT16_MAX/UINT32_MAX
方法,但这会导致预处理器出现问题。应该重新考虑INT16_MAX/INT32_MAX
方法。除了它无法处理18/36位int
和其他非2次幂宽度之外,它似乎更为直接,我认为这些在今天很少见,但我不确定。 - chux - Reinstate Monica