Algorithm 版 (精华区)
发信人: Lerry (想不开·撞树), 信区: Algorithm
标 题: [合集]问一个误差放大问题
发信站: 哈工大紫丁香 (2002年07月26日23:34:02 星期五), 站内信件
────────────────────────────────────────
Kenny (笑三少) 于 2002年07月18日10:23:18 星期四 说道:
同学编程时遇到一个问题,帮她问一下:
诸如 cos90 这样的计算,应该等于 0。
但计算机要计算 cos(PI/2),不等于0,非常接近,有个精确度。
但程序涉及按多媒体时钟步长反复迭代计算,
计算公式中有个 v^2 项,v 值到后来很大,v^2 应该在百万级,
这样会把 cos(PI/2) 不等于0那一点点误差放得很大,不能接受。
如何解决?
────────────────────────────────────────
Lerry (想不开·撞树) 于 2002年07月22日16:38:31 星期一 说道:
用(Pi!=3.14159265358979323846264338327950288)*COS(Pi/2)替换COS(Pi/2)
如果用上式还不能满足要求放大一些范围就好了
例如:(3.1415926<Pi&&Pi<3.1415927)*COS(Pi/2)替换COS(Pi/2)
────────────────────────────────────────
Kenny (笑三少) 于 2002年07月22日19:20:12 星期一 说道:
我看这样不行吧?
PI 是 CONST 值,你这样规定PI的范围没有意义。
我觉得如果算法需要连乘很大的数值,误差大概无法解决。
如果一个数被系统舍入为 0.123,暂且规定这么多位],实际应该更精确;
而真实值为 0.1234......... 等等,后面的小数位不写了,
那么,如果这个数乘一个 10000000000,
系统结果为 1230000000,真实结果为1234000000,
这样相差 4000000。
不是仅仅一个 cos(pi/2) != 0 的问题,
只要乘一个很大的数,所有舍入误差都要被放大,
好像这个问题是算法本身的毛病,不大好解决吧?
────────────────────────────────────────
Lerry (想不开·撞树) 于 2002年07月22日20:59:29 星期一 说道:
哦,原来是这样,
不过依我来看一般在编译系统给的有效数字位数差不多够了
在VC中使用DOUBLE型的变量可以满足绝大多数的要求,
通常应该尽量避免使用高精度计算,
尤其不是在科学计算的时候,
如果结果不合适首先想想怎么样在算法上改进一下
────────────────────────────────────────
Kenny (笑三少) 于 2002年07月23日09:10:56 星期二 说道:
sigh..........
人家是搞导弹计算的,肯定要用 double 的,没法避免;
在算法上又不好避免乘以速度的平方,wk,这项到最后很大的,
你也知道,导弹的速度8马赫以上(末段)。
我是没招了,让她自生自灭吧。
────────────────────────────────────────
Lerry (想不开·撞树) 于 2002年07月23日20:33:52 星期二 说道:
搞导弹的就用高精度计算呗,保留几十位就差不多够了吧
────────────────────────────────────────
Kenny (笑三少) 于 2002年07月25日09:30:13 星期四 说道:
呵呵,关键是要乘以速度的平方嘛!
就连那cos(pi/2) != 0 的一点点误差都被放大很多很多,
保留几十位也没用,估计保留100位差不多,哈哈哈。
────────────────────────────────────────
--
※ 修改:·Lerry 於 07月26日23:35:08 修改本文·[FROM: 天外飞仙]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.581毫秒