【问题标题】:Modulo returns wrong result when using negatives使用负数时取模返回错误的结果
【发布时间】:2012-12-26 11:17:36
【问题描述】:

我想计算: (-15 % 3) 这应该是 0 但我得到的是 1:

当我明确这样做时:

int IntFcn (const void *key, size_t tableSize)
{
    printf("%d\n",(*(int*)key)); // prints -15
    printf("%d\n",tableSize); // prints 3
    printf("%d\n",(-15) % 3); // prints 0
}

我得到了正确的结果 (0),但是当我尝试使用下面的变量时,我得到 1:

int IntFcn (const void *key, size_t tableSize)
{
    printf("%d\n",(*(int*)key)); // prints -15
    printf("%d\n",tableSize); // prints 3
    printf("%d\n",((*(int*)key) % tableSize)); // prints 1
    return ((*(int*)key) % tableSize);
}

为什么会这样?

【问题讨论】:

  • 你能告诉我们你是如何调用所有这些函数的吗?
  • 不要将 size_t 参数打印为“%d”。转换为 (unsigned int) 并使用“%u”规范,或使用“%zu”规范。注意:printf() 是一个可变参数函数,所以你应该非常小心参数的类型。

标签: c modulo


【解决方案1】:

在您的第二种情况下,模的第二个操作数是无符号整数,因此第一个操作数在执行模之前也被提升为无符号。所以结果将是 (unsigned)(-15) % 3 等于(对于 32 位 int)到 4294967281 % 3 == 1

【讨论】:

  • 如果我想让它在两台 32/64 位机器上工作,我该如何克服这个问题?
  • 与 32/64 位无关。这是有符号/无符号算术运算的问题。当您不期望它时,您的操作数被提升为无符号。显式转换为 int 以防止效果:((*(int*)key) % (int)tableSize)
  • 我建议,假设 tablesize 在 64 位机器上可能会变大 [因此使用 size_t?],使用转换为 long 将是比 int 更好的选择。但否则同意。
  • @MatsPetersson 我大体上同意。但在这种情况下,它可能没问题,因为该表的键是 int
【解决方案2】:

试试这个..

return ((*(int*)key) % (int)tableSize);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-04
    • 2013-01-11
    • 1970-01-01
    相关资源
    最近更新 更多