尝试用程序计算Π(3.141592653......)

news2024/11/25 7:11:53

文章目录

1. π \pi π

π \pi π的重要性或者地位不用多说,有时候还是很好奇,精确地 π \pi π值是怎么计算出来的。研究 π \pi π的精确计算应该是很多数学家计算机科学家努力的方向,很多算式看起来和 π \pi π没有一点关系,但是最后的表达式中却包含 π \pi π
作为一个国家定义的从事信息技术的“新时代农民工”,要验证某些式子相对来说就容易得多了。

2. 用微积分来计算 π \pi π

2.1 原理

小学时候就知道了圆的面积公式 S = π r 2 S=\pi r^2 S=πr2,到了高中学习了微积分,方程与曲线之后可以知道:
x 2 + y 2 = r 2 x^2 + y^2 = r^2 x2+y2=r2
表示一个圆,如果 y > = 0 y>=0 y>=0则表示上半圆,这个时候上半圆可以表达为一个函数:
y = ( r 2 − x 2 ) y = \sqrt{(r^2-x^2)} y=(r2x2)
当它是一个单位圆时(r=1)图形如下所示:
r=1
根据从微积分的角度来看曲线 y ( x ) 与 x = 0 , x ∈ [ − r , r ] y(x)与x=0,x\in [-r,r] y(x)x=0x[r,r]围成的区域面积,就是圆面积的一半,即上半圆的面积。 令圆面积为 S , 则有: 令圆面积为S,则有: 令圆面积为S,则有:
S = π r 2 = 2 ∫ − r r ( r 2 − x 2 ) d x S = \pi r^2 = 2\int_{-r}^{r} \sqrt{(r^2-x^2)} dx S=πr2=2rr(r2x2) dx
现在的工作就变成计算上面右侧的积分式了。积分式用化曲为直(马师傅称为:接 化 发),把圆分成许多直立的小矩形,再求和,小矩形的高为 y i = ( r 2 − x i 2 ) , 宽为 Δ x , Δ x = 1 n y_i=\sqrt{(r^2-x_{i}^2)},宽为\Delta x, \Delta x=\frac{1}{n} yi=(r2xi2) ,宽为Δx,Δx=n1,n表示把圆的面积分为n个小矩形的面积来近似,n越大则近似程度越好,而且当n趋近于无穷时就和积分式完全一致了。
为了求 π \pi π那我们只需要用程序帮我们把圆分成一个一个的小矩形再求和就行了,设定圆的半径,每个矩形的宽度,就可以计算积分式的近似值了。

下面的程序就来计算下式
π = 2 r 2 ∫ − r r ( r 2 − x 2 ) d x \pi = \frac{2}{r^2}\int_{-r}^{r} \sqrt{(r^2-x^2)} dx π=r22rr(r2x2) dx

2.2 代码

#include <cmath>
#include <iostream>


/**
 * @brief calculate sqrt(r^2-x^2)
 * 
 * @param x  : 
 * @return constexpr long double 
 */
constexpr inline long double IntegralFormula(const long double radius,const long double x)
{
    return std::sqrt(radius*radius-x*x);
} 

/**
 * @brief 计算曲线y=sqrt(r^2-x^2),在 x in [-r,r]的积分
 * 
 * @param radius  : 
 * @param delta_x  : 
 * @return constexpr long double 
 */
constexpr long double Integral(const long double radius,const long double delta_x)
{
    long double sum = 0.0;
    for (double x = -radius; x <= radius; x += delta_x)
     {
        sum += delta_x * IntegralFormula(radius,x);
     }
     return sum;
}

/**
 * @brief 
 * 
 * @param radius  : 半径
 * @param bin_num  : 分成小矩形的数目
 * @return constexpr long double 
 */
constexpr long double CalculatePi(const long double radius,double bin_num)
{
    long double delta_x = 2 * radius / bin_num;
    long double integral = Integral(radius,delta_x);
    long double pi = integral * 2.0 / (radius * radius);

    return pi;
}

/**
 * @brief 计算pi值,用单位圆的上半圆做积分,y=sqrt(r^2-x^2),x in [-r,r]
 * 
 */
void Test()
{
    constexpr long double true_pi = 3.141592653589793;
    printf("True PI: %.15Lf\n",true_pi);
    for(double radius = 10; radius <= 100; radius*=10)
        for(double bin_num = 100000; bin_num <= 10000000; bin_num*=10)
        {
            printf("radius:%f, \t bin_num: %f,\t pi: %.20Lf \n",radius,bin_num,CalculatePi(radius,bin_num));
        }
    
}

