一个小细节~
用π/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结果是一样的,为什么呢? 你的观察很仔细!在理论上,循环条件 fabs(t) > 1e-6 和 fabs(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,因此两种条件在实际执行中导致相同的循环行为,最终输出的 π 近似值也就相同。
示例代码段:
while(fabs(t) > 1e-6)// 或 while(fabs(t) >= 1e-6),这里效果相同
{
pi = pi + t;
n = n + 2;
s = -s;
t = s / n;
}
希望这个解释能帮你理解这个小细节!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 FishC 发表于 2026-1-9 23:51
你的观察很仔细!在理论上,循环条件 fabs(t) > 1e-6 和 fabs(t) >= 1e-6 确实有区别:前者在项的绝对值大 ...
你的回复太完美了,谢谢~~~ 但求过程001 发表于 2026-01-10 00:09
FishC 发表于 2026-1-9 23:51
你的观察很仔细!在理 ...
不客气,很高兴能帮到你!编程中这类细节的琢磨正是进步的关键,为你细心思考点赞~ 如果以后有其他问题,随时来问就好。加油!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 理论上你说得对,题意是“当 |t|<10⁻⁶ 时停止”,写成 fabs(t)>=1e-6 更严谨~
但在这个程序里,> 和 >= 效果完全一样,原因只有一个:浮点数中,t 永远不会刚好等于 1e-6。
原因说明一下吧:
[*]t = s / n 是浮点运算
[*]1e-6 和 1/n 在二进制中都无法精确表示
[*]|t| 的值会从“略大于 1e-6”直接跳到“略小于 1e-6”
不存在 fabs(t) == 1e-6 这一刻
因此:
fabs(t) >1e-6
fabs(t) >= 1e-6
在实际运行中判断结果完全相同。
不是逻辑等价,而是浮点数精度导致“等于”永远不会发生。
页:
[1]