鱼C论坛

 找回密码
 立即注册
查看: 43|回复: 4

一个小细节~

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

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

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

x
用π/4 ≈ 1-1/3+1/5-1/7+…公式求π的近似值,直到某一项的绝对值小于(10的-6次方)为止。

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

void main()
{
        int s=1;
        double pi,n,t;                         
        pi=0,n=1.0,t=1;
        while(fabs(t)>1e-6)
        {
                pi=pi+t;
                n=n+2;
                s=-s;
                t=s/n;
        }
        pi=pi*4;
        printf("pi=%10.6f\n",pi);
}

如上为题目和程序,这里绝对值小于(10的-6次方),但程序里面不应该是fabs(t)>=1e-6吗?但实际上fabs(t)>1e-6和fabs(t)>=1e-6结果是一样的,为什么呢?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 23:51 | 显示全部楼层
你的观察很仔细!在理论上,循环条件 fabs(t) > 1e-6fabs(t) >= 1e-6 确实有区别:前者在项的绝对值大于 1e-6 时继续,小于或等于时停止;后者在项的绝对值大于或等于 1e-6 时继续,小于时停止。但在这个特定程序中,两者结果相同,原因如下:

1. 序列的项是 t = s/n,其中 n 是奇数(1, 3, 5, 7, ...),所以项的绝对值是 1/n
2. 检查是否存在奇数 n 使得 1/n 恰好等于 1e-6
   - 1/n = 1e-6 解得 n = 1,000,000
   - 但 1,000,000 是偶数,而序列中的 n 必须是奇数,因此没有一项的绝对值恰好等于 1e-6
3. 实际计算中:
   - 当 n = 999,999(奇数)时,1/n ≈ 1.000001e-6,略大于 1e-6
   - 当 n = 1,000,001(奇数)时,1/n ≈ 0.999999e-6,略小于 1e-6
4. 在两种循环条件下:
   - 使用 >:当处理到 n = 1,000,001 时,fabs(t) < 1e-6,条件为假,循环停止,该项不被加入。
   - 使用 >=:同样当 n = 1,000,001 时,fabs(t) < 1e-6,条件为假,循环停止,该项也不被加入。
   因此,循环都在同一项停止,且最后一项均不加入计算,所以结果相同。

总结:由于序列中没有项的绝对值恰好等于 1e-6,因此两种条件在实际执行中导致相同的循环行为,最终输出的 π 近似值也就相同。

示例代码段:


  1. while(fabs(t) > 1e-6)  // 或 while(fabs(t) >= 1e-6),这里效果相同
  2. {
  3.     pi = pi + t;
  4.     n = n + 2;
  5.     s = -s;
  6.     t = s / n;
  7. }
复制代码


希望这个解释能帮你理解这个小细节!

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

使用道具 举报

 楼主| 发表于 14 小时前 | 显示全部楼层
FishC 发表于 2026-1-9 23:51
你的观察很仔细!在理论上,循环条件 fabs(t) > 1e-6 和 fabs(t) >= 1e-6 确实有区别:前者在项的绝对值大 ...

你的回复太完美了,谢谢~~~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 14 小时前 | 显示全部楼层
但求过程001 发表于 2026-01-10 00:09
FishC 发表于 2026-1-9 23:51
你的观察很仔细!在理 ...


不客气,很高兴能帮到你!编程中这类细节的琢磨正是进步的关键,为你细心思考点赞~ 如果以后有其他问题,随时来问就好。加油!

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

使用道具 举报

发表于 半小时前 | 显示全部楼层
理论上你说得对,题意是“当 |t|<10&#8315;&#8310; 时停止”,写成 fabs(t)>=1e-6 更严谨~

但在这个程序里,> 和 >= 效果完全一样,原因只有一个:浮点数中,t 永远不会刚好等于 1e-6。

原因说明一下吧:

  • t = s / n 是浮点运算
  • 1e-6 和 1/n 在二进制中都无法精确表示
  • |t| 的值会从“略大于 1e-6”直接跳到“略小于 1e-6”

不存在 fabs(t) == 1e-6 这一刻

因此:

  1. fabs(t) >  1e-6
  2. fabs(t) >= 1e-6
复制代码

在实际运行中判断结果完全相同。

不是逻辑等价,而是浮点数精度导致“等于”永远不会发生。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-1-10 14:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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