Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 欧拉计划+#97模块化指数不起作用_C_Modular Arithmetic - Fatal编程技术网

C 欧拉计划+#97模块化指数不起作用

C 欧拉计划+#97模块化指数不起作用,c,modular-arithmetic,C,Modular Arithmetic,我正试图从Hackerrank解决这个问题。该问题要求计算A x B**C+D的最后12位数字。我的尝试是使用模块求幂mod10**12from,以便有效地计算最后12位数字并避免溢出。然而,除了样本2x3**4+5之外的所有情况,我都错了。根据约束条件,无符号long-long不应有溢出 问题是: 现在我们想学习如何计算这些大数字的最后几位。假设我们有很多数字a x B**C+D,我们想知道这些数字的最后12位 约束条件: 一,≤ T≤ 五十万 一,≤ A、 B、C、D≤ 10**9 输

我正试图从Hackerrank解决这个问题。该问题要求计算
A x B**C+D
的最后12位数字。我的尝试是使用模块求幂mod
10**12
from,以便有效地计算最后12位数字并避免溢出。然而,除了样本
2x3**4+5
之外的所有情况,我都错了。根据约束条件,
无符号long-long
不应有溢出


问题是:

现在我们想学习如何计算这些大数字的最后几位。假设我们有很多数字
a x B**C+D
,我们想知道这些数字的最后12位

约束条件

  • 一,≤ T≤ 五十万
  • 一,≤ A、 B、C、D≤ 10**9
输入:第一行包含一个整数T-测试数。 T行后面各包含4个整数(A、B、C和D)

输出:只输出一行,其中正好包含12位数字-所有结果总和的最后12位数字。如果总和小于
10**12
则打印相应数量的前导零


我在C语言中的尝试

#include <stdio.h>

int main() {
    const unsigned long long limit = 1000000000000;
    int cases;
    for (scanf("%d", &cases); cases; --cases) {
        // mult = A, base = B, exp = C, add = D
        unsigned long long mult, base, exp, add;
        scanf("%llu %llu %llu %llu", &mult, &base, &exp, &add);
        base = base % limit;
        while (exp) {
            if (exp & 1) {
               mult = (mult * base) % limit;
            }
            exp >>= 1;
            base = (base * base) % limit;
        }
        printf("%012llu\n", (mult + add) % limit);
    }
    return 0;
}
#包括
int main(){
常量无符号长限=10000000000;
int案例;
对于(scanf(“%d”,&cases);cases;--cases){
//mult=A,base=B,exp=C,add=D
无符号长mult、base、exp、add;
scanf(“%llu%llu%llu%llu”、&mult、&base、&exp、&add);
基数=基数百分比限值;
while(exp){
if(exp&1){
mult=(mult*基本)%limit;
}
exp>>=1;
基数=(基数*基数)%限值;
}
printf(“%012llu\n”,(mult+add)%limit);
}
返回0;
}

我认为您可以溢出无符号长-长数学(例如-模2^64),因为您在内部循环中对基的计算可以高达(10^12-1)^2~=10^24~=2^79.726,远远超过2^64。例如,考虑B=10^6-1和C=4

在运行64b版本Mac OS X和clang 8.1.0的MacBook Pro上:

#include <stdio.h>

int main()
{
  fprintf(stdout, "sizeof(unsigned long long) = %u\n", (unsigned) sizeof(unsigned long long));
  fprintf(stdout, "sizeof(__uint128_t) = %u\n", (unsigned) sizeof(__uint128_t));
  fprintf(stdout, "sizeof(long double) = %u\n", (unsigned) sizeof(long double));

  return 0;
}
如果你的平台长时间显示16或10,那么我认为你是清楚的。如果它像我的答案一样写着8,那么你需要重新编写你的答案,要么以本机方式强制128b(或80b)整数数学,要么以其他方式模拟它

您可以尝试uu uint128\t,它由gcc和clang支持。否则,您需要求助于长双精度和fmodl()之类的方法,它们可能有足够的尾数位,但可能无法给出您想要的准确答案

此外,您也不会像任务所说的那样累积多个结果。这是我根据您的程序拍摄的照片,但使用的是uint128

#include <stdio.h>
#include <stdlib.h>

#define BILLION     1000000000
#define TRILLION 1000000000000

