Наближене обчислення числа Пі

Число Пі — це математична константа, яка представляє собою відношення довжини кола до його діаметра. Значення цієї константи приблизно дорівнює 3.14 в звичайних десяткових позначеннях. Багато формул в математиці, природознавстві і техніці включають Пі, що робить його однією з найважливіших математичних констант. До прикладу, площа кола дорівнює Пі, помноженому на квадрат його радіусу.

Оскільки Пі є ірраціональним числом, його значення не може бути виражено точно як дріб, що має цілі числа як в чисельнику, так і в знаменнику. Тобто, його десяткове подання ніколи не закінчується і ніколи не повторюється.

Авторство відкриття числа Пі невідомо і приписується геометрам з Стародавнього Єгипту, Індії, Греції та Вавилону. Першу спробу обчислити його точне значення запропонував Архімед: він вписував в коло і описував навколо нього правильні багатокутники, згодом зробивши висновок, що значення цієї константи лежить в інтервалі між і .

Обчислення числа Пі — спосіб Архімеда

Приблизно через 600 років після Архімеда китайський математик Цзу Чунчжі застосував аналогічний підхід для правильного багатокутника з 12288 сторонами. Це призвело до наближення значення числа Пі до , яке відповідає шести десятковим розрядам. Зазначимо, що отриманий таким чином результат являвся найбільш точним розрахунком числа протягом наступних 900 років.

Зрештою математики виявили, що насправді існують точні формули для обчислення Пі. Характерною особливістю цих формул є те, що кожна з них вимагає виконання певних дій нескінченне число разів (що має сенс, враховуючи, що цифри Пі тривають вічно). Розглянемо декілька з цих формул, та, на вибір, перевіримо ефективність двох з них.

  1. Формула Лю-Хуея ( століття):

  2. Формула Мадхава-Лейбніца ( століття):

  3. Формула Валліса ( століття):

  4. Формула Мечіна ( століття):

  5. Формулу Чудновського ( століття):

Отже, для початку, спробуємо обчислити число Пі скориставшись, наприклад, формулою Валліса. Для цього напишемо просту програму на мові Java.

Програма для обчислення числа Pi використовуючи формулу Валліса

import java.util.Scanner;
import java.lang.Math;
import java.math.BigDecimal;
import java.math.MathContext;
class Wallis_formula {
    public static void main (String args[]) {
        Scanner scann = new Scanner(System.in);
        // Введення кількості ітерацій необхідних для обчисення Pi
        System.out.print("Enter the number of iterations: ");
        int num = scann.nextInt();
        if (num < 0)
            throw new IllegalArgumentException("The number you enter must not be less than one!");
        // Обчислюємо та повертаємо число Pi
        MathContext mc = new MathContext(1000);
        BigDecimal bD2 = new BigDecimal("2");
        BigDecimal bDob = new BigDecimal("1");
        BigDecimal nominator = new BigDecimal("0");
        BigDecimal denominator = new BigDecimal("0");
        for (int i = 1; i <= num; i++) {
            nominator = bD2.multiply(BigDecimal.valueOf(i)).pow(2);
            denominator = bD2.multiply(BigDecimal.valueOf(i)).subtract(BigDecimal.valueOf(1)).multiply(bD2.multiply(BigDecimal.valueOf(i)).add( BigDecimal.valueOf(1)));
            bDob = bDob.multiply(nominator.divide(denominator, mc));
        }
        BigDecimal Pi = bD2.multiply(bDob, mc);
        System.out.println("Iteration number " + num + ": " + Pi);
    }
}

Скомпілювавши, запустивши та задавши в якості числа ітерацій виконуваних під час обчислення числа Пі, наприклад, значення 100, отримаємо наступний результат.

Обчислення числа Pi використовуючи формулу Валліса

Як можна бачити, зробивши сто кроків алгоритму, ми отримали лише один точний знак. Тобто, алгоритм працює, однак він сходиться дуже повільно. До прикладу, необхідно обчислити добуток майже 1500 множників, щоб поліпшити оцінку Архімеда і більше 10000 членів, щоб отримати 10 точних знаків у дробовій частині числа Пі.

