Spigot 算法之一 计算调和级数的和



我是首先在[1] 注意到 Spigot-Algorithm的,这个算法发布的相当早,见[2].  [1] 给出几个令人惊异的程序,只用很少的代码就可以计算e,pi,log(2)等常数。其中那个4行代码计算圆周率的程序被网友称作外星人写的程序,但我一直没有勇气去分析和学习它,最近终于决定学习这个 Spigot-Algorithm,先看了文献【3】,明白了其基本思想,遂计划尝试编写各种计算常数的代码,并写一个系列博客。从这篇开始,我将讲述如果使用这个算法计算各种常数或者级数的和。

数列a[n]={1/1,1/2,1/3,1/4... 1/n} 被称作调和数列。调和数列的和f(n)= 1/1 + 1/2 + 1/3 +1/4 + ... 1/n 被称作调和级数。调和级数是最简单的级数之一。用Spigot 算法来计算这个级数也最为简单。

下面给出代码。具体说明以后补上。

#define R 10		//进制,可改为100,1000,10000,
#define FMT_STR "%d"	//当R=100,1000,10000时,相应的,需要改为"%02d","%03d","%04d",
#define N 10		//计算交错级数的前10项
#define P 20		//当R=10^k时,可打印前P*k位有效数字
int a[N+1],i,j,x;
void main()
{
  for (i=N;i;a[i--]=1);
  for (j=0;j<P;j++)
  {
    x=0;
    for (i=N;i;i--)
    {
	x+=(a[i]*R)/i; a[i]=(a[i]*R)%i;
    }
    x+=a[i]*R;
    printf(FMT_STR,x/R); a[0]=x/R;
    if ( j==0)
     printf(".");
  }
}

几点说明:

1. 数组的长度和计算的项数有关,而和最终精度无关。

2. a[1] to a[n]存储第j轮计算时,各项的分子。

3. 每轮计算中,得到2位10进制数,最高位直接输出,次高位缓存在a[0]

4. 当N大于10时,计算结果错误,这是因为交错级数收敛很慢. 当得到次高位时就急于输出最高位仍是冒险的方法。改进的方法是当得到第5位时再输出最高位,然后将第2到5位存储在a[0],下面是修改后的代码,可正确计算交错级数前100项的值。

#define R 10  //进制,可改为100,1000,10000,
#define FMT_STR "%d" //当R=100,1000,10000时,相应的,需要改为"%02d","%03d","%04d",
#define N 100  //计算交错级数的前N项
#define P 100  //当R=10^k时,可打印前P*k位有效数字
int a[N+1],i,j,x;
void main()
{
  for (i=N;i;i--)
  a[i]=1;
  for (j=0;j<P+1;j++)
  {
    x=0;
    for (i=N;i;i--)
    {
      x+=(a[i]*R)/i; a[i]=(a[i]*R)%i;
    }
    a[0]= a[0]*R + x;
    if ( j>2)
    {
      printf(FMT_STR,a[0]/(R*R*R*R));
      a[0]%=(R*R*R*R);
      if ( j==3)
        printf(".");
    }
  }
}

参考文献:

1. Tiny programs for constants ,http://numbers.computation.free.fr/Constants/constants.html

1. M. Abramowitz and I. Stegun, Handbook of Mathematical Functions, Dover, New York, (1964)

3. https://en.wikipedia.org/wiki/Spigot_algorithm



版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-05 15:31:16

Spigot 算法之一 计算调和级数的和的相关文章

MD5算法【计算文件和字符串的MD5值】

1. MD5算法是一种散列(hash)算法(摘要算法,指纹算法),不是一种加密算法(易错).任何长度的任意内容都可以用MD5计算出散列值.MD5的前身:MD2.MD3.MD4.介绍工具:CalcMD5.zip.主要作用就是[验明"真身"],字符串文件均可(确保信息传输过程中的完整性.一致性). 2. MD5算法的特点: ????1. 长度固定 ????2. 单向性 ---- 可以通过MD5计算器来计算文件或者字符串的MD5值,但是不可以通过给出的MD5值来推算出文件或者字符串. ???

迪杰斯特拉算法(计算路径)