void Test2()
{
    double radius = 10000;
    double bin_num = 100000;
    printf("radius:%f, \t bin_num: %f,\t pi: %.20Lf \n",radius,bin_num,CalculatePi(radius,bin_num));
}

int main()
{
    Test();
    Test2();
    return 0;
}

2.3 结果

输出

True PI: 3.141592653589793
radius:10.000000,        bin_num: 100000.000000,         pi: 3.14159254840509465393
radius:10.000000,        bin_num: 1000000.000000,        pi: 3.14159265028029712060 
radius:10.000000,        bin_num: 10000000.000000,       pi: 3.14159265331958147799 
radius:100.000000,       bin_num: 100000.000000,         pi: 3.14159254846500206543
radius:100.000000,       bin_num: 1000000.000000,        pi: 3.14159265024260935645 
radius:100.000000,       bin_num: 10000000.000000,       pi: 3.14159265331696711159 
radius:10000.000000,     bin_num: 100000.000000,         pi: 3.14159254840753097960

2.4 分析

这重方式用long double的计算精度,但是最后计算的精度最高只到"3.141592653",小数点后9位。分再多的小矩形也没用了,因为计算时候的截断误差已经足够影响计算精度了。不知道有没有什么好的策略保持计算精度的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/373668.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【老卫搬砖】034期:HarmonyOS 3.1 Beta 1初体验,我在本地模拟器里面刷短视频

今天啊打开这个DevEco Studio的话&#xff0c;已经提示有3.1Beta1版本的一个更新啊。然后看一下它的一些特性。本文也演示了如何在本地模拟器里面运行HarmonyOS版短视频。 主要特性 新特性包括&#xff1a; Added support for Windows 11 64-bit and macOS 13.x OSs, as well…

vue中render函数的作用和参数(vue2中render函数用法)

render 函数是 Vue2.x 新增的一个函数、主要用来提升节点的性能&#xff0c;它是基于 JavaScript 计算。使用 Render 函数将 Template 里面的节点解析成虚拟的 Dom 。Vue 推荐在绝大多数情况下使用模板来创建 HTML。然而在一些场景中&#xff0c;需要 JavaScript 的完全编程能力…

RK3568平台开发系列讲解(驱动基础篇)GIC v3中断控制器

🚀返回专栏总目录 文章目录 一、什么是GIC二、GIC v3中断类型三、GIC v3基本结构3.1、Distributor3.2、CPU interface简介3.3、Redistributor简介3.4、ITS(Interrupt translation service)4、中断状态和处理流程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢ARM多核…

在线文档技术-编辑器篇

这是在线文档技术的第二篇文章&#xff0c;本文将对目前市面上所有的主流编辑器和在线文档进行一次深入的剖析和研究&#xff0c;从而使大家对在线文档技术有更深入的了解&#xff0c;也让更多人能够参与其开发与设计中来。 注意&#xff1a;出于对主流文档产品的尊重&#xf…

【Linux环境配置】7. Linux部署code-server

安装 code-server 两种方法&#xff0c;一种是在线安装&#xff0c;另一种是本地安装。因为主机访问github可能会报443错误&#xff0c;因此这里我推荐使用本地安装方法&#xff01; 本地安装方法 进入github&#xff0c;搜索code-server找到项目地址&#xff1a;https://gi…

链表(一):移除链表元素、设计链表等力扣经典链表题目

203.移除链表元素相关题目链接&#xff1a;力扣 - 移除链表元素题目重现给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。思路链表的删除操作如上图所示&#xff0c;我们需要先找到要删除的…

不需要高深技术,只需要Python:创建一个可定制的HTTP服务器!

目录 1、编写服务端代码,命名为httpserver.py文件。 2、编写网页htmlcss文件&#xff0c;命名为index.html和style.css文件。 3、复制htmlcss到服务端py文件同一文件夹下。 4、运行服务端程序。 5、浏览器中输入localhost:8080显示如下&#xff1a; 要编写一个简单的能发布…

UML类图中的类图、接口图、关联、聚合、依赖、组合概念的解释

文章目录UML类图依赖和关联的主要区别UML类图 类&#xff1a;类有三层结构 第一层&#xff1a;类的名字第二层&#xff1a;类的属性第三层&#xff1a;类的方法 接口&#xff1a;接口跟类相似&#xff0c;不过多了一个<<interface>>来表示它是一个接口 第一层&a…

华为OD机试用Python实现 -【统一限载货物数最小值】(2023-Q1 新题)

华为OD机试题 华为OD机试300题大纲统一限载货物数最小值题目描述输入描述输出描述说明示例一输入输出说明示例二输入输出说明Python 代码实现算法逻辑华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查…

