有趣的问题:给你一个生成0到1之间随机数的函数,请求出圆周率π

来源

这是一道我在看 Youtube 时无心间发现的问题,原视频连接:https://www.youtube.com/watch...c++

问题是:给你一个生成0到1之间随机数的函数,请求出圆周率 π编程

第一眼看上去仿佛是一个彻底没头脑的问题,可是仔细一想,就能够使用一点编程能力和初中的数学知识解决。vim

思路

思路应该是去寻找两个东西的交汇点,一个随机数,是一个数字,也能够是数轴上的一个点。两个随机数,就是两个数轴上的点,或者是一个坐标轴上的点(r1, r2),若是调用无数次的随机数,就能够得到无数个坐标轴上的点。dom

圆周率,咱们必需要找到一个使用了圆周率的东西,很容易想到圆的面积和周长。函数

如今咱们有了无数个在坐标轴上的点圆的面积圆的周长。emmmm……有想到什么吗?oop

也许咱们应该画一个图。spa

image.png

也许咱们应该把圆画上去,应该会帮助咱们思考。code

image.png

OK,知道了,全部的点会落在正方形(0,0,1,1) 的范围内,其中有一部分会落在圆的范围内,若是咱们统计落在圆内的点的个数,记为 N,那么 N 与总点数 M 的比值,应该是等于圆的面积比上正方形的面积。视频

列下公式应该是:blog

$$ r = 1/2 $$
$$\frac{N}{M} = \frac{\pi r^2}{(2r)^2}$$

把公式化简一下,变成:
$$\pi = 4 * N / M$$

为了编程中方便计算任意点距离圆心的距离,能够这样理解这个几率:
image.png

公式中的关系依然成立。

编程实现

fun main() {
    var times = 100L
    for (i in 1..9) {
        println("loop: $times pi: ${getPi(times)}")
        times *= 10
    }
}

fun getPi(count: Long): Double {
    var c = 0
    for (i in 0 until count) {
        val x = Math.random()
        val y = Math.random()

        if (x * x + y * y < 1) {
            c++
        }
    }
    return 4.0 * c / count
}

运行结果:

loop: 100 pi: 3.24
loop: 1000 pi: 3.168
loop: 10000 pi: 3.1528
loop: 100000 pi: 3.14348
loop: 1000000 pi: 3.141964
loop: 10000000 pi: 3.1414304
loop: 100000000 pi: 3.14131604
loop: 1000000000 pi: 3.141585632
loop: 10000000000 pi: 3.1415885784
相关文章
相关标签/搜索