(程序题)连续开方再连续平方。用C++语言的开方函数sqrt,连续K次开方,然后再连续K次平方,用双精度计算,结果肯定回不到原始值。

1. (程序题)连续开方再连续平方

用C++语言的开方函数sqrt,连续K次开方,然后再连续K次平方,用双精度计算,结果肯定回不到原始值。

如果要求相差必须大于eps,请问最小的K是多少。注意,必须用C++,否则有可能过不了。

输入格式:

一行,一个整数N和一个小于0.1的实数(格式,比如1.3e-5)。

输出格式:

N-1行,每行两个整数,第一个数是2到N,从小到大,第二个整数为对应的K,比如第三行,一个整数是4,如果eps=1.0e-10,K=18,就是连续18次开方再连续18次平方,与4的误差才超过1.0e-10。

每行两个整数之间有3个空格。

输入样例:

20 1.e-10

输出样例:

2 19

3 20

4 18

5 18

6 18

7 17

8 18

9 17

10 19

11 20

12 19

13 16

14 18

15 16

16 18

17 19

18 17

19 19

20 18

运行代码:

#include <iostream>
#include <cmath>
using namespace std;

bool consecutive_sqrt(int x, int n, double esp) {
    double cvx1 = x, cvx2;
    for (int i = 0; i < n; i++) {
        cvx1 = sqrt(cvx1);
    }
    //n = pow(2, n); 
    //cvx2 = pow(cvx1, n);          //此处所注释的部分效果和下面for语句相同,但是表示的精度却不一样
    for (int i = 0; i < n; i++) {
        cvx1 = pow(cvx1, 2);
    }
    if (abs(cvx1 - x) >= esp) return 1;   //误差大于所设定的数即返回真值退出
    else return 0;
}

int main() {
    double x;
    double esp;
    cin >> x >> esp;
    for (int i = 2; i <= x; i++) {
        for (int j = 1; j <= 100; j++) {
            if (consecutive_sqrt(i, j, esp)) {
                cout << i << "   " << j << endl;
                break;
            }
        }
    }
    return 0;
}

附上运行结果截图:

总结:代码中间注释的那一部分是最开始的想法,效果理应和下面的for语句相同,但最终表示的结果还是不同。

猜想的原因

所注释的部分意思为:

第一次平方为:x*x=x²

第二次平方为:x²*x²=x^4 (x的4次方)

第三次平方为:(x^4)*(x^4)=x^8 (x的8次方)

……………………

第n次平方结果为:x^(2^n) (x的2的n次方的次方)

我们先将x最终的幂次方求出来即:n = pow(2, n)

再进行x的幂次方运算,即:cvx2 = pow(cvx1, n)

因为cvx1,cvx2都为double类型,而且一次性进行幂次方运算后会产生很多位小数,但是会因为四舍五入而造成省略很多位小数产生误差

而for语句的意思即为:一次次进行平方,每平方一次系统都会进行一次四舍五入。也就是说每平方一次做得到的结果都会自动进行四舍五入然后进行下一次平方。两者四舍五入所产生的误差不同。

(本系列文章作为课程练习后的反思总结,也欢迎各位大神在评论区进行交流,或者提供更好的解决方法以及对此代码中的注释部分不能得到需要的答案做出更好的解释)

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值