C取模运算返回负数的问题

3

我有一个数据类型为 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);
}

返回:

-669207835 => this is the correct option and it should be 7629321670
-480306461

5
为什么你在无符号整数数据上使用浮点数函数? - user2357112
尝试使用result = (z*z* 2) % n - chux - Reinstate Monica
这仍然返回一个负数。 - Kendall Weihe
%d 仅用于打印 int - M.M
3个回答

1
printf("%d\n", result);
//      ^^

%d期望一个int类型的值。你却传递了一个unsigned __int128类型的值,导致未定义的行为。很可能,printf函数将result的一部分表示解释为int类型。

我不知道正确的格式说明符是什么,但你应该找到正确的格式说明符并使用它。此外,你不应该在数据上使用浮点函数,因为那样会导致精度丢失。


当我使用取模运算符时,出现错误:二进制表达式的操作数无效('double'和'double') 无符号__int128 result = (pow(z, 2) * 2) % n; - Kendall Weihe
你是正确的,因为它正在抛出关于__int128类型的警告。 - Kendall Weihe
有指数整数函数吗? - Kendall Weihe
@KendallWeihe:不要用 z ^ 2,应该使用 z * z - user2357112
我想我会写一个splice函数,将__int128中的数字拼接成一个整数数组,然后打印出来。 - Kendall Weihe
@user2357112:整数的指数函数:int powi(int n, int power) { if(power < 0) return 0; else { int ret = 1; while(power--) ret *= n; return ret; } } ;)。 - 3442

0

首先在计算过程中避免浮点数误差。
然后,仅在打印时将结果(小于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'大。


0

首先,__int128GNU CC 扩展,因此没有可移植的方法来处理它们,也没有可移植的方法来打印它们。

恰好,甚至 Glibc 也不支持 printf__int128unsigned __int128 的输出(具有讽刺意味...)。

你唯一的选择是编写自己的函数以十进制或更好的十六进制形式打印它们,因为这种大整数在十进制下很容易变得难以阅读。

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

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

由于"%d"格式说明符期望一个int作为参数,不多不少,也不会有其他。

我希望这为您提供了一些启示!


我想我会写一个splice函数,将数字拼接成一个数组,然后打印出来。 - Kendall Weihe
@KendallWeihe:如果这符合你的方法,那就没问题了;)。 - 3442

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接