古中国数学家的计算力真是惊人
现代数学是建立在公理化的体系之上,可以认为是形而上学。公理化是数学的本质所在,古代中国人建立过数学的辉煌,但是却似乎并没有去思考数学的本质,而古希腊的《几何原本》是人类有史以来记载的最早数学往公理化方向努力,尽管《几何原本》中存在着公理的不完备,证明过程中依然有”想当然“的成分,比如直线上除某点之外的一点(几何原本中并没有公理支持直线上除了某点之外还可以取一点),但是往公理化运行的这个历史意义巨大。
很长时间,我都不太认为古代数学有哪些惊人,只是还知道勾股定理,杨辉三角,以及祖冲之算圆周率等。
今天老婆问我圆周率怎么算的,我就想了想。虽然圆周率可以有一堆无穷级数或者无穷乘积可以表示,我还是选择了用最简单的方式来回答,于是就直接行动起来吧。
选择一个单位圆,x2+y2=1,它的面积就是pi,于是用微积分逼近的方法来做,分成n等分,然后用上和或者下和逼近。当然要考虑精度问题,所以还是用上bc这个任意精度计算器,这个计算器我一直很喜欢使用,一边跟老婆解释一边写程序,程序很快写完。
scale = 12;/*所有计算精度小数点后12位*/
n = 10^6;/*单位圆切200万刀,y轴左右各100万刀*/
pi = 0;/*上和累计初始值为0*/
for(i=0;i<n;i++) {
x = i/n;/*x坐标*/
y = sqrt(1-x^2);/*y坐标*/
s = 4*y/n;/*此块上和,4个象限对称4份*/
pi = pi+s;/*累和进去*/
}
print "pi = ", pi, "n";/*最终打印出累和出来的圆周率*/
用bc运行一下,我的虚拟机24秒后有了结果。
# time bc <2
pi = 3.141594151717
real 0m24.015s
user 0m24.006s
sys 0m0.008s
结果并不是很理想,计算精度12位其实只是影响了一点点累和时的精度问题,完全不是祖冲之的3.14159265级别的问题。
于是换条路吧,祖冲之的割圆术应该是对周长的,于是我就分它个215=32768份,成为一个32768边形,边长其实是2*sin(2*pi/32768),我们就来算这个值吧。sin(2x)=2sin(x)*cos(x),因为是锐角,可算出sin(x)=sqrt((1-sqrt(1-cos(2x)*cos(2x)))/2)。
继续用bc来写,
n=13;/*从圆的内接正方形开始,开始对切13次*/
scale=20;/*纪念20位足够*/
s=sqrt(2)/2;/*sin(pi/4)*/
for(i=0;i<n;i++) {
s = sqrt((1-sqrt(1-s^2))/2);/*一个个的推*/
}
print "pi = ", 4*s*2^n, "n";/*打印圆周率*/
运行一下,这次对于计算机就很快了,长度法比面积法靠谱,
# time bc <3
p = 3.14159264877598965760
real 0m0.007s
user 0m0.004s
sys 0m0.004s
可是,精度还差那么一点,看来应该多切一刀,把程序中的n改成14,精度符合要求。
# time bc <3
p = 3.14159265238350561280
real 0m0.005s
user 0m0.000s
sys 0m0.004s
这样的开平方运算用手算是很复杂的,参考我的博文《平方根的C语言实现(二) —— 手算平方根的原理》,我无法想像祖冲之如何面对这么复杂的运算的。中国古人虽然可能对于数学的基本原理没有做深层次的考虑(不排除以前考虑过,但资料丢失的可能,毕竟经过了嬴政和刘彻和那么多的朝代),但至少古人的计算能力真的是很让人震撼。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 使用Apache ab进行http性能测试
- Android Imageloader的配置的实现代码
- Linux下如何查看版本信息的方法步骤
- Android开发实现Files文件读取解析功能示例
- Android实现iPhone晃动撤销输入功能 Android仿微信摇一摇功能
- 猿实战21——商品发布之商品数据存储
- Android编程自定义进度条颜色的方法详解
- Android TextView对齐的两种方法
- Android ScrollView实现反弹效果的实例
- Ubuntu 18.04上安装 phpMyAdmin的详细教程
- Android Popupwindow弹出窗口的简单使用方法
- 解决CentOS7虚拟机无法上网并设置CentOS7虚拟机使用静态IP上网
- Android编程实现自定义Dialog的大小自动控制方法示例
- Linux中如何查看文件的创建时间详解
- Android 图片添加水印的实现方法