【问题标题】:Why does modular exponentiation go wrong when we change datatype of variable "u" from long long to int?当我们将变量“u”的数据类型从 long long 更改为 int 时,为什么模幂运算会出错?
【发布时间】:2019-07-09 15:44:07
【问题描述】:

当变量“u”的数据类型很长时,模幂运算很好,但是当它更改为 int 时,它给出了错误的答案。

例如,当 (2,447,1e9+7) 作为参数传递时,“long long u”给出 941778035 作为答案,但“int u”给出 0 作为答案。功能如下:-

int modpow(int x, int n, int m) {  //to calculate x^n%m
    if (n == 0) return 1%m;
    long long u = modpow(x,n/2,m);
    u = (u*u)%m;
    if (n%2 == 1) u = (u*x)%m;
    return u;
}
int modpow(int x, int n, int m) {  //to calculate x^n%m
    if (n == 0) return 1%m;
    int u = modpow(x,n/2,m);
    u = (u*u)%m;
    if (n%2 == 1) u = (u*x)%m;
    return u;
}
int main(){    //used as main in program with x = 2 and m = 1e9+7 and n is given by user
   int n, m = 1e9+7;
   cin>>n;
   int pow = modpow(2,n,m);
   cout<<pow;
   return 0;
}

【问题讨论】:

  • 在你的编译器上,int 和 longlong 有多大?它们都是63位的吗? (u*x)(u*u) 的每个可能值都适合数据类型吗? (u*x)%m 是否总是将其恢复到适合下一轮的新值?
  • 之前我的主要功能是错误的,现在我已经更新了,很抱歉给您带来不便...
  • 1000000006 * 1000000006 有 60 个二进制数字。
  • 如果在执行u = (u*u)%m; 之前添加此assert(u &lt;= static_cast&lt;decltype(u)&gt;(std::sqrt(std::numeric_limits&lt;decltype(u)&gt;::max())));,您可以确保计算不会超出变量的容量。
  • @molbdnilo 但我们从未乘以幂,即 n = 1e9+7 就像我们乘以 u 和 x

标签: c++ integer long-integer modular-arithmetic


【解决方案1】:

想想modpow(1e9, 2, 1e9+7)

if (2 == 0) // no
int u = modpow(1e9, 1, 1e9+7);

  if (1 == 0) // no
  int u = modpow(1e9, 0, 1e9+7);

    if (0 == 0) return 1;

  int u = 1;
  u = 1; // (1*1) % (1e9+7)
  if (1 % 2 == 1) u = 1e9; // (1 * 1e9) % (1e9+7)

int u = 1e9;
u = (1e9 * 1e9)%(1e9+7); // OUCH!

如果int u 仅 32 位宽,则

1e9 * 1e9 溢出, 大多数现代计算机环境都是这种情况(请参阅https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-06
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 2019-09-22
    • 1970-01-01
    相关资源
    最近更新 更多