int main() 
{
  const __uint128_t limit = TRILLION;
  unsigned long     cases = 0;
  __uint128_t       acc   = 0;

  if (scanf("%lu", &cases) != 1 || cases == 0 || cases > 500000)
    abort();

  while (cases-- > 0)
  {            
    unsigned long a, b, c, d;
    __uint128_t b2c = 1, bbase;

    if (scanf("%lu %lu %lu %lu", &a, &b, &c, &d) != 4 ||
        a == 0 || a > BILLION || b == 0 || b > BILLION || 
        c == 0 || c > BILLION || d == 0 || d > BILLION)
      abort();

    for (bbase = b; c > 0; c >>= 1) 
    {
      if ((c & 0x1) != 0)
        b2c = (b2c * bbase) % limit;    // 64b overflow: ~10^12 * ~10^12 ~= 10^24 > 2^64

      bbase = (bbase * bbase) % limit;  // same overflow issue as above
    }

    // can do modulus on acc only once at end of program instead because
    // 5 * 10^5 * (10^9 * (10^12 - 1) + 10^9) = 5 * 10^26 < 2^128

    acc += a * b2c + d;  
  }

  acc %= limit;

  printf("%012llu\n", (unsigned long long) acc);

  return 0;
}
#包括
#包括
#定义十亿亿
#定义万亿亿
int main()
{
const uu uint128 u t limit=万亿;
无符号长案例=0;
__uint128_t acc=0;
如果(扫描频率(“%lu”,&cases)!=1 | | cases==0 | | cases>500000)
中止();
而(案例-->0)
{            
无符号长a、b、c、d;
__uint128_t b2c=1,bbase;
如果(扫描频率(“%lu%lu%lu%lu”、&a、&b、&c、&d)!=4||
a==0 | a>10亿| b==0 | b>10亿|
c==0 | c>10亿| d==0 | d>10亿)
中止();
对于(bbase=b;c>0;c>>=1)
{
如果((c&0x1)!=0)
b2c=(b2c*bbase)%limit;//64b溢出:~10^12*~10^12~=10^24>2^64
bbase=(bbase*bbase)%limit;//与上述溢出问题相同
}
//在程序结束时只能对acc执行一次模数转换,因为
// 5 * 10^5 * (10^9 * (10^12 - 1) + 10^9) = 5 * 10^26 < 2^128
acc+=a*b2c+d;
}
acc%=限额;
printf(“%012llu\n”,(无符号长)acc);
返回0;
}

我认为您可以溢出无符号长-长数学(例如-模2^64),因为您在内部循环中对基的计算可以高达(10^12-1)^2~=10^24~=2^79.726,远远超过2^64。例如,考虑B=10^6-1和C=4

在运行64b版本Mac OS X和clang 8.1.0的MacBook Pro上:

#include <stdio.h>

int main()
{
  fprintf(stdout, "sizeof(unsigned long long) = %u\n", (unsigned) sizeof(unsigned long long));
  fprintf(stdout, "sizeof(__uint128_t) = %u\n", (unsigned) sizeof(__uint128_t));
  fprintf(stdout, "sizeof(long double) = %u\n", (unsigned) sizeof(long double));

  return 0;
}
如果你的平台长时间显示16或10,那么我认为你是清楚的。如果它像我的答案一样写着8,那么你需要重新编写你的答案,要么以本机方式强制128b(或80b)整数数学,要么以其他方式模拟它

您可以尝试uu uint128\t,它由gcc和clang支持。否则,您需要求助于长双精度和fmodl()之类的方法,它们可能有足够的尾数位,但可能无法给出您想要的准确答案

此外,您也不会像任务所说的那样累积多个结果。这是我根据您的程序拍摄的照片,但使用的是uint128

#include <stdio.h>
#include <stdlib.h>

#define BILLION     1000000000
#define TRILLION 1000000000000

int main() 
{
  const __uint128_t limit = TRILLION;
  unsigned long     cases = 0;
  __uint128_t       acc   = 0;

  if (scanf("%lu", &cases) != 1 || cases == 0 || cases > 500000)
    abort();

  while (cases-- > 0)
  {            
    unsigned long a, b, c, d;
    __uint128_t b2c = 1, bbase;

    if (scanf("%lu %lu %lu %lu", &a, &b, &c, &d) != 4 ||
        a == 0 || a > BILLION || b == 0 || b > BILLION || 
        c == 0 || c > BILLION || d == 0 || d > BILLION)
      abort();

    for (bbase = b; c > 0; c >>= 1) 
    {
      if ((c & 0x1) != 0)
        b2c = (b2c * bbase) % limit;    // 64b overflow: ~10^12 * ~10^12 ~= 10^24 > 2^64

      bbase = (bbase * bbase) % limit;  // same overflow issue as above
    }

    // can do modulus on acc only once at end of program instead because
    // 5 * 10^5 * (10^9 * (10^12 - 1) + 10^9) = 5 * 10^26 < 2^128

    acc += a * b2c + d;  
  }

  acc %= limit;

  printf("%012llu\n", (unsigned long long) acc);

  return 0;
}
#包括
#包括
#定义十亿亿
#定义万亿亿
int main()
{
const uu uint128 u t limit=万亿;
无符号长案例=0;
__uint128_t acc=0;
如果(扫描频率(“%lu”,&cases)!=1 | | cases==0 | | cases>500000)
中止();
而(案例-->0)
{            
无符号长a、b、c、d;
__uint128_t b2c=1,bbase;
如果(扫描频率(“%lu%lu%lu%lu”、&a、&b、&c、&d)!=4||
a==0 | a>10亿| b==0 | b>10亿|
c==0 | c>10亿| d==0 | d>10亿)
中止();
对于(bbase=b;c>0;c>>=1)
{
如果((c&0x1)!=0)
b2c=(b2c*bbase)%limit;//64b溢出:~10^12*~10^12~=10^24>2^64
bbase=(bbase*bbase)%limit;//与上述溢出问题相同
}
//在程序结束时只能对acc执行一次模数转换,因为
// 5 * 10^5 * (10^9 * (10^12 - 1) + 10^9) = 5 * 10^26 < 2^128
acc+=a*b2c+d;
}
acc%=限额;
printf(“%012llu\n”,(无符号长)acc);
返回0;
}
(mult*base)%limit
真的吗?非
((多个百分比限制)*(基本百分比限制))%limit