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.
The assumption that all *_MAX constants are of the form (2^n)-1
is valid. See 6.2.6 Representations of Types, and particularly 6.2.6.2 Integer types, where the representations of unsigned integer types and the positive values of signed integer types are fully defined as pure binary, thus yielding a maximum which is one less than a power of two.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With