Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.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++ 大数的位数之和(10^9)?_C++ - Fatal编程技术网

C++ 大数的位数之和(10^9)?

C++ 大数的位数之和(10^9)?,c++,C++,我试图解决这个特殊的问题:: 2^15=32768,其位数之和为3+2+7+6+8=26。 数字2^1000的数字之和是多少 然而,互联网提到的正确答案是1366,而不是我得到的1181。问题是不是关于第一次计算: long double n = pow(2, num); 因为即使是常规的doubletype()也将保持2^1000=1.07151e+301,没有任何问题,特别是这是一个基数2计算 请注意,您使用的是double版本pow()、fmod()和floor(),而不是长的doubl

我试图解决这个特殊的问题::

2^15=32768,其位数之和为3+2+7+6+8=26。
数字2^1000的数字之和是多少


然而,互联网提到的正确答案是
1366
,而不是我得到的
1181

问题是不是关于第一次计算:

long double n = pow(2, num);
因为即使是常规的
double
type()也将保持
2^1000=1.07151e+301
,没有任何问题,特别是这是一个基数2计算

请注意,您使用的是
double
版本
pow()
fmod()
floor()
,而不是
长的double
版本
powl()
fmodl()
floorl()
。但正如我所说,这不是问题所在,不会改变任何事情

但是while循环中的计算将缺少精度和舍入误差。此外,在使用浮点数进行算术运算时,千万不要检查浮点数是否相等,请参阅(网络上还有很多关于该主题的讨论和帖子)

简而言之:
我假设您的
fmod()
floor()
将导致精度损失和舍入错误


下面是一个有效的解决方案(),用于将
double
转换为
std::string
,并迭代字符串的每个字符,将转换为整数的字符相加

简而言之:
它只是使用初始计算(仅使用
double
)并将其转换为字符串

#include <iostream>
#include <cmath>

int main ()
{
   int num;
   std::cin >> num;
   double n = pow(2, num); /* note I use just double */

   std::string nstr = std::to_string(n);
   const char* nstr_p = nstr.c_str();

   std::cout << std::fixed << nstr << std::endl;
   int sum = 0;
   while (std::isdigit(*nstr_p)) /* number contains dot and fractional (.0000) */
   {
      sum = sum + (*nstr_p - '0'); /* convert character to integer and sum it */
      nstr_p++;
   }
   std::cout << sum << std::endl;
}

注意:转换:<代码>(*NSTRYP-‘0’)< /C> >假设一个编码类似或其它,其中数字在其十六进制表示中没有间隙增加。

< P>这里是使用GMP的多精度整数运算(注释GMPX.H)的C++方法。 如果可能的话,我更喜欢整数,gmp使处理大整数变得足够容易

和Andre一样,我创建了结果的std::字符串,并添加了数字


环境:

Ubuntu 15.10,64位,使用g++-5,版本为v5.2.1,在较旧的Dell上


代码:


JFF(只是为了好玩)并且因为mpz_课程很简单:

2 ^ 10000  size: 3011  

19,950,631, ... ,596,709,376

sum-of-digits: 13,561



2 ^ 100000  size: 30103  

9,990,020, ... ,883,109,376

sum-of-digits: 135,178

你忘了问问题了。不要粘贴文本图片,请自行粘贴文本检查double是否完全(不)等于某个值将永远不会起作用。不要在这些计算中使用浮点数学,因为它没有精度。您需要创建一个简单的长数字类。您必须检查所使用的
long double
的最大值是多少。它是
LDBL\u MAX
中的常量C@Sma2 ^ 1000需要1000位的精度,我怀疑他的<代码>长双< /代码>是Bigi@ truthSt寻,如果这个或任何答案已经解决了你的问题,请考虑点击复选标记。这向更广泛的社区表明,你已经找到了一个解决方案,并给回答者和你自己带来了一些声誉。没有义务这样做。
#include <iostream>
#include <cmath>

int main ()
{
   int num;
   std::cin >> num;
   double n = pow(2, num); /* note I use just double */

   std::string nstr = std::to_string(n);
   const char* nstr_p = nstr.c_str();

   std::cout << std::fixed << nstr << std::endl;
   int sum = 0;
   while (std::isdigit(*nstr_p)) /* number contains dot and fractional (.0000) */
   {
      sum = sum + (*nstr_p - '0'); /* convert character to integer and sum it */
      nstr_p++;
   }
   std::cout << sum << std::endl;
}
1366
#include <chrono>
// 'compressed' chrono access --------------vvvvvvv
typedef std::chrono::high_resolution_clock  HRClk_t; // std-chrono-hi-res-clk
typedef HRClk_t::time_point                 Time_t;  // ...-time-point
typedef std::chrono::milliseconds           MS_t;    // std-chrono-milliseconds
typedef std::chrono::microseconds           US_t;    // std-chrono-microseconds
typedef std::chrono::nanoseconds            NS_t;    // std-chrono-nanoseconds
using   namespace std::chrono_literals; // support suffixes like 100ms, 2s, 30us
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <cassert>

