求sqrt(2)精确值

· · 个人记录

我突然想到精确根号2

我精确它到上千位了!

众所周知,根号2 约等于 1.414

那么,怎么用编程把它精确到小数点后前10000位呢

调用math库函数sqrt()?那太简单了,但——

精度有限,所以不可行

我们要选取精度最高的数据类型——string

先要有高精度乘法的函数

相信很多人都学了高精乘高精

不会的请看P1303的题解

在此不再熬述

切入正题

有一种方法 就是夹逼法

请看下图:

ans=""
1*1<2,2*2>2,ans=1.0
1.1*1.1<2,1.2*1.2<2,……1.4*1.4<2,1.5*1.5>2,ans=1.4
1.41*1.41<2,1.42*1.42>2,ans=1.41
……

怎么样,看懂了吧

像这样无限的算下去

就可得到100%精确的值

因为10*10=100

所以按以上思路

先忽略小数点

ans的位数每次加1

要开根号的数每次要乘100

就是后面加两个0

我们可以写模板了

输入精确的位数n
string a="2";
string ans="";
for(1~n):
    a+="00";
   int c=0;
    重复执行直到ans*ans>a
        c++;
   c--;
    ans+=(c+'0');
   ans.insert(1,".");
输出ans

为了人们的耐心, 我们可以把每一位逐一输出

代码如下(作者亲测毫无bug)(算出前若干位可以保存,下次计算接上次的进度):

#include <bits/stdc++.h>
using namespace std;
string mul3(string a,string b);//高精和比大小自己去写吧
int lar(string a,string b);//大于返回1,小于返回-1,等于返回0
string jia="414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572735013846230912297024924836055850737212644121497099935831413222665927505592755799950501152782060571470109559971605970274534596862014728517418640889198609552329230484308714321450839762603627995251407989687253396546331808829640620615258352395054745750287759961729835575220337531857011354374603408498847160386899970699004815030544027790316454247823068492936918621580578463111596668713013015618568987237235288509264861249497715421833420428568606014682472077143585487415565706967765372022648544701585880162075847492265722600208558446652145839889394437092659180031138824646815708263010059485870400318648034219489727829064104507263688131373985525611732204024509122770022694112757362728049573810896750401836986836845072579936472906076299694138047565482372899718032680247442062926912485905218100445984215059112024944134172853147810580360337107730918286931471017111168391658172688941975871658215212822951848847208969463386289156288276595263514054226765323969461751129160240871551013515045538128756005263146801712740265396947024030051749531886292563138518816347800156936917688185237868405228783762938921430065586956868596459515550164472450983689603688";//已经算出的
string ans="1";
int main()
{
    ios::sync_with_stdio(false);
    string a="2";
    ans+=jia;
    for(int i=1;i<=1239;i++)
    {
        a+="00";
    }
    int n;
    cin>>n;
    if(n==0)
    {
        cout<<"1";
        return 0;
    }
    if(n==1239)
    {
        ans.insert(1,".");
        cout<<ans;
        return 0;
    }
    if(n<1239)
    {
        ans.insert(1,".");
        cout<<ans.substr(0,n+2);
        return 0;
    }
    ans.insert(1,".");
    cout<<ans;
    ans.erase(1,1);
    char c='0';
    for(int i=1239;i<=n;i++)
    {
        a+="00";
        while(lar(mul3(ans+c,ans+c),a)<=0)
        {
            c=O.toc(O.toi(c)+1);
        }
        c=O.toc(O.toi(c)-1);
        cout<<c;
        ans+=c;
        c='0';
    }
   return 0;
}