我的精度问题

#include<bits/stdc++.h>
#define ll long double
using namespace std;
int main()
{
	ios::sync_with_stdio(false);cin.tie(0);
	ll k=0,p=1;
	for(int i=1;;i++)
	{
		if(i%2==1)
		{
			k+=4*(1.0/p);
		}	
		else
		{
			k-=4*(1.0/p);
		}
		p+=2;
		cout<<k<<'\n';
	} 
	return 0;
}

这是我使用的计算 \pi 的代码,可是精度有限,现在向大家征集一些高精度计算 \pi 的代码和思路。

高精度

对于无穷级数计算来说不是很方便

#include <iostream>
#include <cstring>
#include <bits/stdc++.h>
#define MAX_LEN 1000
using namespace std;

// 高精度加法函数
void add(char a[MAX_LEN], char b[MAX_LEN], char result[MAX_LEN]) {
    int len_a = strlen(a);
    int len_b = strlen(b);
    int carry = 0;
    int i = len_a - 1, j = len_b - 1, k = MAX_LEN - 1;
    while (i >= 0 || j >= 0 || carry) {
        int digit_a = (i >= 0)? a[i--] - '0' : 0;
        int digit_b = (j >= 0)? b[j--] - '0' : 0;
        int sum = digit_a + digit_b + carry;
        carry = sum / 10;
        result[k--] = (sum % 10) + '0';
    }
    // 找到第一个非零数字的位置
    int start = 0;
    while (result[start] == '0' && start < MAX_LEN - 1) start++;
    // 复制到最终结果中
    for (i = 0; i < MAX_LEN - start; i++) {
        result[i] = result[i + start];
    }
    result[i] = '\0';
}

// 高精度减法函数,假设 a >= b
void subtract(char a[MAX_LEN], char b[MAX_LEN], char result[MAX_LEN]) {
    int len_a = strlen(a);
    int len_b = strlen(b);
    int borrow = 0;
    int i = len_a - 1, j = len_b - 1, k = MAX_LEN - 1;
    while (i >= 0 || j >= 0) {
        int digit_a = (i >= 0)? a[i--] - '0' : 0;
        int digit_b = (j >= 0)? b[j--] - '0' : 0;
        digit_a -= borrow;
        if (digit_a >= digit_b) {
            result[k--] = (digit_a - digit_b) + '0';
            borrow = 0;
        } else {
            result[k--] = (digit_a + 10 - digit_b) + '0';
            borrow = 1;
        }
    }
    // 找到第一个非零数字的位置
    int start = 0;
    while (result[start] == '0' && start < MAX_LEN - 1) start++;
    // 复制到最终结果中
    for (i = 0; i < MAX_LEN - start; i++) {
        result[i] = result[i + start];
    }
    result[i] = '\0';
}

// 高精度除法函数,这里是 4 除以 p 的特殊情况
void divide_by_2(char num[MAX_LEN], char result[MAX_LEN]) {
    int len = strlen(num);
    int carry = 0;
    for (int i = 0; i < len; i++) {
        int digit = num[i] - '0';
        result[i] = ((carry * 10 + digit) / 2) + '0';
        carry = (carry * 10 + digit) % 2;
    }
    // 找到第一个非零数字的位置
    int start = 0;
    while (result[start] == '0' && start < len) start++;
    // 复制到最终结果中
    for (int i = 0; i < len - start; i++) {
        result[i] = result[i + start];
    }
    result[i] = '\0';
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    char k[MAX_LEN];
    memset(k, '0', sizeof(k));
    k[MAX_LEN - 1] = '\0';
    int p = 1;
    for (int i = 1;; i++) {
        char term[MAX_LEN];
        memset(term, '0', sizeof(term));
        term[MAX_LEN - 1] = '\0';
        char four[MAX_LEN] = "4";
        char divisor[MAX_LEN];
        sprintf(divisor, "%d", p);
        // 高精度除法 4/p
        divide_by_2(four, term);
        if (i % 2 == 1) {
            add(k, term, k);
        } else {
            subtract(k, term, k);
        }
        p += 2;
        cout << k << '\n';
    }
    return 0;
}

pi这个东西不能算是代码精度问题,你可以用“高斯-勒让德算法”来搞,具体做法上网上查,我个人感觉比较适合用计算机去迭代,也比较好理解

嗯,谢了