鱼C论坛

 找回密码
 立即注册
查看: 56|回复: 11

关于sqrt()函数

[复制链接]
发表于 昨天 23:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <stdio.h>

void main()
{
        double sqrt01(double a)
        double x,z;
        scanf("%lf",&x);
        z=sqrt01(x);
        printf("%.2f\n",z);
}

double sqrt01(double a)
{
       
}

想用程序实现sqrt()函数,但是定义部分想不出来如何写~~
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 23:44 | 显示全部楼层
我看到你想自己实现 sqrt() 函数!这里有几个问题需要先修正,然后我会教你如何用牛顿迭代法实现平方根函数。

首先修正代码结构问题:

问题1:函数声明应该放在 main 函数外面

正确写法


  1. #include <stdio.h>

  2. // 函数声明
  3. double sqrt01(double a);

  4. int main()
  5. {
  6.     double x, z;
  7.     scanf("%lf", &x);
  8.     z = sqrt01(x);
  9.     printf("%.2f\n", z);
  10.     return 0;
  11. }

  12. // 函数定义
  13. double sqrt01(double a)
  14. {
  15.     // 这里实现平方根算法
  16. }
复制代码


问题2:如何实现平方根函数?

最简单的方法是用牛顿迭代法,公式是:x = (x + a/x) / 2

完整实现


  1. #include <stdio.h>

  2. // 函数声明
  3. double sqrt01(double a);

  4. int main()
  5. {
  6.     double x, z;
  7.     printf("请输入一个数字: ");
  8.     scanf("%lf", &x);
  9.    
  10.     if(x < 0)
  11.     {
  12.         printf("不能计算负数的平方根!\n");
  13.         return 1;
  14.     }
  15.    
  16.     z = sqrt01(x);
  17.     printf("平方根: %.6f\n", z);
  18.     return 0;
  19. }

  20. // 用牛顿迭代法实现平方根
  21. double sqrt01(double a)
  22. {
  23.     if(a == 0) return 0;  // 0的平方根是0
  24.    
  25.     double x = a;  // 初始猜测值
  26.     double epsilon = 1e-6;  // 精度
  27.    
  28.     // 迭代直到精度足够
  29.     while((x * x - a) > epsilon || (a - x * x) > epsilon)
  30.     {
  31.         x = (x + a / x) / 2.0;
  32.     }
  33.    
  34.     return x;
  35. }
复制代码


简单版本(如果你觉得上面的太复杂):


  1. double sqrt01(double a)
  2. {
  3.     if(a < 0) return -1;  // 返回-1表示错误
  4.    
  5.     double x = a;
  6.    
  7.     // 迭代10次,通常已经足够精确
  8.     for(int i = 0; i < 10; i++)
  9.     {
  10.         x = (x + a / x) / 2.0;
  11.     }
  12.    
  13.     return x;
  14. }
复制代码


工作原理
1. 先猜一个值(比如就用输入的数字本身)
2. 用公式 x = (x + a/x) / 2 改进猜测
3. 重复多次,结果会越来越接近真正的平方根

试试这个代码,然后输入一个正数看看效果!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 23:56 | 显示全部楼层
FishC 发表于 2026-1-18 23:44
我看到你想自己实现 sqrt() 函数!这里有几个问题需要先修正,然后我会教你如何用牛顿迭代法实现平方根函数 ...

我将函数体输入程序后报错,说conversion from 'double ' to 'int ', possible loss of data
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 23:57 | 显示全部楼层
但求过程001 发表于 2026-01-18 23:56
FishC 发表于 2026-1-18 23:44
我看到你想自己实现 s ...


看到你的代码报错,问题是在 `main` 函数前面忘记加分号了。让我帮你修正一下:

错误的地方在这里:

  1. void main()
  2. {
  3.     double sqrt01(double a)   // 这里缺少分号!
  4.     double x,z;               // 这里会报错
复制代码


应该是:

  1. void main()
  2. {
  3.     double sqrt01(double a);   // 注意这里加了分号
  4.     double x,z;
复制代码


完整修正后的代码:


  1. #include <stdio.h>

  2. void main()
  3. {
  4.     double sqrt01(double a);   // 函数声明要加分号
  5.     double x, z;
  6.     scanf("%lf", &x);
  7.     z = sqrt01(x);
  8.     printf("%.2f\n", z);
  9. }

  10. // 函数定义
  11. double sqrt01(double a)
  12. {
  13.     // 这里可以加上前面教的牛顿迭代法
  14. }
复制代码


或者更好的写法是把函数声明放在 `main` 外面:


  1. #include <stdio.h>

  2. // 函数声明放在这里更清晰
  3. double sqrt01(double a);

  4. void main()
  5. {
  6.     double x, z;
  7.     scanf("%lf", &x);
  8.     z = sqrt01(x);
  9.     printf("%.2f\n", z);
  10. }

  11. // 函数定义
  12. double sqrt01(double a)
  13. {
  14.     // 这里可以加上前面教的牛顿迭代法
  15. }
复制代码


编译器报错 "conversion from 'double' to 'int'" 是因为缺少分号导致编译器误解了你的代码结构。

现在把分号加上,然后按照之前的教程实现 `sqrt01` 函数的内部逻辑,应该就不会报错了!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 17 小时前 | 显示全部楼层
FishC 发表于 2026-1-18 23:57
看到你的代码报错,问题是在 `main` 函数前面忘记加分号了。让我帮你修正一下:

错误的地方在这里: ...

#include <stdio.h>

void main()
{
        double sqrt01(double a);
        double x,z;
        scanf("%lf",&x);
        z=sqrt01(x);
        if(z<0)
        {
                printf("error!\n");
        }
        else
                printf("%.2f\n",z);
}

double sqrt01(double a)
{
    if(a < 0) return -1;  // 返回-1表示错误
       
    double x = a;
       
    // 迭代10次,通常已经足够精确
    for(int i = 0; i < 10; i++)
    {
        x = (x + a / x) / 2.0;
    }
       
    return x;
}

这是我的整个程序,还是报错,一样conversion from 'double' to 'int
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 17 小时前 | 显示全部楼层
但求过程001 发表于 2026-01-19 00:05
FishC 发表于 2026-1-18 23:57
看到你的代码报错,问 ...


看到你的代码了,有几个小问题需要修正:

1. main() 函数应该是 int main() 而不是 void main()
2. 你的 if 语句不完整,缺少括号和内容
3. 需要在程序结束时返回一个值

让我帮你修正一下:


#include <stdio.h>

// 函数声明
double sqrt01(double a);

int main()
{
    double x, z;
    printf("请输入一个数字: ");
    scanf("%lf", &x);
   
    z = sqrt01(x);
   
    if(z < 0)
    {
        printf("不能计算负数的平方根!\n");
    }
    else
    {
        printf("平方根: %.2f\n", z);
    }
   
    return 0;
}

// 函数定义 - 用牛顿迭代法计算平方根
double sqrt01(double a)
{
    // 如果是负数,返回-1表示错误
    if(a < 0)
        return -1;
   
    // 如果a是0,直接返回0
    if(a == 0)
        return 0;
   
    double x = a;        // 初始猜测值
    double epsilon = 0.000001;  // 精度
   
    // 迭代直到精度足够
    while(1)
    {
        double next_x = (x + a / x) / 2.0;
        if((x - next_x) < epsilon && (next_x - x) < epsilon)
            break;
        x = next_x;
    }
   
    return x;
}


如果你想要一个更简单的方法(不用循环),可以直接用 math.h 库:


#include <stdio.h>
#include <math.h>

// 使用math.h库中的sqrt函数
int main()
{
    double x, z;
    printf("请输入一个数字: ");
    scanf("%lf", &x);
   
    if(x < 0)
    {
        printf("不能计算负数的平方根!\n");
    }
    else
    {
        z = sqrt(x);
        printf("平方根: %.2f\n", z);
    }
   
    return 0;
}


记住要包含头文件 math.h,并且在编译时可能需要加 -lm 选项。

试试第一个版本,它应该能正确运行!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 17 小时前 | 显示全部楼层
FishC 发表于 2026-1-19 00:05
看到你的代码了,有几个小问题需要修正:

1. main() 函数应该是 int main() 而不是 void main()

奇了怪了,我输入了第一个程序,还是报错,算了,好像很难,看不懂,就这样吧~~感谢~~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 17 小时前 | 显示全部楼层
但求过程001 发表于 2026-01-19 00:18
FishC 发表于 2026-1-19 00:05
看到你的代码了,有几 ...


别灰心!我给你一个超级简单的版本,不需要复杂的数学知识:


#include <stdio.h>
#include <math.h>  // 直接使用数学库

int main()
{
    double x, z;
   
    printf("请输入一个数字: ");
    scanf("%lf", &x);
   
    if(x < 0)
    {
        printf("不能计算负数的平方根!\n");
    }
    else
    {
        z = sqrt(x);  // 直接调用数学库的sqrt函数
        printf("平方根: %.2f\n", z);
    }
   
    return 0;
}


最简单的理解方式:
1. #include <math.h> 告诉编译器"我要用数学函数"
2. sqrt(x) 就是计算平方根的函数

如果想自己实现但不用复杂的牛顿迭代法,可以这样:


double sqrt01(double a)
{
    double guess = a / 2;  // 从a的一半开始猜
   
    // 猜5次改进结果
    guess = (guess + a/guess) / 2;  // 第1次改进
    guess = (guess + a/guess) / 2;  // 第2次改进
    guess = (guess + a/guess) / 2;  // 第3次改进
    guess = (guess + a/guess) / 2;  // 第4次改进
    guess = (guess + a/guess) / 2;  // 第5次改进
   
    return guess;
}


这样就很简单了吧!数学的部分让计算机去算,你只需要知道用哪个函数就好。

学编程就像学走路,一开始会摔跤很正常,多练习几次就好了!加油!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 17 小时前 | 显示全部楼层
FishC 发表于 2026-1-19 00:20
别灰心!我给你一个超级简单的版本,不需要复杂的数学知识:

可以了
但是guess=(guess+a/guess)/2;实现的是什么?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 17 小时前 | 显示全部楼层
但求过程001 发表于 2026-01-19 00:37
FishC 发表于 2026-1-19 00:20
别灰心!我给你一个超 ...


太棒了!你问到了最关键的一行代码。这一行实现的正是**牛顿迭代法**的核心,它用一个巧妙的公式来“猜”出平方根。

别怕,我用最简单的方式解释给你听:

### 它做了什么?
**一句话:它把你“猜”的答案,变得更准一点。**

### 怎么理解?
想象一下,我们要找一个数 guess,让它满足:
guess * guess = a (也就是 guess 是 a 的平方根)

这个公式 `guess = (guess + a/guess) / 2` 的神奇之处在于:

1.  **`a / guess`**:如果 `guess` 猜小了(比如 guess=3, a=16,那么 16/3 ≈ 5.33),这个值就会比真正的平方根大。
2.  **`guess`**:就是你当前猜的值(比如 3)。
3.  **把它们加起来再除以 2**:`(3 + 5.33) / 2 = 4.165`。看到了吗?新的猜测值 `4.165`,比旧的 `3` 更接近真正的答案 `4` 了!

### 一个生动的比喻:猜价格游戏
假设商品真实价格是100元。
*   你第一次猜:50元(猜低了)。
*   主持人不会直接告诉你答案,但他会说:“嗯...如果按你猜的50元算,这个商品的价值应该是 `100/50 = 2` 件。”(这暗示你猜得太便宜了)。
*   接下来,聪明的做法是取你猜的价格和这个暗示价格的**中间值**:`(50 + 2) / 2 = 26元`?等等,这里不对... 哦!在我们的平方根问题里,“暗示的价格”不是除出来的数本身,而是它的**倒数关系**调整后的值。更准确的比喻是:
    *   你猜平方根是 `guess`。
    *   系统告诉你:“如果你用 `guess`,那么为了得到 `a`,另一个因子必须是 `a/guess`。”
    *   那么真实的平方根,很可能就在 `guess` 和 `a/guess` 这**两个数之间**。
    *   所以取它们的平均值 `(guess + a/guess)/2` 作为新的猜测,就离真相更近了!

### 核心思想
这个公式保证了:
*   如果你猜小了 (`guess` < 真实根),那么 `a/guess` 就会比真实根大。
*   如果你猜大了 (`guess` > 真实根),那么 `a/guess` 就会比真实根小。
*   **无论哪种情况,真实的平方根都一定在你猜的数 `guess` 和 `a/guess` 之间!**
*   所以,取它们的**平均数** `(guess + a/guess)/2` 作为下一次的猜测,一定是**更优的猜测**。

### 看一个数字例子(求 a=9 的平方根)
1.  初始乱猜:`guess = 9`
    *   计算:`(9 + 9/9) / 2 = (9+1)/2 = 5`
2.  第一次改进:`guess = 5`
    *   计算:`(5 + 9/5) / 2 = (5+1.8)/2 = 3.4`
3.  第二次改进:`guess = 3.4`
    *   计算:`(3.4 + 9/3.4)/2 ≈ (3.4+2.647)/2 ≈ 3.0235`
4.  第三次改进:`guess = 3.0235`
    *   计算:`(3.0235 + 9/3.0235)/2 ≈ (3.0235+2.9765)/2 = 3.000000...`

你看,仅仅几次计算,就从9飞快地逼近到了真实的答案3!

所以,这一行代码是一个**数学魔法**,它利用 `guess` 和 `a/guess` 总在真实答案两边的特性,通过取它们的平均值来快速逼近正确的平方根。程序只需要重复这个过程几次,就能得到非常精确的结果。

希望这个解释能让你豁然开朗!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 7 小时前 | 显示全部楼层
用牛顿迭代法即可,本质是解 y*y = a。

迭代公式:

Xnip2026-01-19_10-03-28.png

写成代码就好:

  1. #include <stdio.h>
  2. #include <math.h>

  3. double sqrt01(double a);

  4. int main(void)
  5. {
  6.     double x;
  7.     scanf("%lf", &x);
  8.     printf("%.2f\n", sqrt01(x));
  9.     return 0;
  10. }

  11. double sqrt01(double a)
  12. {
  13.     double x = a, y;
  14.     if (a <= 0) return 0;

  15.     do {
  16.         y = x;
  17.         x = 0.5 * (y + a / y);
  18.     } while (fabs(x - y) > 1e-6);

  19.     return x;
  20. }
复制代码

不断用 x = (x + a/x) / 2 更新,直到前后两次结果几乎不变。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 6 小时前 | 显示全部楼层
牛掰,原来鱼c都已经有智能助理在回答问题了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-1-19 17:46

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表