#include <gmpxx.h>  // multiprecision arithmetic:
                    // no rounding errors because mpz_class is integer

class T526_t
{
public:
   T526_t() = default;
   ~T526_t() = default;

   int exec()
      {
         Time_t start_us = HRClk_t::now();

         mpz_class  N("1"); // initialize multi-precision integer to value 1

         std::string s;
         int i;
         for (i=0; true; ++i) // run forever
         {
            std::stringstream ss;
            ss << N;              // stream i/o from gmpxx.h
            N = N * 2;            // compute next value

            if(i <= 16) // confirm the first 17 values
            {
               std::cout << "\n"
                         << "  2 ^" << std::setw(3) << i
                         << "  size:" << std::setw(2) << ss.str().size()
                         << "  " << digiComma(ss.str())
                         << "  sum : " << sumOfDigits(ss.str());
            }
            s = ss.str();

            if (1000 == i) break; // enough already
         }

         std::cout << "\n\n"
                   << "  2 ^" << std::setw(5) << i
                   << "  size:" << std::setw(4) << s.size()
                   << "  \n\n" << digiComma(s)
                   << "\n\n  sum-of-digits: " << sumOfDigits(s) << std::endl;

         auto duration_us =
            std::chrono::duration_cast<US_t>(HRClk_t::now() - start_us);

         std::cout << "\n\n  duration: "
                   << digiComma(std::to_string(duration_us.count()))
                   << " us" << std::endl;

         return (0);
      }


private: // methods

   size_t sumOfDigits(std::string s)
      {
         size_t retVal = 0;
         for (uint i=0; i<s.size(); ++i)
         {
            retVal += s[i] - '0';
         }
         return retVal;
      }

   std::string digiComma(std::string s)
      {  //vvvvv--sSize must be signed int of sufficient size
         int32_t sSize = static_cast<int32_t>(s.size());
         if (sSize > 3)
            for (int32_t indx = (sSize - 3); indx > 0; indx -= 3)
               s.insert(static_cast<size_t>(indx), 1, ',');
         return(s);
      }


}; // class T526_t


int main(int , char** )
{
   Time_t start_us = HRClk_t::now();

   int retVal = -1;
   {
      T526_t   t526;
      retVal = t526.exec();
   }

   auto  duration_us =
      std::chrono::duration_cast<US_t>(HRClk_t::now() - start_us);

   std::cout << "\n  FINI   " << duration_us.count() << " us" << std::endl;
   return(retVal);
}
Rule-526: dumy526.cc
rm -f dumy526
g++-5 -m64  -O0 -ggdb -std=c++14 -Wall -Wextra -Wshadow -Wnon-virtual-dtor
                -pedantic -Wcast-align -Wcast-qual -Wconversion -Wpointer-arith
                -Wunused -Woverloaded-virtual   dumy526.cc  -o dumy526
                -L../../bag  -lbag_i686  -lgmpxx -lgmp

real    0m2.235s
user    0m1.992s
sys 0m0.208s

  2 ^  0  size: 1  1  sum : 1
  2 ^  1  size: 1  2  sum : 2
  2 ^  2  size: 1  4  sum : 4
  2 ^  3  size: 1  8  sum : 8
  2 ^  4  size: 2  16  sum : 7
  2 ^  5  size: 2  32  sum : 5
  2 ^  6  size: 2  64  sum : 10
  2 ^  7  size: 3  128  sum : 11
  2 ^  8  size: 3  256  sum : 13
  2 ^  9  size: 3  512  sum : 8
  2 ^ 10  size: 4  1,024  sum : 7
  2 ^ 11  size: 4  2,048  sum : 14
  2 ^ 12  size: 4  4,096  sum : 19
  2 ^ 13  size: 4  8,192  sum : 20
  2 ^ 14  size: 5  16,384  sum : 22
  2 ^ 15  size: 5  32,768  sum : 26
  2 ^ 16  size: 5  65,536  sum : 25

  2 ^ 1000  size: 302  

10,715,086,071,862,673,209,484,250,490,600,018,105,614,048,117,055,336,074,437,
503,883,703,510,511,249,361,224,931,983,788,156,958,581,275,946,729,175,531,468,
251,871,452,856,923,140,435,984,577,574,698,574,803,934,567,774,824,230,985,421,
074,605,062,371,141,877,954,182,153,046,474,983,581,941,267,398,767,559,165,543,
946,077,062,914,571,196,477,686,542,167,660,429,831,652,624,386,837,205,668,069,
376

  sum-of-digits: 1366


  duration: 4,569 us

  FINI   4616 us
2 ^ 10000  size: 3011  

19,950,631, ... ,596,709,376

sum-of-digits: 13,561



2 ^ 100000  size: 30103  

9,990,020, ... ,883,109,376

sum-of-digits: 135,178