C++ 大数的位数之和(10^9)?
我试图解决这个特殊的问题:: 2^15=32768,其位数之和为3+2+7+6+8=26。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^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