Подивимося тепер, який результат, з аналогічною кількістю ітерацій, можна отримати скориставшись бульш сучасною формулою Чудновського.

Програма для обчислення числа Pi використовуючи формулу Чудновського
import java.util.Scanner;
import java.lang.Math;
import java.math.BigDecimal;
import java.math.MathContext;
class Chudnovskys_formula {
    public static void main (String args[]) {
        Scanner scann = new Scanner(System.in);
        // Введення кількості ітерацій необхідних для обчисення Pi
        System.out.print("Enter the number of iterations: ");
        int num = scann.nextInt();
        if (num < 0)
            throw new IllegalArgumentException("The number you enter must not be less than one!");
        // Обчислюємо та повертаємо числа Pi отримані на кожній ітерації алгоритму
        MathContext mc = new MathContext(1000);
        BigDecimal Pi = new BigDecimal("0");
        BigDecimal fct = new BigDecimal("1");
        BigDecimal fct3 = new BigDecimal("1");
        BigDecimal fct6 = new BigDecimal("1");
        BigDecimal sign = new BigDecimal("1");
        BigDecimal pSign = new BigDecimal("1");
        BigDecimal nSign = new BigDecimal("-1");
        BigDecimal bDsum = new BigDecimal("0");
        BigDecimal nominator = new BigDecimal("0");
        BigDecimal denominator = new BigDecimal("0");
        BigDecimal bD13591409 = new BigDecimal("13591409");
        BigDecimal bD545140134 = new BigDecimal("545140134");
        BigDecimal bD640320 = new BigDecimal("640320");
        for (int i = 0; i <= num; i++) {
            if ((i % 2) == 0) {
                sign = pSign;
            } else {
                sign = nSign;
            }
            fct = Factorial(i);
            fct3 = Factorial(3 * i);
            fct6 = Factorial(6 * i);
            nominator = sign.multiply(fct6).multiply(bD13591409.add(bD545140134.multiply(BigDecimal.valueOf(i))));
            denominator = (fct3.multiply(fct.pow(3))).multiply(bD640320.pow(3 * i)).multiply(Sqrt(bD640320, mc).pow(3));
            bDsum = bDsum.add(nominator.divide(denominator, mc));
        }
        BigDecimal bD1 = new BigDecimal("1");
        BigDecimal bD12 = new BigDecimal("12");
        Pi = bD12.multiply(bDsum);
        Pi = bD1.divide(Pi, mc);
        System.out.println("Iteration number " + num + ": " + Pi);
    }
    // Обчислюємо факторіал заданого числа
    public static BigDecimal Factorial(int number) {
        BigDecimal factorial = BigDecimal.valueOf(1);
        for (int i = number; i > 0; i--) {
            factorial = factorial.multiply(BigDecimal.valueOf(i));
        }
        return factorial;
    }
    // Знаходимо квадратний корінь числа
    public static BigDecimal Sqrt(BigDecimal number, MathContext mc) {
        BigDecimal squareRooti = new BigDecimal("0");
        int i = 0;
        BigDecimal squareRoot0 = number.divide(BigDecimal.valueOf(2), mc);
        do {
            squareRooti = (squareRoot0.add(number.divide(squareRoot0, mc))).divide(BigDecimal.valueOf(2), mc);
            i = squareRoot0.compareTo(squareRooti);
            squareRoot0 = squareRooti;
        } while (i != 0);
        return squareRooti;
    }
}

Знову-таки компілюємо, запускаємо та задаємо в якості кількості ітерацій значення 100, отримаємо результат, який містить більше тисячі точних цифр числа Пі.

Обчислення числа Pi використовуючи формулу Чудновського

Отже, підсумуємо. Хоч і сучасні формули не настільки прості зовні, зате працюють в декілька разів швидше та ефективніше (14 цифр Пі за одну ітерацію). Як можна бачити, навіть з використанням факторіала (що досить довго), алгоритм Чудновського працює швидше за попередній в 5 разів. Перетворення його до виду обчислення факторіала з використанням попереднього значення дає прискорення ще в кілька разів.

Матеріал був корисним, поділись в соціальних мережах:
Якщо тобі сподобалась дана тема, залиш свій коментар