两个无符号整数相乘作为一个无符号整数
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 的结果一致。
我有以下 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 的结果一致。