社畜大学生的Python之pandas学习笔记,保姆入门级教学

接上期&#xff0c;上篇介绍了 NumPy&#xff0c;本篇介绍 pandas。 目录 pandas 入门pandas 的数据结构介绍基本功能汇总和计算描述统计处理缺失数据层次化索引 pandas 入门 Pandas 是基于 Numpy 构建的&#xff0c;让以 NumPy 为中心的应用变的更加简单。 Pandas是基于Numpy…

【20230225】【剑指1】分治算法(中等)

1.重建二叉树class Solution { public:TreeNode* traversal(vector<int>& preorder,vector<int>& inorder){if(preorder.size()0) return NULL;int rootValuepreorder.front();TreeNode* rootnew TreeNode(rootValue);//int rootValuepreorder[0];if(preo…

Java学习--多线程(等待唤醒机制)生产者消费者

3.生产者消费者 3.1生产者和消费者模式概述【应用】 概述 生产者消费者模式是一个十分经典的多线程协作的模式&#xff0c;弄懂生产者消费者问题能够让我们对多线程编程的理解更加深刻。 所谓生产者消费者问题&#xff0c;实际上主要是包含了两类线程&#xff1a; ​ 一类是生…

C++ primer 之 extern

C primer 之 extern什么是声明什么是定义两者有什么区别ertern的作用什么是声明 就是使得名字为程序所知&#xff0c;一个文件如果想使用别处定义的名字就必须包含对那个名字的声明。 什么是定义 负责创建与名字关联的实体。 两者有什么区别 变量声明和声明都规定了变量的…

FPGA纯verilog解码SDI视频 纯逻辑资源实现 提供2套工程源码和技术支持

目录1、前言2、硬件电路解析SDI摄像头Gv8601a单端转差GTX解串SDI解码VGA时序恢复YUV转RGB图像输出FDMA图像缓存HDMI输出3、工程1详解&#xff1a;无缓存输出4、工程2详解&#xff1a;缓存3帧输出5、上板调试验证并演示6、福利&#xff1a;工程代码的获取1、前言 FPGA实现SDI视…

多元回归分析 | LASSO多输入单输出预测(Matlab完整程序)

多元回归分析 | LASSO多输入单输出预测(Matlab完整程序) 目录 多元回归分析 | LASSO多输入单输出预测(Matlab完整程序)预测结果评价指标基本介绍程序设计预测结果 评价指标 LASSO回归 训练集平均绝对误差MAE:1.7669 训练集平均相对误差MAPE:0.051742 训练集均方根误差MSE…

【ARMv8 编程】ARMv8 指令集介绍

ARMv8 架构中引入的最重要的变化之一是增加了 64 位指令集。该指令集补充了现有的 32 位指令集架构。这种增加提供了对 64 位宽整数寄存器和数据操作的访问&#xff0c;以及使用 64 位长度的内存指针的能力。新指令被称为 A64&#xff0c;以 AArch64 执行状态执行。ARMv8 还包括…

编码的基本概念

本专栏包含信息论与编码的核心知识&#xff0c;按知识点组织&#xff0c;可作为教学或学习的参考。markdown版本已归档至【Github仓库&#xff1a;information-theory】&#xff0c;需要的朋友们自取。或者公众号【AIShareLab】回复 信息论 也可获取。 文章目录信源编码分类前缀…

nginx模块介绍

新编译前&#xff0c;在对应的nginx原编译文件夹 如&#xff1a;nginx-1.23.0 下&#xff0c;要 make clean 清空以前编译的objs文件夹&#xff0c;实际上就是执行了rm objs文件夹。 很多要用到git&#xff0c;先yum install git -y echo-nginx-module 让nginx直接使用echo的…

基于SpringBoot的任务管理三种方式

文章目录前言一&#xff0c;异步任务1.1 无返回值异步任务调用1.2 有返回值异步任务调用二、定时任务2.1 背景介绍2.2 todo三、邮箱任务3.1 todo前言 开发 web 应用时&#xff0c;多数应用都具备任务调度功能&#xff0c;常见的任务包括异步任务、定时任务和邮件任务。我们以数…

springboot+vue企业固定资产管理系统java

资产管理系统可以更加直观的了解到企业资产的使用情况&#xff0c;让企业资产透明化。资产管理系统可以帮助企业标记企业所有的资产&#xff0c;这些资产包括电脑&#xff0c;桌子&#xff0c;椅子等不动资产的标识&#xff0c;以及固定资产的新增&#xff0c;修改&#xff0c;…