计算2^1000/2^10000的各位数和

2^1000在各进制的表示:

2进制: 1000.....(共跟1000个0)

8进制:  2000....(共跟333个0)

16进制: 10000...(共跟250个0)

二进制转十进制的计算过程等于:2*2*2....(共1000个2相乘)

考虑到相乘的结果比较大=(2^10)^100=(1024)^100 >= (1000)^100 = 1000..(后面300个0)

精确计算的话,现有的类型是不能满足的。

所以我们一般使用 char* 来存储相关的值,并进行相关计算:

2^2 = 2+2 = 4

2^3 = 4+4 = 8

2^4 = 8+8 = 16

2^5 = 16 + 16 = 32

...

2^1000 相当于经过999次加法计算即可得出。我们只要开发逐字节相加的char*,模拟10进制加法运算即可。

下面的计算是使用g++编译的计算程序,使用PC机计算的效率:

2^1000计算完毕15ms

2^10000计算完毕2.5s

#include "stdio.h"
#include <vector>
#include "time.h"

#define N_SIZE 10000
bool plusSelf(std::vector<char>& vecBytes)
{
 int nPlus = 0;
 for (int i=0; i<vecBytes.size(); i++)
 {
  // 使用*2速度 == <1 速度 > A+A速度,速度快约30%,具体原因可能是因为
  // 1. 不用查找变量
  // 2. 对于*2有优化,直接使用<1位的结果
  int result = vecBytes[i] * 2 + nPlus;
  //int result = vecBytes[i] <1 + nPlus;
  //int result = vecBytes[i] + vecBytes[i] + nPlus;

  // 使用下面这两种效率很接近,对比来看,第二种稍微快一点点,不超过3%
  // 1。 第二种多了一个比较判断,但对于nPlus采用的直接赋值
  // 2.  第一种使用求余和除法,因为char型的数据比较短,才8个字节,所以对于这种情况,也还比较快
  // 建议的话,采用两种方法均可,第一种代码短,第二种速度稍微快一点点
  //vecBytes[i] = result % 10;
  //nPlus = result / 10;
  if (result < 10)
  {
   vecBytes[i] = result;
   nPlus = 0;
  }
  else
  {
   vecBytes[i] = result - 10;
   nPlus = 1;
  }
 }
}

int main()
{
 std::vector<char> vecBytes;
 vecBytes.resize(N_SIZE/3, 0);
 vecBytes[0] = 1;
 for (int i=0; i<N_SIZE; i++)
 {
  plusSelf(vecBytes);
 }

 for (int i=0; i<vecBytes.size(); i++)
 {
  printf("%c", vecBytes[i] + '0');
 }
 printf("\n");

 int nTotal = 0;
 for (int i=0; i<vecBytes.size(); i++)
 {
  nTotal += vecBytes[i];
 }
 printf("nTotal: %d   clock: %d\n", nTotal, clock());

 getchar();
    return 0;
}
时间: 2024-10-12 13:27:35

计算2^1000/2^10000的各位数和的相关文章

计算一个大数n的阶乘的位数宽度(十进制)转载

计算一个大数n的阶乘的位数宽度(十进制)(log i累加法 )转载 输入: 每行输入1个正整数n, (0<n<1000 000) 输出: 对于每个n,输出n!的(十进制)位数. 分析: 这道题采用蛮力法.根据定义,直接求解! 所谓n!的十进制位数,就是 log(n)+1, 根据数学公式有:n!=1*2*3*.....*n; lg(n!)=lg(2)+......lg(n); 代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

计算一个大数n的阶乘的位数宽度(十进制)(log i累加法 )

输入: 每行输入1个正整数n, (0<n<1000 000) 输出: 对于每个n,输出n!的(十进制)位数. 分析: 这道题采用蛮力法.根据定义,直接求解! 所谓n!的十进制位数,就是 log(n)+1, 根据数学公式有:n!=1*2*3*.....*n; lg(n!)=lg(2)+......lg(n); 代码: //输入一个数字n,请你计算该数的阶乘的十进制数的位数宽度 //比如:3!=6, 则宽度为1 //样例数据: //n=3 输出1 //n=32000 输出130271 //n=10

