两个无符号整数相乘作为一个无符号整数

Multiplication of two unsigned integers as an unsigned int

我有以下 C 函数,它在 GPU 上对 32 位无符号整数执行一些乘法和位移。假设我从值 X = 0 和 C = 2 开始:

void MWC64X_Step(global mwc64x_state_t *s)
{
    uint X=s->x, C=s->c;
    printf("X = %u, C = %u, ", X, C);
    uint Xn=MWC64X_A*X+C;
    uint carry=(uint)(Xn<C); //The (Xn<C) will be zero or one for scalar
    uint Cn=mad_hi(MWC64X_A,X,carry);
    printf("Xn = %u, Cn = %u, ", Xn, Cn);
    s->x=Xn;
    s->c=Cn;
}

typedef struct{ uint x; uint c; } mwc64x_state_t;

enum{ MWC64X_A = 4294883355U };
enum{ MWC64X_M = 18446383549859758079UL };

该函数是我在网上找到的一个包的一部分。我很想知道 X 是否变得非常非常大,达到 2^32 的数量级,因为 Xn 被声明为无符号整数(在我的平台上是 32 位),那么它是如何计算的? Xn 是只保留模 MAX_INT_32 的值,还是执行一些其他操作?

我从 X=0 和 C=2 的几个连续运行中得到的结果:

Xn = 2, Cn = 0, 
Xn = 4294799414, Cn = 1, 
Xn = 1207281075, Cn = 4294715476. <--- 3rd iteration

谢谢,

常数 MWC64X_A = 4294883355U 等于 -83941 mod 2^32.

2 * (-83941) + 0 = -167882,等于 4294799414 mod 2^32.

(-167882) * (-83941) = 14092182962,等于 1207281074 mod 2^32(根据 Excel)和 1207281074 + 1 = 1207281075。所以结果你得到的结果与每次乘法 modulo 2^32 的结果一致。