Values of intermediate multiplication typically need twice the number of bits as inputs.
// 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);
}
Considering the potential for padding, (which appears to limit sizeof()
usefulness) and non-2`s complement integers (which limits bit dibbling), ...
Does the following always create the needed type?
If not, how to code at least a reasonable solution, even if not entirely portable?
#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
[Edit]
Qualify:"always", if long
, long long
and intmax_t
, do not work it is OK to #error
.
What I want to know is if at least 1 of long
, long long
, or intmax_t
will work, will int2x
be correctly typed?
Notes: The above assumes xxx_MAX
are some odd power-of-2 minus 1. Maybe a good assumption? The above works on at least 2 platforms, but that is hardly a great portability test.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…