C ++中的双精度(或pow(2,1000)) [英] Double precision in C++ (or pow(2, 1000))
问题描述
我工作的项目欧拉刷上我的C ++编码技能的编程挑战(S),我们就做这个,下学期准备(因为他们不让我们使用Python,嘘!)。
I'm working on Project Euler to brush up on my C++ coding skills in preparation for the programming challenge(s) we'll be having this next semester (since they don't let us use Python, boo!).
我在#16,我想找到一种方法来保持2¹°的真实精度。
I'm on #16, and I'm trying to find a way to keep real precision for 2¹°°°
例如:
int main(){
double num = pow(2, 1000);
printf("%.0f", num):
return 0;
}
列印
10715086071862673209484250490600018105614050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
10715086071862673209484250490600018105614050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
一个缺少大部分的数字(从蟒蛇):
Which is missing most of the numbers (from python):
>>> 2 ** 1000
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376L
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376L
授予,我可以用Python 1内核编写程序
Granted, I can write the program with a Python 1 liner
sum(int(_) for _ in str(2**1000))
立即给出结果,试图找到一种方法来做它在C ++。任何指针? (haha ...)
that gives me the result immediately, but I'm trying to find a way to do it in C++. Any pointers? (haha...)
编辑:
标准libs之外的东西对我来说毫无价值 - - 树的代码是允许在那些比赛,而且我可能不会打印出10,000行的外部代码...
Something outside the standard libs is worthless to me - only dead-tree code is allowed in those contests, and I'm probably not going to print out 10,000 lines of external code...
推荐答案
如果你只是跟踪一个字符数组中的每个数字,这很容易。加倍数字是微不足道的,如果结果大于10,你只减去10和进位添加到下一位。从值1开始,循环加倍功能1000次,你就完成了。你可以预测你需要用 CEIL的位数(1000 *日志(2)/日志(10))
,或者只是添加它们动态。
If you just keep track of each digit in a char array, this is easy. Doubling a digit is trivial, and if the result is greater than 10 you just subtract 10 and add a carry to the next digit. Start with a value of 1, loop over the doubling function 1000 times, and you're done. You can predict the number of digits you'll need with ceil(1000*log(2)/log(10))
, or just add them dynamically.
垃圾邮件提醒:它显示我必须在任何人都相信我之前显示代码。这是一个带有两个函数Double和Display的bignum的简单实现。为了简单起见,我没有把它做成一个类。数字被存储在一个小尾数格式,用最少的显著位在先。
Spoiler alert: it appears I have to show the code before anyone will believe me. This is a simple implementation of a bignum with two functions, Double and Display. I didn't make it a class in the interest of simplicity. The digits are stored in a little-endian format, with the least significant digit first.
结果
结果
结果
typedef std::vector<char> bignum;
void Double(bignum & num)
{
int carry = 0;
for (bignum::iterator p = num.begin(); p != num.end(); ++p)
{
*p *= 2;
*p += carry;
carry = (*p >= 10);
*p -= carry * 10;
}
if (carry != 0)
num.push_back(carry);
}
void Display(bignum & num)
{
for (bignum::reverse_iterator p = num.rbegin(); p != num.rend(); ++p)
std::cout << static_cast<int>(*p);
}
int main(int argc, char* argv[])
{
bignum num;
num.push_back(1);
for (int i = 0; i < 1000; ++i)
Double(num);
Display(num);
std::cout << std::endl;
return 0;
}
这篇关于C ++中的双精度(或pow(2,1000))的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!