C 取模返回负数

C modulus returning negative number

我的数据类型是 unsigned __int128 data;,所以我认为这不是类型问题,但我不知道为什么会这样

#include <stdio.h>

int main(int argc, char *argv[]) {
    unsigned __int128 z = 1911602146;
    unsigned __int128 n = 4003562209;

    //case 1
        unsigned __int128 result = fmod((pow(z, 2)  * 2), n);
        printf("%d\n", result);

    //case 2
        unsigned __int128 result_2 = fmod(pow(z, 2), n);
        printf("%d\n", result_2);
}

returns:

-669207835 => this is the correct option and it should be 7629321670
-480306461
printf("%d\n", result);
//      ^^

%d 期望 int。您将 unsigned __int128 传递给它,从而导致未定义的行为。最有可能的是,printf 参与了 result 的表示并将其解释为 int.

我不知道正确的格式说明符是什么,但您应该找到正确的格式说明符并使用它。此外,您不应该对数据使用浮点函数;你在那里失去了精度。

首先,__int128 是一个 GNU CC extension,因此没有可移植的方式来处理它们,也没有可移植的方式来打印它们。

碰巧的是,printfing()、__int128s 和 unsigned __int128s 都没有(具有讽刺意味的是...)支持,甚至来自 Glibc。

您唯一的选择是编写自己的函数以十进制或更好的十六进制打印出来,因为这种大整数很容易在十进制中变得非常难读。

顺便说一句,这是未定义的行为:

printf("%d\n", result);

因为 "%d" 说明符需要一个 int 作为参数,仅此而已,仅此而已。

希望这对您有所启发!

首先要避免计算时的浮点跳闸。
然后,仅用于打印,将结果(< 10^10)转换为 double 以便使用 printf 函数

unsigned __int128 z = 1911602146;
unsigned __int128 n = 4003562209;

unsigned __int128 result = (z * z * 2) % n;
printf("%.0lf\n", (double)result);

unsigned __int128 result_2 = (z * z) % n;
printf("%.0lf\n", (double)result_2);

那应该给你

3625759213
3814660711

(结果你无法得到 7629321670,因为它比取模操作数大,'n')