神秘常量!用0x077CB531计算末尾0的个数,32位数首位相连

大家或许还记得 Quake III 里面的一段有如天书般的代码,其中用到的神秘常量 0x5F3759DF 究竟是怎么一回事,着实让不少人伤透了脑筋.今天,我见到了一段同样诡异的代码.     下面这个位运算小技巧可以迅速给出一个数的二进制表达中末尾有多少个 0 .比如, 123 456 的二进制表达是 1 11100010 01000000 ,因此这个程序给出的结果就是 6 . unsigned int v;  // find the number of trailing zeros in 32

计算一个整数(N)的阶乘的位数

对于一个正整数N, 计算N! 的位数.例如N=4, 4!=24,那么位数就是2. 直接计算N!的数值,然后再去数位数,这个很难,因为N!很有可能超过int(32bit) 或long(64bit)的表达范围. 换一种思路,假设要求的位数为x, 那么一定满足 10^(x-1) <=N!<10^x.两边取10为底的对数,得到x-1<=log10(N!)<x.最终x 取 int(log10(N!))+1. log10(N!) = log10(N)+log10(N-1)+log10(N-2)

使用 python 实现π的计算

π的计算 一.π的简介 π的介绍 圆周率用希腊字母 π(读作pài)表示,是一个常数(约等于3.141592654),是代表圆周长和直径的比值.它是一个即无限不循环小数,在日常生活中,通常都用3.14代表圆周率去进行近似计算. π的求解历程 1965年,英国数学家约翰·沃利斯(John Wallis)出版了一本数学专著,其中他推导出一个公式,发现圆周率等于无穷个分数相乘的积. 2015年,罗切斯特大学的科学家们在氢原子能级的量子力学计算中发现了圆周率相同的公式. 2019年3月14日,谷歌宣布圆

Integer和Long部分源码分析

Integer和Long的java中使用特别广泛,本人主要一下Integer.toString(int i)和Long.toString(long i)方法,其他方法都比较容易理解. Integer.toString(int i)和Long.toString(long i),以Integer.toString(int i)为例,先看源码: 1 /** 2 * Returns a {@code String} object representing the 3 * specified intege

中国石油大学胜利学院15级软件工程计算机组成原理复习提纲(上)

第一章 绪论 计算机的性能指标 吞吐量 相应时间 利用率 处理机字长 总线宽度 存储器容量 存储器带宽 主频 第二章 计算机中数据信息表示法 数值转换 数的编码表示 原码:符号位数值化,数值位不变 (1)       零的原码表示不唯一(有+0和-0) (2)       原码的表示范围: 1)  整数范围:-127<=x<=127 2)  小数范围:-(1-2-7 )<= x <=1-2-7 补码: (1)       正数:原反补表示相同 (2)       负数:对原码,符号

【程序员眼中的统计学(9)】总体和样本的估计:进行预测

总体和样本的估计:进行预测 作者 白宁超 2015年10月15日18:30:07 摘要:程序员眼中的统计学系列是作者和团队共同学习笔记的整理.首先提到统计学,很多人认为是经济学或者数学的专利,与计算机并没有交集.诚然在传统学科中,其在以上学科发挥作用很大.然而随着科学技术的发展和机器智能的普及,统计学在机器智能中的作用越来越重要.本系列统计学的学习基于<深入浅出统计学>一书(偏向代码实现,需要读者有一定基础,可以参见后面PPT学习).正如(吴军)先生在<数学之美>一书中阐述的,基于

基数排序/桶排序-单链表实现

今天下午编程实现了基数排序(桶排序),只能说一千个人有一千个哈姆雷特,因此,一千个人可能有一千种基数排序的实现方式,无论是用数组,栈,队列,单链表(都是线性表哦, 好巧,哈哈).重要的是理解该排序算法的思路后,自己也就可以尝试着慢慢写出来了.时间关系,暂且只给出跟人代码(面试黄金月),以后有机会再补充实现思路.新手出道,代码可读性不要期望太高,多包涵,相信以后自己会进步的. typedef struct listnode // 定义节点 { int data; struct listnode *