【问题标题】:I am using modulo operator, but it still giving me a negative number我正在使用模运算符,但它仍然给我一个负数
【发布时间】:2022-01-17 07:27:36
【问题描述】:

我正在尝试用 c++ 解决编程问题(版本:(MinGW.org GCC Build-2) 9.2.0)
我正在使用模运算符在 int 范围内给出答案,但对于 6,它给了我 -ve 答案
为什么会发生这种情况??
我的代码:

#include <cmath>
#include <iostream>

using namespace std;

int balancedBTs(int h) {
    if (h <= 1) return 1;
    
    int x = balancedBTs(h - 1);
    int y = balancedBTs(h - 2);
    int mod = (int)(pow(10, 9) + 7);
    
    int temp1 = (int)(((long)(x) * x) % mod);
    int temp2 = (int)((2 * (long)(x) * y) % mod);

    int ans = (temp1 + temp2) % mod;
    
    return ans;
}
int main()
{
    int h;
    cin >> h;
    cout << balancedBTs(h) << endl;
    return 0;
}

输出:

【问题讨论】:

  • 您的示例中没有输出,因此很难知道这些值的来源。复制问题的xy 的值是什么?考虑将minimal reproducible example 放在一起。
  • 如果(temp1 + temp2) 是负数,那么% 将返回负数。
  • 扩展 Retired Ninja 所说的内容:您的代码比演示问题所需的复杂大约 10 倍,因为它使用递归函数和cin,而您没有告诉我们您在标准输入中键入的数字。真正的 MRE 应该是这样的:int main() { return -5 % 4; },你会问为什么它返回 -1 而不是 3。答案是 % 就是这样设计的。
  • 假设您在 Windows 上,intlong 都是 32 位。如果将 long 替换为 int64_t,则结果为 878720798。

标签: c++ modulo


【解决方案1】:

代码做了两个隐含的假设:

  • int 至少为 32 位(否则 mod 的 1,000,000,007 将不适合)
  • long 大于 int(避免乘法溢出)

这些假设均不受标准https://en.cppreference.com/w/cpp/language/types 的保证

我无法访问问题中的同一个平台,但如果我在 temp1 和 temp2 的分配中删除强制转换为 long,我可以准确地重现输出(有效地模拟平台是 sizeof int 和 long 都是4).

您可以通过检查 sizeof(int) 和 sizeof(long) 来验证第二个假设是否适用于您的平台。

【讨论】:

  • 是的,在 32 位系统中它工作正常
  • 是的,第二个假设是正确的,谢谢。
猜你喜欢
  • 1970-01-01
  • 2022-12-12
  • 1970-01-01
  • 1970-01-01
  • 2022-07-09
  • 2022-09-23
  • 1970-01-01
  • 2015-07-21
  • 1970-01-01
相关资源
最近更新 更多