package com.rao.graph; import java.util.LinkedList; import java.util.List; /** * @author Srao * @className DijkstraWithPath * @date 2019/12/11 17:59 * @package com.rao.graph * @Description 迪杰斯特拉算法(计算路径) */ public class DijkstraWithPath { /** * 图的顶点 *

算法时间复杂度计算

概述 ??一个算法是由控制结构(顺序,分支,循环)和原操作(指固有数据类型的操作)构成.为了便于比较同一问题的不同算法,通常的做法是,从算法中选取一种对所研究的问题来说是基本操作的原操作,以该基本原操作重复执行的次数作为算法的时间度量.多数情况下,基本原操作是它最深层循环中的原操作,对算法的时间度量最常用的是考虑在最坏的情况下时间复杂度. 时间复杂度的定义 ??算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)

Levenshtein Distance莱文斯坦距离算法来计算字符串的相似度

转 理解起来不难,但是很实用. 核心公式就是下面:             (1) 1.百度百科介绍: Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数. 许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符. 编辑距离的算法是首先由俄国科学家Levenshtein提出的,故又叫Levenshtein Distance. 2.用途 模糊查询 3.实现过程 a.首先是有两个字符串,这里写一个简单的 abc和abe b.将

算法_计算输入的算术表达式的值.

例如:如果输入:( ( 1 + 2 ) * ( 3 + ( 4 * 5 ) ) )可以计算出输入的字符串所对应的算术表达式的值.我们支持运算符+,-,*,/,和一个一元运算abs,可以用一个简单的算法获取这个算术表达式的值: 我们用两个栈(一个用于保存操作符,一个用于保存操作数).表达式由括号,运算符和操作数组成.我们按照以下四种情况对于这个实体送入栈处理: 1.将操作数压入操作数栈 2.将运算符压入运算符栈 3.忽略左括号 4.如果碰到右括号,弹出一个运算符,如果运算符是abs以外的运算符,弹

数据结构与算法-怎样计算时间复杂度

今天我们来谈一下怎样计算时间复杂度. 时间复杂度概念:(百度版) 同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率. 算法分析的目的在于选择合适算法和改进算法. 计算机科学中,算法的时间复杂度是一个函数,它定量描写叙述了该算法的执行时间. 这是一个关于代表算法输入值的字符串的长度的函数.时间复杂度经常使用大O符号表述,不包含这个函数的低阶项和首项系数.使用这样的方式时.时间复杂度可被称为是渐近的.它考察当输入值大小趋近无穷时的情况. 注意:本文承接上一篇<数据结构与算法-

算法在计算中的作用

算法是任何一段定义好的步骤,它把一些值或者值域作为输入,处理后把某个值或者值域作为输出,而算法就是把输入转换成输出的一系列计算步骤. 我们也可把算法看成解决具体计算问题的工具.通常描述问题的语句指定需要的输入/输出之间的关系.而算法描述了具体的计算步骤来构建输入/输出之间的关系. 举个例子,我们需要把一系列数字以非递减的顺序排列.该问题在实际中频繁出现,成为许多标准设计技巧和分析工具的肥沃土壤.以下是排序问题的正式定义: .输入:n个数列:a1,a2,...,an. .输出:序列(a1',a2'

算法导论-第一章-算法在计算中的作用(速记)

算法就是把输入转换成输出的计算步骤的一个序列. 问题实例由计算该问题解所必需的(满足问题陈述中强加的各种约束的)输入组成. 若对每个输入实例,算法都以正确的输出停机,则称该算法是正确的. 许多有趣的算法问题所共有的两个特征: 1.存在许多候选解,但绝大多数候选解都没有解决手头的问题.寻找一个真正的解或一个做好的解可能是一个很大的挑战. 2.存在实际应用. 数据结构是一种存储和组织数据的方式,旨在便于访问和修改. 原文地址:https://www.cnblogs.com/lixiaov/p/104

Java入门:基础算法之计算三角形面积

本部分介绍如何计算三角形面积. /** * @author: 理工云课堂 * @description: 程序计算三角形的面积.三角形的底和高由用户输入 */ import java.util.Scanner; class AreaTriangleDemo { public static void main(String args[]) { Scanner scanner = new Scanner(System.in); System.out.println("Enter the width