【问题标题】:C modulus returning negative numberC 模数返回负数
【发布时间】:2016-02-10 18:58:22
【问题描述】:

我的数据类型为 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

【问题讨论】:

  • 为什么对无符号整数数据使用浮点函数?
  • 试试result = (z*z* 2) % n
  • 这仍然返回负数
  • %d 仅用于打印int

标签: c int modulus negative-number int128


【解决方案1】:
printf("%d\n", result);
//      ^^

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

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

【讨论】:

  • 当我使用取模运算符时出现错误:二进制表达式的无效操作数 ('double' 和 'double') unsigned __int128 result = (pow(z, 2) * 2) % n;
  • 你是对的,因为它抛出了关于 __int128 类型的警告
  • 有指数整数函数吗?
  • @KendallWeihe:不。使用z * z
  • 我想我要做的就是写一个拼接函数,将 __int128 中的数字拼接成一个整数数组,然后打印出来
【解决方案2】:

首先要避免计算过程中的浮点跳闸。
然后,仅用于打印,将结果(即

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' 大)

【讨论】:

    【解决方案3】:

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

    事实上,对于printfing()、__int128s 和 unsigned __int128s,甚至没有来自 Glibc 的支持(具有讽刺意味的是......)。

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

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

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

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

    我希望这对你有所启发!

    【讨论】:

    • 我想我会写一个拼接函数,将数字拼接成一个数组,然后打印数组
    • @KendallWeihe:如果这符合你的方法,那没关系;)。
    猜你喜欢
    • 1970-01-01
    • 2013-09-21
    • 2021-10-11
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多