ライプニッツ級数

以下の文章はライプニッツの公式の要約分を含む

ライプニッツ級数（ライプニッツきゅうすう、）は、円周率 π を求めるための無限級数の一つであり、17世紀にゴットフリート・ライプニッツによって示された。
次の交代級数として表される。

概要

ライプニッツ級数は、円周率を求める最も単純な数式の一つとして知られている。
構造が単純であるため、数学教育やプログラミングの例題として広く用いられる。

一方で、収束速度が非常に遅く、高精度な円周率を求めるには膨大な項数が必要となる。そのため、実用的な数値計算では他のアルゴリズムが用いられることが多い。
数学的背景
ライプニッツ級数は、逆正接関数

において 
x=1 を代入することで得られる。

この関係から、ライプニッツ級数が円周率と結び付けられる。
収束性と精度

ライプニッツ級数は交代級数であり、条件付き収束することが知られている。
ただし、誤差はおおよそ次の項の大きさに比例するため、100万項を計算しても正確な桁数は数桁程度にとどまる。

このため、実際の円周率計算では以下のような方法が用いられることが多い。

・ガウス＝ルジャンドルのアルゴリズム

・マチンの公式

・チュドノフスキー級数
プログラミングにおける利用例

ライプニッツ級数は、ループ処理や浮動小数点演算の例として、さまざまなプログラミング言語で実装されている。

C++
#include <iostream>
#include <cmath>
using namespace std;
int main(){
    int a=0;
    long double x=0.0;
    cin >> a;
    for(int n=0;n<=a;n++){
        x+=pow(-1,n)/(2*n+1);
    }
    cout << 4*x << endl;
    return 0;
}

C
#include <stdio.h>
#include <math.h>
int main() {
    int a;
    long double x = 0.0;
    scanf("%d", &a);
    for (int n = 0; n <= a; n++) {
        x += pow(-1, n) / (2 * n + 1);
    }
    printf("%.15Lf\n", 4 * x);
    return 0;
}

C#
using System;
class Program {
    static void Main() {
        int a = int.Parse(Console.ReadLine());
        double x = 0.0;
        for (int n = 0; n <= a; n++) {
            x += Math.Pow(-1, n) / (2.0 * n + 1);
        }
        Console.WriteLine(4 * x);
    }
}

Python
a = int(input())
x = 0.0
for n in range(a + 1):
    x += (-1) ** n / (2 * n + 1)
print(4 * x)

Java
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        double x = 0.0;
        for (int n = 0; n <= a; n++) {
            x += Math.pow(-1, n) / (2.0 * n + 1);
        }
        System.out.println(4 * x);
    }
}

JavaScript(Node.js)
const fs = require("fs");
const a = parseInt(fs.readFileSync(0, "utf8").trim());
let x = 0;
for (let n = 0; n <= a; n++) {
    x += Math.pow(-1, n) / (2 * n + 1);
}
console.log(4 * x);

Rust
use std::io;
fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    let a: i32 = input.trim().parse().unwrap();
    let mut x: f64 = 0.0;
    for n in 0..=a {
        x += (-1.0_f64).powi(n) / (2.0 * n as f64 + 1.0);
    }
    println!("{}", 4.0 * x);
}

Go
package main
import (
    "fmt"
    "math"
)
func main() {
    var a int
    fmt.Scan(&a)
    var x float64 = 0.0
    for n := 0; n <= a; n++ {
        x += math.Pow(-1, float64(n)) / (float64(2*n) + 1)
    }
    fmt.Println(4 * x)
}

Ruby
a = gets.to_i
x = 0.0
(0..a).each do |n|
  x += (-1.0)**n / (2*n + 1)
end
puts 4 * x

Swift
import Foundation
if let line = readLine(), let a = Int(line) {
    var x = 0.0
    for n in 0...a {
        x += pow(-1.0, Double(n)) / (2.0 * Double(n) + 1.0)
    }
    print(4 * x)
}

Kotlin
fun main() {
    val a = readLine()!!.toInt()
    var x = 0.0
    for (n in 0..a) {
        x += Math.pow(-1.0, n.toDouble()) / (2.0 * n + 1)
    }
    println(4 * x)
}

Haskell
main = do
    a <- readLn :: IO Int
    let x = sum [(-1)^^n / fromIntegral (2*n + 1) | n <- [0..a]]
    print (4 * x)

Lisp
(defun calculate-pi (a)
  (let ((x 0.0))
    (loop for n from 0 to a do
      (setq x (+ x (/ (expt -1 n) (+ (* 2 n) 1)))))
    (* 4 x)))

(let ((a (parse-integer (read-line))))
  (format t "~f~%" (calculate-pi a)))

文言
吾有一数者名为a。
吾有一数者名为x。
吾有一数者名为n。
请输吾a。
吾x为零。
吾n为零。
若n小于等于a，则：
    吾x为 吾x 加 (-1) 的 n 次方 除以 (二乘n 加 一)。
    吾n为 吾n 加 一。
是故。
吾x为 四乘吾x。
请输吾x。

Fortran
program pi
    implicit none
    integer :: a, n
    real(8) :: x
    read *, a
    x = 0.0d0
    do n = 0, a
        x = x + (-1.0d0) ** n / (2.0d0 * real(n) + 1.0d0)
    end do
    print *, 4.0d0 * x
end program pi

Pascal
program pi;
uses
  SysUtils, Math;
var
  a, n: Integer;
  x: Extended;
begin
  x := 0.0;
  ReadLn(a);
  for n := 0 to a do
  begin
    x := x + Power(-1, n) / (2*n + 1);
  end;
  WriteLn(4 * x:0:15);
end.

Julia
a = parse(Int, readline())
x = 0.0
for n in 0:a
    x += (-1.0)^n / (2 * n + 1)
end
println(4 * x)

PHP
<?php
$a = intval(trim(fgets(STDIN)));
$x = 0.0;
for ($n = 0; $n <= $a; $n++) {
    $x += pow(-1, $n) / (2 * $n + 1);
}
echo 4 * $x . PHP_EOL;
?>

Perl
use strict;
use warnings;
my $a = <STDIN>;
chomp $a;
my $x = 0.0;
for my $n (0..$a) {
    $x += (-1.0)**$n / (2 * $n + 1);
}
print 4 * $x, "\n";

Lua
a = tonumber(io.read())
x = 0.0
for n = 0, a do
    x = x + (-1.0)^n / (2 * n + 1)
end
print(4 * x)

これらのプログラムは、計算回数を入力として受け取り、ライプニッツ級数による円周率の近似値を出力する。
教育的意義
ライプニッツ級数は、以下の概念を説明する教材として用いられる。

 無限級数
 交代級数の収束
 数値計算における誤差
 アルゴリズムの効率比較

その単純さから、初学者向けの数学教育やプログラミング教育において重要な役割を果たしている。
関連項目
 円周率
 無限級数
 テイラー級数
 円周率の近似
 参考文献 

http://www.pluto.ai.kyutech.ac.jp/~matumoto/dvi/pi.pdf
https://manabitimes.jp/math/1229
https://note.com/ur_alr/n/n6f7420a41d24
https://shigotoron.com/%E4%B8%89%E8%A7%92%E9%96%A2%E6%95%B0%E3%81%AE%E7%84%A1%E9%99%90%E7%A9%8D%E3%82%92%E7%94%A8%E3%81%84%E3%81%9F%E7%B4%9A%E6%95%B0%E3%81%AE%E8%A8%88%E7%AE%97/
https://mathlandscape.com/alter-series-convergence/

Category:数学に関する記事
Category:数学のエポニム