但求过程001 发表于 7 天前

关于sqrt()函数

#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()函数,但是定义部分想不出来如何写~~

FishC 发表于 7 天前

我看到你想自己实现 sqrt() 函数!这里有几个问题需要先修正,然后我会教你如何用牛顿迭代法实现平方根函数。

首先修正代码结构问题:

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

正确写法:


#include <stdio.h>

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

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

// 函数定义
double sqrt01(double a)
{
    // 这里实现平方根算法
}


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

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

完整实现:


#include <stdio.h>

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

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

// 用牛顿迭代法实现平方根
double sqrt01(double a)
{
    if(a == 0) return 0;// 0的平方根是0
   
    double x = a;// 初始猜测值
    double epsilon = 1e-6;// 精度
   
    // 迭代直到精度足够
    while((x * x - a) > epsilon || (a - x * x) > epsilon)
    {
      x = (x + a / x) / 2.0;
    }
   
    return x;
}


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


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;
}


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

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

但求过程001 发表于 7 天前

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

我将函数体输入程序后报错,说conversion from 'double ' to 'int ', possible loss of data

FishC 发表于 7 天前

但求过程001 发表于 2026-01-18 23:56
FishC 发表于 2026-1-18 23:44
我看到你想自己实现 s ...

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

错误的地方在这里:

void main()
{
    double sqrt01(double a)   // 这里缺少分号!
    double x,z;               // 这里会报错


应该是:

void main()
{
    double sqrt01(double a);   // 注意这里加了分号
    double x,z;


完整修正后的代码:


#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)
{
    // 这里可以加上前面教的牛顿迭代法
}


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


#include <stdio.h>

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

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

// 函数定义
double sqrt01(double a)
{
    // 这里可以加上前面教的牛顿迭代法
}


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

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

但求过程001 发表于 6 天前

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

FishC 发表于 6 天前

但求过程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 小助理,如未能正确解答您的问题,请继续追问。

但求过程001 发表于 6 天前

FishC 发表于 2026-1-19 00:05
看到你的代码了,有几个小问题需要修正:

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


奇了怪了,我输入了第一个程序,还是报错,算了,好像很难,看不懂,就这样吧~~感谢~~

FishC 发表于 6 天前

但求过程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 小助理,如未能正确解答您的问题,请继续追问。

但求过程001 发表于 6 天前

FishC 发表于 2026-1-19 00:20
别灰心!我给你一个超级简单的版本,不需要复杂的数学知识:




可以了
但是guess=(guess+a/guess)/2;实现的是什么?

FishC 发表于 6 天前

但求过程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 小助理,如未能正确解答您的问题,请继续追问。

不二如是 发表于 6 天前

用牛顿迭代法即可,本质是解 y*y = a。

迭代公式:



写成代码就好:

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

double sqrt01(double a);

int main(void)
{
    double x;
    scanf("%lf", &x);
    printf("%.2f\n", sqrt01(x));
    return 0;
}

double sqrt01(double a)
{
    double x = a, y;
    if (a <= 0) return 0;

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

    return x;
}

不断用 x = (x + a/x) / 2 更新,直到前后两次结果几乎不变。

kuaile4585 发表于 6 天前

牛掰,原来鱼c都已经有智能助理在回答问题了

但求过程001 发表于 6 天前

kuaile4585 发表于 2026-1-19 11:20
牛掰,原来鱼c都已经有智能助理在回答问题了

嗯,基本上都是秒回,等不了多久,又详细又准确的答案便呈现出来了,令鄙人钦佩不已,主要我绝大部分的问题他给出的答案往往都能切入核心,解释的明亮通透,真的厉害~
页: [1]
查看完整版本: 关于sqrt()函数